From 9e9b526d46afaf09647213fc6640825b9c3ad1a4 Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Tue, 3 Feb 2026 17:04:34 +0700 Subject: [PATCH] feat: Move and enhance `update_initial_simulation_data` to fetch acquisition year and cost from `wo_maximo` and update equipment records before simulation. --- src/equipment/router.py | 69 +++++-------------------------------- src/equipment/service.py | 74 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 61 deletions(-) diff --git a/src/equipment/router.py b/src/equipment/router.py index 23545e0..2dfa7b0 100644 --- a/src/equipment/router.py +++ b/src/equipment/router.py @@ -30,6 +30,7 @@ from src.equipment.service import ( get_top_10_economic_life, get_maximo_by_assetnum, get_all_assetnums, + update_initial_simulation_data, ) from src.modules.equipment.Prediksi import main as prediksi_main from src.modules.equipment.Eac import Eac @@ -38,7 +39,6 @@ from src.database.service import CommonParameters, search_filter_sort_paginate from src.database.core import DbSession, CollectorDbSession from src.auth.service import CurrentUser, Token from src.models import CommonParams, StandardResponse -from src.modules.config import get_production_connection router = APIRouter() @@ -82,6 +82,13 @@ async def simulate_equipment(db_session: DbSession, assetnum: str): """ async def event_generator(): + try: + await update_initial_simulation_data(db_session=db_session, assetnum=assetnum) + except Exception as e: + # Log error but proceed? Or maybe yield an error? + # For now, we proceed as this is an enhancement check. + print(f"Update simulation data failed: {e}") + # notify start of prediksi yield f"data: {json.dumps({'status':'started','step':'prediksi','message':'Starting prediksi'})}\n\n" @@ -119,66 +126,6 @@ async def simulate_equipment(db_session: DbSession, assetnum: str): return StreamingResponse(event_generator(), media_type='text/event-stream') -async def update_initial_simulation_data(db_session: DbSession, assetnum: str): - """ - Update acquisition_year from wo_maximo and set default forecasting_target_year - before running simulation. - """ - conn = get_production_connection() - first_year = None - if conn: - try: - cursor = conn.cursor() - # Query the first year from wo_maximo - query = """ - select DATE_PART('year', a.reportdate) AS year - from wo_maximo a - where a.asset_replacecost > 0 - and a.asset_assetnum = %s - order by a.reportdate asc - limit 1; - """ - cursor.execute(query, (assetnum,)) - result = cursor.fetchone() - if result: - first_year = int(result[0]) - cursor.close() - conn.close() - except Exception as e: - print(f"Error fetching acquisition year for {assetnum}: {e}") - if conn: - try: - conn.close() - except: - pass - - if first_year: - # Fetch equipment to update - eq = await get_by_assetnum(db_session=db_session, assetnum=assetnum) - if eq: - # Check if forecasting_target_year matches the "default" logic (acquisition + design_life) - # using the OLD acquisition year. - current_acq = eq.acquisition_year - current_life = eq.design_life - current_target = eq.forecasting_target_year - - # If current_target is logically "default", we update it. - # If user changed it to something else, we might want to preserve it? - # User request: "must be default acquisition_year+design_life if not changes" - # We interpret "if not changes" as: if it currently holds the default value (based on old acq year). - is_valid_default = current_target == (current_acq + current_life) - - # Apply updates - if eq.acquisition_year != first_year: - eq.acquisition_year = first_year - - if is_valid_default: - eq.forecasting_target_year = first_year + current_life - - await db_session.commit() - # await db_session.refresh(eq) - - @router.get("/simulate-all") async def simulate_all_equipment(db_session: DbSession): """Run simulation (prediksi + EAC) for ALL equipment. diff --git a/src/equipment/service.py b/src/equipment/service.py index a30f225..1f3a559 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -25,6 +25,7 @@ from src.modules.equipment.insert_actual_data import query_data from src.modules.equipment.Prediksi import main as predict_main from src.modules.equipment.Eac import main as eac_main from src.modules.equipment.where_query_sql import get_where_query_sql_all_worktype +from src.modules.config import get_production_connection import datetime import math @@ -647,3 +648,76 @@ async def delete(*, db_session: DbSession, equipment_id: str): query = Delete(Equipment).where(Equipment.id == equipment_id) await db_session.execute(query) await db_session.commit() + + +async def update_initial_simulation_data(db_session: DbSession, assetnum: str): + """ + Update acquisition_year and acquisition_cost from wo_maximo and set default forecasting_target_year + before running simulation. + """ + conn = get_production_connection() + first_year = None + first_cost = None + if conn: + try: + cursor = conn.cursor() + # Query the first year from wo_maximo + query = """ + select DATE_PART('year', a.reportdate) AS year, a.asset_replacecost AS cost + from wo_maximo a + where a.asset_replacecost > 0 + and a.asset_assetnum = %s + order by a.reportdate asc + limit 1; + """ + cursor.execute(query, (assetnum,)) + result = cursor.fetchone() + if result: + first_year = int(result[0]) + first_cost = float(result[1]) if result[1] is not None else 0.0 + cursor.close() + conn.close() + except Exception as e: + print(f"Error fetching acquisition year for {assetnum}: {e}") + if conn: + try: + conn.close() + except: + pass + + if first_year: + # Fetch equipment to update + eq = await get_by_assetnum(db_session=db_session, assetnum=assetnum) + if eq: + # Check if forecasting_target_year matches the "default" logic (acquisition + design_life) + # using the OLD acquisition year. + current_acq = eq.acquisition_year + current_life = eq.design_life + current_target = eq.forecasting_target_year + + # If current_target is logically "default", we update it. + # If user changed it to something else, we might want to preserve it? + # User request: "must be default acquisition_year+design_life if not changes" + # We interpret "if not changes" as: if it currently holds the default value (based on old acq year). + is_valid_default = False + if current_acq and current_life and current_target: + is_valid_default = current_target == (current_acq + current_life) + + updates_needed = False + + # Update acquisition_cost + if first_cost is not None and eq.acquisition_cost != first_cost: + eq.acquisition_cost = first_cost + updates_needed = True + + # Update acquisition_year + if eq.acquisition_year != first_year: + eq.acquisition_year = first_year + updates_needed = True + + if is_valid_default and current_life: + eq.forecasting_target_year = first_year + current_life + + if updates_needed: + await db_session.commit() + # await db_session.refresh(eq)