diff --git a/src/acquisition_cost/model.py b/src/acquisition_cost/model.py new file mode 100644 index 0000000..4e420ca --- /dev/null +++ b/src/acquisition_cost/model.py @@ -0,0 +1,12 @@ +from sqlalchemy import Column, Float, Integer, String +from src.database.core import Base +from src.models import DefaultMixin, IdentityMixin + + +class AcquisitionData(Base, DefaultMixin, IdentityMixin): + __tablename__ = "lcc_equipment_acq_cost_data" + + category_no = Column(String, nullable=False) + name = Column(String, nullable=False) + cost_unit_3_n_4 = Column(Float, nullable=False) + cost_unit_3 = Column(Float, nullable=False) diff --git a/src/equipment/model.py b/src/equipment/model.py index b854075..454c16c 100644 --- a/src/equipment/model.py +++ b/src/equipment/model.py @@ -23,6 +23,10 @@ class Equipment(Base, DefaultMixin, IdentityMixin): minimum_pmt = Column(Float, nullable=False) minimum_pmt_aq_cost = Column(Float, nullable=False) minimum_is_actual = Column(Integer, nullable=False) + efdh_equivalent_forced_derated_hours = Column(Float, nullable=False) + foh_forced_outage_hours = Column(Float, nullable=False) + category_no = Column(String, nullable=True) + proportion = Column(Float, nullable=True) equipment_master = relationship( "EquipmentMaster", @@ -96,5 +100,3 @@ class EquipmentTransactionRecords(Base, DefaultMixin, IdentityMixin): eac_eac = Column(Float, nullable=False) efdh_equivalent_forced_derated_hours = Column(Float, nullable=False) foh_forced_outage_hours = Column(Float, nullable=False) - category_no = Column(String, nullable=True) - proportion = Column(Float, nullable=True) \ No newline at end of file diff --git a/src/equipment/schema.py b/src/equipment/schema.py index 14faa5c..ef11c1f 100644 --- a/src/equipment/schema.py +++ b/src/equipment/schema.py @@ -16,18 +16,29 @@ class EquipmentBase(DefaultBase): forecasting_start_year: Optional[int] = Field(None, nullable=True) forecasting_target_year: Optional[int] = Field(None, nullable=True) manhours_rate: Optional[float] = Field(None, nullable=True) + min_eac_info: Optional[str] = Field(None, nullable=True) + harga_saat_ini: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) + minimum_eac_seq: Optional[int] = Field(None, nullable=True) + minimum_eac_year: Optional[int] = Field(None, nullable=True) + minimum_eac: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) + minimum_npv: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) + minimum_pmt: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) + minimum_pmt_aq_cost: Optional[float] = Field(None, nullable=True, le=MAX_PRICE) + minimum_is_actual: Optional[int] = 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) + category_no: Optional[str] = Field(None, nullable=True) + proportion: Optional[float] = Field(None, nullable=True) created_at: Optional[datetime] = Field(None, nullable=True) updated_at: Optional[datetime] = Field(None, nullable=True) created_by: Optional[str] = Field(None, nullable=True) updated_by: Optional[str] = Field(None, nullable=True) - class EquipmentMasterBase(DefaultBase): location_tag: Optional[str] = Field(None, nullable=True) assetnum: Optional[str] = Field(None, nullable=True) name: Optional[str] = Field(None, nullable=True) - class MasterBase(DefaultBase): assetnum: Optional[str] = Field(None, nullable=True) tahun: Optional[int] = Field(None, nullable=True) diff --git a/src/equipment/service.py b/src/equipment/service.py index 5f9556b..bbf512d 100644 --- a/src/equipment/service.py +++ b/src/equipment/service.py @@ -4,6 +4,7 @@ from sqlalchemy.orm import selectinload from src.database.service import search_filter_sort_paginate from src.equipment.model import Equipment, EquipmentTransactionRecords +from src.acquisition_cost.model import AcquisitionData from src.yeardata.model import Yeardata from ..equipment_master.model import EquipmentMaster from .schema import EquipmentCreate, EquipmentUpdate, MasterBase @@ -422,6 +423,19 @@ async def update( data = equipment_in.model_dump() update_data = equipment_in.model_dump(exclude_defaults=True) + # Check if proportion from AcquisitionData changed and recalculate acquisition_cost + if "proportion" in update_data: + acquisition_data_query = Select(AcquisitionData).filter( + AcquisitionData.assetnum == equipment.assetnum + ) + acquisition_data_result = await db_session.execute(acquisition_data_query) + acquisition_data = acquisition_data_result.scalars().one_or_none() + + if acquisition_data and acquisition_data.cost_unit_3: + new_proportion = update_data.get("proportion") + if new_proportion is not None: + equipment.acquisition_cost = (new_proportion * 0.01) * acquisition_data.cost_unit_3 + for field in data: if field in update_data: setattr(equipment, field, update_data[field]) diff --git a/src/modules/equipment/Prediksi.py b/src/modules/equipment/Prediksi.py index ee169c9..8c18d05 100644 --- a/src/modules/equipment/Prediksi.py +++ b/src/modules/equipment/Prediksi.py @@ -534,19 +534,19 @@ class Prediksi: rc_cm_labor = rc_labor_cost(raw_cm_interval, raw_cm_labor_time, raw_cm_labor_human, man_hour) try: - if np.isfinite(raw_pm_interval) and raw_pm_interval != 0: - rc_pm_material = raw_pm_material_cost * raw_pm_interval - else: - rc_pm_material = raw_pm_material_cost + # if np.isfinite(raw_pm_interval) and raw_pm_interval != 0: + # rc_pm_material = raw_pm_material_cost * raw_pm_interval + # else: + rc_pm_material = raw_pm_material_cost except Exception: rc_pm_material = 0.0 rc_pm_labor = rc_labor_cost(raw_pm_interval, raw_pm_labor_time, raw_pm_labor_human, man_hour) try: - if np.isfinite(raw_predictive_interval) and raw_predictive_interval != 0: - rc_predictive_material = raw_predictive_material_cost * raw_predictive_interval - else: - rc_predictive_material = raw_predictive_material_cost + # if np.isfinite(raw_predictive_interval) and raw_predictive_interval != 0: + # rc_predictive_material = raw_predictive_material_cost * raw_predictive_interval + # else: + rc_predictive_material = raw_predictive_material_cost except Exception: rc_predictive_material = 0.0 diff --git a/src/modules/equipment/insert_actual_data.py b/src/modules/equipment/insert_actual_data.py index aba96a0..409e845 100644 --- a/src/modules/equipment/insert_actual_data.py +++ b/src/modules/equipment/insert_actual_data.py @@ -109,10 +109,10 @@ 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, - sum(a.actmatcost) as raw_{worktype.lower()}_material_cost, - ( + DATE_PART('year', a.reportdate) as tahun, + COUNT(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 @@ -128,7 +128,8 @@ where AND a.asset_assetnum = '{assetnum}' and a.wonum not like 'T%' {f"AND a.wojp8 != 'S1'" if worktype == 'CM' else ""} -group by DATE_PART('year', a.reportdate); +group by DATE_PART('year', a.reportdate) +having ROUND(SUM(EXTRACT(EPOCH FROM (a.actfinish - a.actstart)) / 3600), 2) <= 730.001; """ # Eksekusi query dan fetch hasil cursor.execute(query)