diff --git a/src/equipment/service.py b/src/equipment/service.py index 01ccd9d..dbc52b3 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -122,12 +122,16 @@ logger = logging.getLogger(__name__) MAXIMO_SQL = text( """ - SELECT + SELECT * FROM public.wo_maximo AS a WHERE a.asset_unit = '3' - AND a.asset_assetnum = :assetnum - AND a.wonum NOT LIKE 'T%' + AND a.asset_assetnum = 'A29133' + AND a.wonum NOT LIKE 'T%' + AND ( + (a.worktype = 'CM' AND a.wojp8 != 'S1') + OR (a.worktype <> 'CM') + ); """ ) @@ -381,10 +385,18 @@ async def get_top_10_economic_life(*, db_session: DbSession, common) -> list[Equ query = ( query.add_columns( - func.abs(current_year - Equipment.minimum_eac_year).label("economic_life") + func.case( + ( + (current_year - Equipment.minimum_eac_year) >= 0, + (current_year - Equipment.minimum_eac_year), + ), + else_=None, + ).label("economic_life") ) .filter(Equipment.minimum_eac_year != None) - .order_by(func.abs(current_year - Equipment.minimum_eac_year).desc()) + # .filter((current_year - Equipment.minimum_eac_year) >= 0) + .order_by((current_year - Equipment.minimum_eac_year).desc()) + .order_by(func.abs(Equipment.minimum_eac).desc()) ) # result = await db_session.execute(query) @@ -401,12 +413,20 @@ async def get_top_10_replacement_priorities(*, db_session: DbSession, common) -> current_year = datetime.datetime.now().year + # Only select rows where (current_year - Equipment.minimum_eac_year) >= 0 query = ( query.add_columns( - func.abs(current_year - Equipment.minimum_eac_year).label("economic_life") + func.case( + ( + (current_year - Equipment.minimum_eac_year) >= 0, + (current_year - Equipment.minimum_eac_year), + ), + else_=0, + ).label("economic_life") ) .filter(Equipment.minimum_eac_year != None) - .order_by(func.abs(current_year - Equipment.minimum_eac_year).asc()) + # .filter((current_year - Equipment.minimum_eac_year) >= 0) + .order_by((current_year - Equipment.minimum_eac_year).asc()) .order_by(func.abs(Equipment.minimum_eac).desc()) ) diff --git a/src/modules/equipment/Eac.py b/src/modules/equipment/Eac.py index f79181b..cf7cbdd 100644 --- a/src/modules/equipment/Eac.py +++ b/src/modules/equipment/Eac.py @@ -7,6 +7,7 @@ import os sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from config import get_connection +import argparse class Eac: @@ -34,6 +35,8 @@ class Eac: (SELECT value_num / 100 FROM lcc_ms_master WHERE name = 'inflation_rate') as inflation_rate , (SELECT value_num / 100 FROM lcc_ms_master WHERE name = 'discount_rate') as discount_rate , (select COALESCE(rc_total_cost,0) from lcc_equipment_tr_data ltd where assetnum = %s and seq = 0) as rc_total_cost_0 + , (SELECT value_num / 100 FROM lcc_ms_master WHERE name = 'history_inflation_rate') as history_inflation_rate + , (SELECT value_num / 100 FROM lcc_ms_master WHERE name = 'history_future_inflation_rate_annual') as history_future_inflation_rate_annual ; """ cursor.execute(query_inflation_rate, (equipment_id,)) @@ -44,6 +47,8 @@ class Eac: return None inflation_rate = inflation_rate_result["inflation_rate"] + history_inflation_rate = inflation_rate_result["history_inflation_rate"] + history_future_inflation_rate = inflation_rate_result["history_future_inflation_rate_annual"] disc_rate = inflation_rate_result["discount_rate"] rc_total_cost_0 = inflation_rate_result["rc_total_cost_0"] @@ -70,13 +75,13 @@ class Eac: # Rumus NPV: NPV = Σ [Ct / (1 + r)^t] # dimana Ct = cash flow pada periode t, r = disc_rate, t = periode final_value = sum( - value / ((1 + disc_rate) ** (i + 1)) + value / ((1 + history_inflation_rate) ** (i + 1)) for i, value in enumerate(cumulative_values) ) # Menghitung PMT biaya maintenance # Rumus PMT: PMT = PV * [r(1 + r)^n] / [(1 + r)^n – 1] - # dimana PV = final_value, r = disc_rate, n = row["seq"] - pmt_mnt_cost = -npf.pmt(disc_rate, row["seq"], final_value) + # dimana PV = final_value, r = history_future_inflation_rate, n = row["seq"] + pmt_mnt_cost = -npf.pmt(history_future_inflation_rate, row["seq"], final_value) eac_disposal_cost = 0.07 * pmt_mnt_cost # Menghitung PMT biaya akuisisi @@ -365,42 +370,13 @@ def main(assetnum=None): if __name__ == "__main__": - try: - connections = get_connection() - connection = connections[0] if isinstance(connections, tuple) else connections - if connection is None: - print("Database connection failed.") - sys.exit(1) - - cursor = connection.cursor(cursor_factory=DictCursor) - query_main = "SELECT DISTINCT(assetnum) FROM ms_equipment_master WHERE assetnum = 'A26190'" - cursor.execute(query_main) - results = cursor.fetchall() - - eac = Eac() - for row in results: - try: - assetnum = row["assetnum"] - except Exception: - assetnum = row[0] if len(row) > 0 else None - - if assetnum is None: - print("Skipping None assetnum") - continue - print(f"Processing asset: {assetnum}") - eac.hitung_eac_equipment(assetnum) - - print("EAC calculation finished for all equipment.") + parser = argparse.ArgumentParser(description="Run EAC calculation for equipment.") + parser.add_argument("--assetnum", type=str, help="Asset number to process (optional). If not provided, process all.") + args = parser.parse_args() + try: + processed = main(assetnum=args.assetnum) + print(f"EAC calculation finished for: {processed}") except Exception as e: print("Terjadi kesalahan saat memproses semua equipment:", str(e)) - finally: - try: - cursor.close() - except Exception: - pass - try: - connection.close() - except Exception: - pass diff --git a/src/modules/equipment/Prediksi.py b/src/modules/equipment/Prediksi.py index 8c18d05..e1b4782 100644 --- a/src/modules/equipment/Prediksi.py +++ b/src/modules/equipment/Prediksi.py @@ -18,7 +18,7 @@ import os from equipment.formula import rc_labor_cost, rc_lost_cost, rc_total_cost sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) -from config import get_connection +from config import get_connection, get_production_connection import json load_dotenv() @@ -435,10 +435,14 @@ class Prediksi: def __update_data_lcc(self, equipment_id): try: connections = get_connection() + production_connection = get_production_connection() connection = ( connections[0] if isinstance(connections, tuple) else connections ) - if connection is None: + production_connection = ( + production_connection[0] if isinstance(production_connection, tuple) else production_connection + ) + if connection is None or production_connection is None: print("Database connection failed.") return None @@ -464,13 +468,15 @@ class Prediksi: # Helper to get man_hour for a year (fallback to master 'manhours_rate') def _get_man_hour_for_year(year): try: - cur = connection.cursor() + # cur = connection.cursor() + prod_cur = production_connection.cursor() # cur.execute("SELECT man_hour FROM lcc_ms_year_data WHERE year = %s", (year,)) # r = cur.fetchone() # if r and r[0] is not None: # return float(r[0]) - cur.execute("SELECT value_num FROM lcc_ms_master WHERE name='manhours_rate'") - r2 = cur.fetchone() + # cur.execute("SELECT value_num FROM lcc_ms_master WHERE name='manhours_rate'") + prod_cur.execute("""SELECT value_num FROM lcc_ms_master WHERE name='manhours_rate'""") + r2 = prod_cur.fetchone() if r2 and r2[0] is not None: return float(r2[0]) except Exception: @@ -559,10 +565,10 @@ class Prediksi: rc_oh_material = raw_oh_material_cost rc_oh_labor = rc_labor_cost(raw_oh_interval, raw_oh_labor_time, raw_oh_labor_human, man_hour) - rc_lost = rc_lost_cost(raw_loss_output_mw, raw_loss_output_price, raw_cm_interval) + # rc_lost = rc_lost_cost(raw_loss_output_mw, raw_loss_output_price, raw_cm_interval) - rc_operation = raw_operational_cost - rc_maintenance = raw_maintenance_cost + # rc_operation = raw_operational_cost + # rc_maintenance = raw_maintenance_cost asset_criticality_data = self.__get_asset_criticality_params(equipment_id) asset_criticality_value = 0.0 @@ -587,9 +593,9 @@ class Prediksi: rc_pm=rc_pm_material + rc_pm_labor + ac_multiplier, rc_predictive=rc_predictive_material + rc_predictive_labor + ac_multiplier, rc_oh=rc_oh_material + rc_oh_labor + ac_multiplier, - rc_lost=rc_lost, - rc_operation=rc_operation, - rc_maintenance=rc_maintenance, + # rc_lost=rc_lost, + # rc_operation=rc_operation, + # rc_maintenance=rc_maintenance, ) id_val = r.get("id") if isinstance(r, dict) else r[0] @@ -605,9 +611,9 @@ class Prediksi: rc_predictive_labor, rc_oh_material, rc_oh_labor, - rc_lost, - rc_operation, - rc_maintenance, + # rc_lost, + # rc_operation, + # rc_maintenance, total, id_val, ), diff --git a/src/modules/equipment/insert_actual_data.py b/src/modules/equipment/insert_actual_data.py index 409e845..a5655e8 100644 --- a/src/modules/equipment/insert_actual_data.py +++ b/src/modules/equipment/insert_actual_data.py @@ -110,14 +110,14 @@ def get_recursive_query(cursor, assetnum, worktype="CM"): query = f""" select DATE_PART('year', a.reportdate) as tahun, - COUNT(a.wonum) as raw_{worktype.lower()}_interval, + COUNT(DISTINCT a.wonum) as raw_{worktype.lower()}_interval, sum(a.actmatcost) as raw_{worktype.lower()}_material_cost, ( ROUND(SUM(EXTRACT(EPOCH FROM (a.actfinish - a.actstart)) / 3600), 2) ) AS raw_{worktype.lower()}_labor_time, CASE - WHEN COUNT(b.laborcode) = 0 THEN 3 - ELSE COUNT(b.laborcode) + WHEN COUNT(DISTINCT b.laborcode) = 0 THEN 3 + ELSE COUNT(DISTINCT b.laborcode) END AS raw_{worktype.lower()}_labor_human from public.wo_maximo as a LEFT JOIN public.wo_maximo_labtrans AS b @@ -286,16 +286,16 @@ def _build_tr_row_values( data_predictive_row, "raw_predictive_labor_human" ) - raw_loss_output_MW = ( - data_tahunan_row.get("total_lost") - if data_tahunan_row and data_tahunan_row.get("total_lost") is not None - else 0 - ) - raw_loss_output_price = ( - data_tahunan_row.get("rp_per_kwh") - if data_tahunan_row and data_tahunan_row.get("rp_per_kwh") is not None - else 0 - ) + # raw_loss_output_MW = ( + # data_tahunan_row.get("total_lost") + # if data_tahunan_row and data_tahunan_row.get("total_lost") is not None + # else 0 + # ) + # raw_loss_output_price = ( + # data_tahunan_row.get("rp_per_kwh") + # if data_tahunan_row and data_tahunan_row.get("rp_per_kwh") is not None + # else 0 + # ) man_hour_value = ( data_tahunan_row.get("man_hour") @@ -364,8 +364,8 @@ def _build_tr_row_values( "raw_predictive_material_cost": raw_pdm_material_cost, "raw_predictive_labor_time": raw_pdm_labor_time, "raw_predictive_labor_human": raw_pdm_labor_human, - "raw_loss_output_MW": raw_loss_output_MW, - "raw_loss_output_price": raw_loss_output_price, + # "raw_loss_output_MW": raw_loss_output_MW, + # "raw_loss_output_price": raw_loss_output_price, "rc_cm_material_cost": rc_cm_material_cost, "rc_cm_labor_cost": rc_cm_labor_cost, "rc_pm_material_cost": rc_pm_material_cost, diff --git a/src/modules/equipment/run.py b/src/modules/equipment/run.py index 91937e9..d5624a0 100644 --- a/src/modules/equipment/run.py +++ b/src/modules/equipment/run.py @@ -17,23 +17,23 @@ except ImportError: async def main(): start_time = time.time() - # try: - # await query_data() - # except Exception as e: - # print(f"Error in query_data: {str(e)}") - # return + try: + await query_data() + except Exception as e: + print(f"Error in query_data: {str(e)}") + return - # try: - # await insert_acquisition_cost_data() - # except Exception as e: - # print(f"Error in insert_acquisition_cost_data: {str(e)}") - # return + try: + await insert_acquisition_cost_data() + except Exception as e: + print(f"Error in insert_acquisition_cost_data: {str(e)}") + return - # try: - # await predict_run() - # except Exception as e: - # print(f"Error in predict_equipment_data: {str(e)}") - # return + try: + await predict_run() + except Exception as e: + print(f"Error in predict_equipment_data: {str(e)}") + return try: # eac = Eac()