From 38dbafbe3be93767e3ce5bba55f7acf5d6c600d4 Mon Sep 17 00:00:00 2001 From: MrWaradana Date: Mon, 24 Nov 2025 16:04:45 +0700 Subject: [PATCH] simulate plant if umur_teknis change --- src/masterdata/service.py | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/masterdata/service.py b/src/masterdata/service.py index 4821b63..6a12d3a 100644 --- a/src/masterdata/service.py +++ b/src/masterdata/service.py @@ -1,4 +1,8 @@ from sqlalchemy import Select, Delete +import asyncio +import os +from subprocess import PIPE +from datetime import datetime from src.database.service import search_filter_sort_paginate from .model import MasterData @@ -143,9 +147,14 @@ async def bulk_update( records_map = {str(record.id): record for record in records} records_by_name = {record.name: record for record in records} + # Track if umur_teknis was changed in this batch + umur_changed = False + umur_new_value = None + # Process updates in batches updated_records = [] for masterdata_id, masterdata_in in zip(ids, updates): + masterdata = records_map.get(masterdata_id) print("Processing update for ID:", masterdata) if not masterdata: @@ -181,6 +190,13 @@ async def bulk_update( for field, val in update_data.items(): if field in attr_fields: setattr(masterdata, field, val) + # If this record itself represents umur_teknis, detect change + if getattr(masterdata, "name", None) == "umur_teknis": + umur_changed = True + try: + umur_new_value = float(masterdata.value_num) + except Exception: + umur_new_value = None else: # Field is not a direct attribute: treat it as a named masterdata # e.g. payload included {"discount_rate": 5.0} @@ -191,6 +207,12 @@ async def bulk_update( # Update numeric or string value depending on payload if isinstance(val, (int, float)): other.value_num = val + if other.name == "umur_teknis": + umur_changed = True + try: + umur_new_value = float(other.value_num) + except Exception: + umur_new_value = None else: other.value_str = str(val) # keep updated record available for batch calculations @@ -242,6 +264,44 @@ async def bulk_update( # Commit all changes in a single transaction await db_session.commit() + # If umur_teknis changed, clear projection rows and trigger recalculation + if umur_changed: + try: + # Determine current year + current_year = datetime.now(datetime.timezone.utc).year + + # Import model locally to avoid circular imports + from src.plant_transaction_data.model import PlantTransactionData + + # Delete projection rows (is_actual == 0) from current year onward + del_q = Delete(PlantTransactionData).where( + PlantTransactionData.is_actual == 0, + PlantTransactionData.tahun >= current_year, + ) + await db_session.execute(del_q) + await db_session.commit() + + # Trigger recalculation by running the plant module script + directory_path = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../modules/plant") + ) + script_path = os.path.join(directory_path, "run.py") + + process = await asyncio.create_subprocess_exec( + "python", + script_path, + stdout=PIPE, + stderr=PIPE, + cwd=directory_path, + ) + stdout, stderr = await process.communicate() + if process.returncode != 0: + print(f"Plant recalc error: {stderr.decode()}") + else: + print(f"Plant recalc output: {stdout.decode()}") + except Exception as e: + print(f"Error during umur_teknis recalculation: {e}") + return updated_records