You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.7 KiB
Python

import random
from typing import Optional
from sqlalchemy import Delete, Select
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.scope_equipment.model import ScopeEquipment
from src.scope_equipment.service import get_by_scope_name
from src.overhaul_activity.service import get_all_by_session_id
# async def get_all_budget_constrains(
# *, db_session: DbSession, session_id: str, cost_threshold: float = 100000000
# ):
# At the module level, add this dictionary to store persistent EAF values
_equipment_eaf_cache = {}
import random
async def get_all_budget_constrains(
*, db_session: DbSession, session_id: str, cost_threshold: float = 100000000
):
"""Get all overhaul overview with EAF values that sum to 100%."""
equipments = await get_all_by_session_id(db_session=db_session, overhaul_session_id=session_id)
# If no equipments found, return empty list
if not equipments:
return [], []
# Create or retrieve persistent EAF values
global _equipment_eaf_cache
# Generate EAF values for new equipment IDs
equipment_ids = [equipment.id for equipment in equipments]
# Generate new random EAF values if they don't exist
if not _equipment_eaf_cache or set(equipment_ids) != set(_equipment_eaf_cache.keys()):
total_eaf = 100.0
remaining_items = len(equipment_ids)
_equipment_eaf_cache.clear()
# Ensure minimum EAF value for each equipment
min_eaf = 1.0 # Minimum 1% for each equipment
reserved_eaf = min_eaf * remaining_items
distributable_eaf = total_eaf - reserved_eaf
for eq_id in equipment_ids[:-1]: # All except last item
if remaining_items > 1:
# Generate a random value between min_eaf and the remaining distributable EAF
max_allowed = distributable_eaf / (remaining_items - 1)
eaf = round(min_eaf + random.uniform(0, max_allowed), 2)
_equipment_eaf_cache[eq_id] = eaf
distributable_eaf -= (eaf - min_eaf)
remaining_items -= 1
# Assign remaining EAF to last item, ensuring it's at least min_eaf
_equipment_eaf_cache[equipment_ids[-1]] = round(distributable_eaf + min_eaf, 2)
# Create result array of dictionaries
result = [
{
"id": equipment.id,
"assetnum": equipment.assetnum,
"location_tag": equipment.equipment.location_tag,
"name": equipment.equipment.name,
"total_cost": equipment.material_cost + equipment.service_cost,
"eaf_contribution": _equipment_eaf_cache[equipment.id]
}
for equipment in equipments
]
# Sort by EAF contribution (highest to lowest)
result.sort(key=lambda x: x["eaf_contribution"], reverse=True)
# Filter equipment up to threshold
cumulative_cost = 0
included_results = []
for equipment in result:
cumulative_cost += equipment["total_cost"]
if cumulative_cost >= cost_threshold:
break
included_results.append(equipment)
# Rest equipment is consequence list
consequence_results = result[len(included_results):]
#Sort
consequence_results.sort(key=lambda x: x["eaf_contribution"], reverse=True)
included_results.sort(key=lambda x: x["eaf_contribution"], reverse=True)
return included_results, consequence_results
# """Get all overhaul overview with EAF values that sum to 100%."""
# # equipments = await get_by_scope_name(db_session=db_session, scope_name=scope_name)
# equipments = await get_all_by_session_id(db_session=db_session, overhaul_session_id=session_id)
# # If no equipments found, return empty list
# if not equipments:
# return []
# # Create result array of dictionaries
# result = [
# {
# "id": equipment.id,
# "assetnum": equipment.assetnum,
# "location_tag": equipment.equipment.location_tag,
# "name": equipment.equipment.name,
# "total_cost": equipment.material_cost + equipment.service_cost
# "eaf_contribution": ## Create Dummy % number, each equipment has different value
# }
# for equipment in equipments
# ]
# result.sort(key=lambda x: x["eaf_contribution"], reverse=True) #Sort from biggest contribution
# # Filter equipment up to threshold
# cumulative_cost = 0
# included_results = []
# for equipment in result:
# cumulative_cost += equipment["total_cost"]
# if cumulative_cost >= cost_threshold:
# break
# included_results.append(equipment)
# # rest equipemnt is consequence list
# consequence_results = result[len(included_results):]
# return included_results ,consequence_results