|
|
|
@ -7,41 +7,123 @@ from src.auth.service import CurrentUser
|
|
|
|
from src.database.core import DbSession
|
|
|
|
from src.database.core import DbSession
|
|
|
|
from src.scope_equipment.model import ScopeEquipment
|
|
|
|
from src.scope_equipment.model import ScopeEquipment
|
|
|
|
from src.scope_equipment.service import get_by_scope_name
|
|
|
|
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(
|
|
|
|
async def get_all_budget_constrains(
|
|
|
|
*, db_session: DbSession, scope_name: str, cost_threshold: float = 100.0
|
|
|
|
*, db_session: DbSession, session_id: str, cost_threshold: float = 100000000
|
|
|
|
):
|
|
|
|
):
|
|
|
|
"""Get all overhaul overview with EAF values that sum to 100%."""
|
|
|
|
"""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 no equipments found, return empty list
|
|
|
|
if not equipments:
|
|
|
|
if not equipments:
|
|
|
|
return []
|
|
|
|
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
|
|
|
|
# Create result array of dictionaries
|
|
|
|
result = [
|
|
|
|
result = [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"id": equipment.id,
|
|
|
|
"id": equipment.id,
|
|
|
|
"assetnum": equipment.assetnum,
|
|
|
|
"assetnum": equipment.assetnum,
|
|
|
|
"location_tag": equipment.master_equipment.location_tag,
|
|
|
|
"location_tag": equipment.equipment.location_tag,
|
|
|
|
"name": equipment.master_equipment.name,
|
|
|
|
"name": equipment.equipment.name,
|
|
|
|
"total_cost": 1000000 + random.randint(10000, 5000000),
|
|
|
|
"total_cost": equipment.material_cost + equipment.service_cost,
|
|
|
|
|
|
|
|
"eaf_contribution": _equipment_eaf_cache[equipment.id]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for equipment in equipments
|
|
|
|
for equipment in equipments
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
result.sort(key=lambda x: x["total_cost"], reverse=True)
|
|
|
|
# Sort by EAF contribution (highest to lowest)
|
|
|
|
|
|
|
|
result.sort(key=lambda x: x["eaf_contribution"], reverse=True)
|
|
|
|
|
|
|
|
|
|
|
|
# Filter equipment up to threshold
|
|
|
|
# Filter equipment up to threshold
|
|
|
|
cumulative_cost = 0
|
|
|
|
cumulative_cost = 0
|
|
|
|
filtered_result = []
|
|
|
|
included_results = []
|
|
|
|
|
|
|
|
|
|
|
|
for equipment in result:
|
|
|
|
for equipment in result:
|
|
|
|
cumulative_cost += equipment["total_cost"]
|
|
|
|
cumulative_cost += equipment["total_cost"]
|
|
|
|
|
|
|
|
|
|
|
|
if cumulative_cost >= cost_threshold:
|
|
|
|
if cumulative_cost >= cost_threshold:
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
included_results.append(equipment)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Rest equipment is consequence list
|
|
|
|
|
|
|
|
consequence_results = result[len(included_results):]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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):]
|
|
|
|
|
|
|
|
|
|
|
|
filtered_result.append(equipment)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return filtered_result
|
|
|
|
# return included_results ,consequence_results
|
|
|
|
|