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