|
|
|
@ -151,7 +151,7 @@ class Prediksi:
|
|
|
|
# connection.close()
|
|
|
|
# connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
# Fungsi untuk menyimpan data proyeksi ke database
|
|
|
|
# Fungsi untuk menyimpan data proyeksi ke database
|
|
|
|
async def __insert_predictions_to_db(self, data, equipment_id, token):
|
|
|
|
async def __insert_predictions_to_db(self, data, equipment_id, token, acquisition_year_ref=None):
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
connection, connection_wo_db = get_connection()
|
|
|
|
connection, connection_wo_db = get_connection()
|
|
|
|
if connection is None:
|
|
|
|
if connection is None:
|
|
|
|
@ -173,6 +173,7 @@ class Prediksi:
|
|
|
|
id,
|
|
|
|
id,
|
|
|
|
seq,
|
|
|
|
seq,
|
|
|
|
is_actual,
|
|
|
|
is_actual,
|
|
|
|
|
|
|
|
acquisition_year_ref,
|
|
|
|
tahun, assetnum,
|
|
|
|
tahun, assetnum,
|
|
|
|
rc_cm_material_cost,
|
|
|
|
rc_cm_material_cost,
|
|
|
|
rc_cm_labor_cost,
|
|
|
|
rc_cm_labor_cost,
|
|
|
|
@ -184,7 +185,7 @@ class Prediksi:
|
|
|
|
rc_predictive_labor_cost,
|
|
|
|
rc_predictive_labor_cost,
|
|
|
|
created_by, created_at
|
|
|
|
created_by, created_at
|
|
|
|
) VALUES (
|
|
|
|
) VALUES (
|
|
|
|
%s, %s, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'Sys', NOW()
|
|
|
|
%s, %s, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 'Sys', NOW()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
@ -235,7 +236,7 @@ class Prediksi:
|
|
|
|
|
|
|
|
|
|
|
|
check_existence_query = """
|
|
|
|
check_existence_query = """
|
|
|
|
SELECT id FROM lcc_equipment_tr_data
|
|
|
|
SELECT id FROM lcc_equipment_tr_data
|
|
|
|
WHERE assetnum = %s AND tahun = %s AND is_actual = 0
|
|
|
|
WHERE assetnum = %s AND tahun = %s AND is_actual = 0 AND (acquisition_year_ref = %s OR (acquisition_year_ref IS NULL AND %s IS NULL))
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
update_query = """
|
|
|
|
update_query = """
|
|
|
|
@ -256,7 +257,7 @@ class Prediksi:
|
|
|
|
|
|
|
|
|
|
|
|
for _, row in data.iterrows():
|
|
|
|
for _, row in data.iterrows():
|
|
|
|
# Check if data exists
|
|
|
|
# Check if data exists
|
|
|
|
cursor.execute(check_existence_query, (equipment_id, int(row["year"])))
|
|
|
|
cursor.execute(check_existence_query, (equipment_id, int(row["year"]), acquisition_year_ref, acquisition_year_ref))
|
|
|
|
existing_record = cursor.fetchone()
|
|
|
|
existing_record = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
if existing_record:
|
|
|
|
if existing_record:
|
|
|
|
@ -280,6 +281,7 @@ class Prediksi:
|
|
|
|
(
|
|
|
|
(
|
|
|
|
str(uuid4()), # id
|
|
|
|
str(uuid4()), # id
|
|
|
|
int(max_seq), # seq
|
|
|
|
int(max_seq), # seq
|
|
|
|
|
|
|
|
int(acquisition_year_ref) if acquisition_year_ref is not None else None, # acquisition_year_ref
|
|
|
|
int(row["year"]),
|
|
|
|
int(row["year"]),
|
|
|
|
equipment_id,
|
|
|
|
equipment_id,
|
|
|
|
float(row.get("rc_cm_material_cost", 0)) if not pd.isna(row.get("rc_cm_material_cost", 0)) else 0.0,
|
|
|
|
float(row.get("rc_cm_material_cost", 0)) if not pd.isna(row.get("rc_cm_material_cost", 0)) else 0.0,
|
|
|
|
@ -743,8 +745,97 @@ class Prediksi:
|
|
|
|
if connection:
|
|
|
|
if connection:
|
|
|
|
connection.close()
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def __update_equipment_acquisition_year(self, assetnum: str):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Update acquisition_year from wo_maximo and set default forecasting_target_year
|
|
|
|
|
|
|
|
using raw SQL connections.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
# 1. Fetch first acquisition year from wo_maximo (production db)
|
|
|
|
|
|
|
|
prod_conn = get_production_connection()
|
|
|
|
|
|
|
|
if not prod_conn:
|
|
|
|
|
|
|
|
print("Failed to connect to production DB for acquisition year update.")
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
first_year = None
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
p_cursor = prod_conn.cursor()
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
p_cursor.execute(query, (assetnum,))
|
|
|
|
|
|
|
|
res = p_cursor.fetchone()
|
|
|
|
|
|
|
|
if res and res[0] is not None:
|
|
|
|
|
|
|
|
first_year = int(res[0])
|
|
|
|
|
|
|
|
p_cursor.close()
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
|
|
prod_conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not first_year:
|
|
|
|
|
|
|
|
# No data, skip update
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 2. Update local DB
|
|
|
|
|
|
|
|
conn, _ = get_connection()
|
|
|
|
|
|
|
|
if not conn:
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updated_acq = None
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
cursor = conn.cursor(cursor_factory=DictCursor)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Fetch current values
|
|
|
|
|
|
|
|
cursor.execute("SELECT acquisition_year, design_life, forecasting_target_year FROM lcc_ms_equipment_data WHERE assetnum = %s", (assetnum,))
|
|
|
|
|
|
|
|
current = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if current:
|
|
|
|
|
|
|
|
curr_acq = int(current["acquisition_year"])
|
|
|
|
|
|
|
|
curr_life = int(current["design_life"])
|
|
|
|
|
|
|
|
curr_target = int(current["forecasting_target_year"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Logic: if current_target matches the "old default" (old_acq + life), then update it too.
|
|
|
|
|
|
|
|
is_valid_default = (curr_target == (curr_acq + curr_life))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if curr_acq != first_year:
|
|
|
|
|
|
|
|
new_target = curr_target
|
|
|
|
|
|
|
|
if is_valid_default:
|
|
|
|
|
|
|
|
new_target = first_year + curr_life
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update_q = """
|
|
|
|
|
|
|
|
UPDATE lcc_ms_equipment_data
|
|
|
|
|
|
|
|
SET acquisition_year = %s, forecasting_target_year = %s
|
|
|
|
|
|
|
|
WHERE assetnum = %s
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
cursor.execute(update_q, (first_year, new_target, assetnum))
|
|
|
|
|
|
|
|
conn.commit()
|
|
|
|
|
|
|
|
print(f"Updated acquisition_year for {assetnum}: {curr_acq} -> {first_year}")
|
|
|
|
|
|
|
|
updated_acq = first_year
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
updated_acq = curr_acq
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
# Logic if equipment not found? Unlikely here.
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return updated_acq
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
print(f"Error updating acquisition year for {assetnum}: {e}")
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
async def predict_equipment_data(self, assetnum, token):
|
|
|
|
async def predict_equipment_data(self, assetnum, token):
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
|
|
|
|
# Update acquisition year first
|
|
|
|
|
|
|
|
acquisition_year_ref = await self.__update_equipment_acquisition_year(assetnum)
|
|
|
|
|
|
|
|
|
|
|
|
# Mengambil data dari database
|
|
|
|
# Mengambil data dari database
|
|
|
|
df = self.__fetch_data_from_db(assetnum)
|
|
|
|
df = self.__fetch_data_from_db(assetnum)
|
|
|
|
if df is None:
|
|
|
|
if df is None:
|
|
|
|
@ -999,7 +1090,7 @@ class Prediksi:
|
|
|
|
# Insert hasil prediksi ke database
|
|
|
|
# Insert hasil prediksi ke database
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
await self.__insert_predictions_to_db(
|
|
|
|
await self.__insert_predictions_to_db(
|
|
|
|
predictions_df, assetnum, token
|
|
|
|
predictions_df, assetnum, token, acquisition_year_ref
|
|
|
|
)
|
|
|
|
)
|
|
|
|
except Exception as e:
|
|
|
|
except Exception as e:
|
|
|
|
print(f"Error saat insert data ke database: {e}")
|
|
|
|
print(f"Error saat insert data ke database: {e}")
|
|
|
|
|