diff --git a/src/auth/__pycache__/service.cpython-311.pyc b/src/auth/__pycache__/service.cpython-311.pyc index 02e487c..daf1c83 100644 Binary files a/src/auth/__pycache__/service.cpython-311.pyc and b/src/auth/__pycache__/service.cpython-311.pyc differ diff --git a/src/equipment/__pycache__/model.cpython-311.pyc b/src/equipment/__pycache__/model.cpython-311.pyc index 99402df..a8e1524 100644 Binary files a/src/equipment/__pycache__/model.cpython-311.pyc and b/src/equipment/__pycache__/model.cpython-311.pyc differ diff --git a/src/equipment/__pycache__/router.cpython-311.pyc b/src/equipment/__pycache__/router.cpython-311.pyc index bd93b86..e6f5bd1 100644 Binary files a/src/equipment/__pycache__/router.cpython-311.pyc and b/src/equipment/__pycache__/router.cpython-311.pyc differ diff --git a/src/equipment/__pycache__/schema.cpython-311.pyc b/src/equipment/__pycache__/schema.cpython-311.pyc index 13617cf..2cb302b 100644 Binary files a/src/equipment/__pycache__/schema.cpython-311.pyc and b/src/equipment/__pycache__/schema.cpython-311.pyc differ diff --git a/src/equipment/__pycache__/service.cpython-311.pyc b/src/equipment/__pycache__/service.cpython-311.pyc index b04bd9d..2ef5726 100644 Binary files a/src/equipment/__pycache__/service.cpython-311.pyc and b/src/equipment/__pycache__/service.cpython-311.pyc differ diff --git a/src/equipment/model.py b/src/equipment/model.py index c39feb8..09c66f1 100644 --- a/src/equipment/model.py +++ b/src/equipment/model.py @@ -94,5 +94,5 @@ class EquipmentTransactionRecords(Base, DefaultMixin, IdentityMixin): eac_annual_acq_cost = Column(Float, nullable=False) eac_disposal_cost = Column(Float, nullable=False) eac_eac = Column(Float, nullable=False) - efdh_equivalent_forced_derating_hours = Column(Float, nullable=False) + efdh_equivalent_forced_derated_hours = Column(Float, nullable=False) foh_forced_outage_hours = Column(Float, nullable=False) diff --git a/src/equipment/router.py b/src/equipment/router.py index 6a86c49..f2969c9 100644 --- a/src/equipment/router.py +++ b/src/equipment/router.py @@ -212,7 +212,7 @@ async def update_equipment( token: Token, ): equipment = await get_by_assetnum(db_session=db_session, assetnum=assetnum) - print(equipment, assetnum) + if not equipment: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, diff --git a/src/equipment/schema.py b/src/equipment/schema.py index a865f92..be238d9 100644 --- a/src/equipment/schema.py +++ b/src/equipment/schema.py @@ -72,7 +72,7 @@ class MasterBase(DefaultBase): eac_annual_acq_cost: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) eac_disposal_cost: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) eac_eac: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) - efdh_equivalent_forced_derating_hours: Optional[float] = Field(None, nullable=True) + efdh_equivalent_forced_derated_hours: Optional[float] = Field(None, nullable=True) foh_forced_outage_hours: Optional[float] = Field(None, nullable=True) diff --git a/src/equipment/service.py b/src/equipment/service.py index cd0e902..5f9556b 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -15,6 +15,8 @@ from src.config import RELIABILITY_APP_URL import httpx from src.modules.equipment.run import main +from src.modules.equipment.Prediksi import main as predict_main +from src.modules.equipment.Eac import main as eac_main import datetime import math from sqlalchemy import text @@ -285,15 +287,17 @@ async def generate_transaction( *, db_session: DbSession, data_in: EquipmentCreate, token ): # Delete all existing master records for this asset number and prediction data - query = ( - Delete(EquipmentTransactionRecords) - .where(EquipmentTransactionRecords.assetnum == data_in.assetnum) - .where(EquipmentTransactionRecords.is_actual == 0) - ) - await db_session.execute(query) - await db_session.commit() + # query = ( + # Delete(EquipmentTransactionRecords) + # .where(EquipmentTransactionRecords.assetnum == data_in.assetnum) + # .where(EquipmentTransactionRecords.is_actual == 0) + # ) + # await db_session.execute(query) + # await db_session.commit() """Generate transaction for equipment.""" - prediction = await main(data_in.assetnum, token, RELIABILITY_APP_URL) + # prediction = await main(data_in.assetnum, token, RELIABILITY_APP_URL) + prediction = await predict_main(assetnum=data_in.assetnum, token=token) + eac = eac_main(assetnum=data_in.assetnum) # # Fetch data from external API # async def fetch_api_data(assetnum: str, year: int) -> dict: @@ -396,7 +400,7 @@ async def generate_transaction( # # Return the number of transactions created # return len(transactions) - return prediction + return prediction, eac async def create(*, db_session: DbSession, equipment_in: EquipmentCreate, token): @@ -411,7 +415,10 @@ async def create(*, db_session: DbSession, equipment_in: EquipmentCreate, token) async def update( *, db_session: DbSession, equipment: Equipment, equipment_in: EquipmentUpdate, token ): - """Updates a document.""" + """Updates a document and re-simulates transaction for the asset.""" + + # capture original assetnum (optional use) + old_assetnum = equipment.assetnum data = equipment_in.model_dump() update_data = equipment_in.model_dump(exclude_defaults=True) @@ -421,11 +428,17 @@ async def update( await db_session.commit() - updated_data = vars(equipment) - # equipment_create = EquipmentCreate(**updated_data) - # await generate_transaction( - # db_session=db_session, data_in=equipment_create, token=token - # ) + # prepare a clean dict of attributes for return / recreate input model + updated_data = {k: v for k, v in vars(equipment).items() if not k.startswith("_")} + + # Re-run generate_transaction for this equipment's assetnum. + # Build an EquipmentCreate from the updated SQLAlchemy object and call the generator. + try: + equipment_create = EquipmentCreate(**updated_data) + await generate_transaction(db_session=db_session, data_in=equipment_create, token=token) + except Exception as e: + # don't break the update if resimulation fails — log/print for visibility + print(f"Resimulation failed for assetnum {updated_data.get('assetnum')}: {e}") return updated_data diff --git a/src/modules/equipment/Eac.py b/src/modules/equipment/Eac.py index e9c1055..f79181b 100644 --- a/src/modules/equipment/Eac.py +++ b/src/modules/equipment/Eac.py @@ -308,9 +308,10 @@ class Eac: except Exception as e: print("Terjadi kesalahan saat memproses semua equipment:", str(e)) -def main(): +def main(assetnum=None): """ - Process all equipment EAC calculations. Returns list of processed asset numbers. + Process EAC calculations. If assetnum is provided (string), process only that asset; + otherwise process all equipment. Returns list of processed asset numbers. Raises RuntimeError if database connection cannot be established. """ connections = get_connection() @@ -321,26 +322,31 @@ def main(): cursor = connection.cursor(cursor_factory=DictCursor) processed = [] try: - query_main = "SELECT DISTINCT(assetnum) FROM ms_equipment_master" - cursor.execute(query_main) + if assetnum: + query_main = "SELECT DISTINCT(assetnum) FROM ms_equipment_master WHERE assetnum = %s" + cursor.execute(query_main, (assetnum,)) + else: + query_main = "SELECT DISTINCT(assetnum) FROM ms_equipment_master" + cursor.execute(query_main) + results = cursor.fetchall() eac = Eac() for row in results: try: - assetnum = row["assetnum"] + row_assetnum = row["assetnum"] except Exception: - assetnum = row[0] if len(row) > 0 else None + row_assetnum = row[0] if len(row) > 0 else None - if assetnum is None: + if row_assetnum is None: print("Skipping None assetnum") continue - print(f"Processing asset: {assetnum}") - eac.hitung_eac_equipment(assetnum) - processed.append(assetnum) + print(f"Processing asset: {row_assetnum}") + eac.hitung_eac_equipment(row_assetnum) + processed.append(row_assetnum) - print("EAC calculation finished for all equipment.") + print("EAC calculation finished for processed equipment.") return processed except Exception as e: diff --git a/src/modules/equipment/Prediksi.py b/src/modules/equipment/Prediksi.py index 3249b37..ee169c9 100644 --- a/src/modules/equipment/Prediksi.py +++ b/src/modules/equipment/Prediksi.py @@ -454,7 +454,7 @@ class Prediksi: raw_predictive_interval, raw_predictive_material_cost, raw_predictive_labor_time, raw_predictive_labor_human, "raw_loss_output_MW" as raw_loss_output_mw, raw_loss_output_price, raw_operational_cost, raw_maintenance_cost, - efdh_equivalent_forced_derated_hours, foh_forced_outage_hours, + efdh_equivalent_forced_derated_hours, foh_forced_outage_hours FROM lcc_equipment_tr_data WHERE assetnum = %s; ''' @@ -993,16 +993,20 @@ class Prediksi: RELIABILITY_APP_URL = os.getenv("RELIABILITY_APP_URL", "http://192.168.1.82:8000/reliability") -async def main(RELIABILITY_APP_URL=RELIABILITY_APP_URL, assetnum=None): +async def main(RELIABILITY_APP_URL=RELIABILITY_APP_URL, assetnum=None, token=None): connection = None try: prediksi = Prediksi(RELIABILITY_APP_URL) - # Sign in to obtain access_token/refresh_token before processing - signin_res = await prediksi.sign_in() - if not getattr(prediksi, "access_token", None): - print("Failed to obtain access token; aborting.") - return + # If token not provided, sign in to obtain access_token/refresh_token + if token is None: + signin_res = await prediksi.sign_in() + if not getattr(prediksi, "access_token", None): + print("Failed to obtain access token; aborting.") + return + else: + # Use provided token as access token + prediksi.access_token = token # If an assetnum was provided, run only for that assetnum if assetnum: @@ -1044,7 +1048,6 @@ async def main(RELIABILITY_APP_URL=RELIABILITY_APP_URL, assetnum=None): finally: if connection: connection.close() - if __name__ == "__main__": asyncio.run( diff --git a/src/modules/equipment/__pycache__/Eac.cpython-311.pyc b/src/modules/equipment/__pycache__/Eac.cpython-311.pyc index 026678b..d78681d 100644 Binary files a/src/modules/equipment/__pycache__/Eac.cpython-311.pyc and b/src/modules/equipment/__pycache__/Eac.cpython-311.pyc differ diff --git a/src/modules/equipment/__pycache__/Prediksi.cpython-311.pyc b/src/modules/equipment/__pycache__/Prediksi.cpython-311.pyc index 9093594..5cf07ad 100644 Binary files a/src/modules/equipment/__pycache__/Prediksi.cpython-311.pyc and b/src/modules/equipment/__pycache__/Prediksi.cpython-311.pyc differ diff --git a/src/modules/equipment/__pycache__/run.cpython-311.pyc b/src/modules/equipment/__pycache__/run.cpython-311.pyc index 6b3e3bb..f5309f3 100644 Binary files a/src/modules/equipment/__pycache__/run.cpython-311.pyc and b/src/modules/equipment/__pycache__/run.cpython-311.pyc differ diff --git a/src/plant_transaction_data/__pycache__/service.cpython-311.pyc b/src/plant_transaction_data/__pycache__/service.cpython-311.pyc index 935bf99..7cf3ef3 100644 Binary files a/src/plant_transaction_data/__pycache__/service.cpython-311.pyc and b/src/plant_transaction_data/__pycache__/service.cpython-311.pyc differ diff --git a/src/yeardata/__pycache__/model.cpython-311.pyc b/src/yeardata/__pycache__/model.cpython-311.pyc index 49c4e89..42306a4 100644 Binary files a/src/yeardata/__pycache__/model.cpython-311.pyc and b/src/yeardata/__pycache__/model.cpython-311.pyc differ diff --git a/src/yeardata/__pycache__/schema.cpython-311.pyc b/src/yeardata/__pycache__/schema.cpython-311.pyc index 658105f..e2b29df 100644 Binary files a/src/yeardata/__pycache__/schema.cpython-311.pyc and b/src/yeardata/__pycache__/schema.cpython-311.pyc differ