From a770bf85d5624f88613a4602e3f800d1161471a5 Mon Sep 17 00:00:00 2001 From: Cizz22 Date: Fri, 17 Jan 2025 14:04:11 +0700 Subject: [PATCH] fix time constaint calculation --- src/api.py | 10 +++--- src/calculation_time_constrains/flows.py | 1 + src/calculation_time_constrains/model.py | 11 +++--- src/calculation_time_constrains/schema.py | 39 +++++++++++----------- src/calculation_time_constrains/service.py | 24 +++---------- src/overhaul_scope/model.py | 2 +- src/overhaul_scope/service.py | 8 +++-- src/overhaul_scope/utils.py | 33 ++++++++++++++++++ 8 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 src/overhaul_scope/utils.py diff --git a/src/api.py b/src/api.py index bf6bdb9..0056736 100644 --- a/src/api.py +++ b/src/api.py @@ -10,7 +10,6 @@ from src.auth.service import JWTBearer # from src.overhaul_scope.router import router as scope_router # from src.scope_equipment.router import router as scope_equipment_router # from src.overhaul.router import router as overhaul_router -# from src.calculation_time_constrains.router import router as calculation_time_constrains_router # from src.overhaul_history.router import router as overhaul_history_router # from src.overhaul_activity.router import router as scope_equipment_activity_router # # from src.overhaul_schedule.router import router as ovehaul_schedule_router @@ -27,6 +26,9 @@ from src.overhaul_activity.router import router as overhaul_activity_router from src.calculation_target_reliability.router import router as calculation_target_reliability from src.scope_equipment_job.router import router as scope_equipment_job_router from src.job.router import router as job_router +from src.calculation_time_constrains.router import router as calculation_time_constrains_router + + class ErrorMessage(BaseModel): msg: str @@ -101,9 +103,9 @@ authenticated_api_router.include_router( # calculation calculation_router = APIRouter(prefix="/calculation", tags=["calculations"]) -# # Time constrains -# calculation_router.include_router( -# calculation_time_constrains_router, prefix="/time-constraint", tags=["calculation", "time_constraint"]) +# Time constrains +calculation_router.include_router( + calculation_time_constrains_router, prefix="/time-constraint", tags=["calculation", "time_constraint"]) # Target reliability calculation_router.include_router( diff --git a/src/calculation_time_constrains/flows.py b/src/calculation_time_constrains/flows.py index f215092..4ca8540 100644 --- a/src/calculation_time_constrains/flows.py +++ b/src/calculation_time_constrains/flows.py @@ -66,6 +66,7 @@ async def create_calculation(*, db_session: DbSession, calculation_time_constrai results = await create_calculation_result_service(db_session=db_session, calculation_id=calculation_data.id) + return results diff --git a/src/calculation_time_constrains/model.py b/src/calculation_time_constrains/model.py index 12b552f..5e3b76c 100644 --- a/src/calculation_time_constrains/model.py +++ b/src/calculation_time_constrains/model.py @@ -62,9 +62,12 @@ class CalculationData(Base, DefaultMixin, IdentityMixin): parameter_id = Column(UUID(as_uuid=True), ForeignKey( 'oh_ms_calculation_param.id'), nullable=True) - overhaul_session_id= Column(UUID(as_uuid=True), ForeignKey('oh_ms_overhaul.id')) + overhaul_session_id= Column(UUID(as_uuid=True), ForeignKey('oh_ms_overhaul_scope.id')) optimum_oh_day = Column(Integer, nullable=True) + session = relationship( + "OverhaulScope", lazy="raise") + parameter = relationship( "CalculationParam", back_populates="calculation_data") @@ -72,8 +75,7 @@ class CalculationData(Base, DefaultMixin, IdentityMixin): @classmethod async def create_with_param( cls, - overhaul_reference_type: str, - reference_id: Union[str, UUID], + overhaul_session_id: str, db: DbSession, avg_failure_cost: Optional[float], overhaul_cost: Optional[float], @@ -93,8 +95,7 @@ class CalculationData(Base, DefaultMixin, IdentityMixin): params_id = params.id calculation_data = cls( - overhaul_reference_type=overhaul_reference_type, - reference_id=str(reference_id), + overhaul_session_id=overhaul_session_id, created_by=created_by, parameter_id=params_id ) diff --git a/src/calculation_time_constrains/schema.py b/src/calculation_time_constrains/schema.py index 9862668..9867a7a 100644 --- a/src/calculation_time_constrains/schema.py +++ b/src/calculation_time_constrains/schema.py @@ -6,6 +6,7 @@ from uuid import UUID from pydantic import Field from src.models import DefultBase +from dataclasses import dataclass class CalculationTimeConstrainsBase(DefultBase): @@ -54,13 +55,28 @@ class CalculationResultsRead(CalculationTimeConstrainsBase): overhaul_cost: float num_failures: int +class OptimumResult(CalculationTimeConstrainsBase): + overhaul_cost: float + corrective_cost: float + num_failures: int + days: int + + +class EquipmentResult(CalculationTimeConstrainsBase): + corrective_costs: List[float] + overhaul_costs: List[float] + daily_failures: List[float] + assetnum: str + material_cost: float + service_cost: float + optimum: OptimumResult # Added optimum result for each equipment class CalculationTimeConstrainsRead(CalculationTimeConstrainsBase): id: Union[UUID, str] - name: str - results: List[Any] - equipment_results: List[Any] - optimumOh: Dict[str, Any] + reference: UUID + results: List[CalculationResultsRead] + equipment_results: List[EquipmentResult] + optimum_oh: Any class CalculationTimeConstrainsCreate(CalculationTimeConstrainsBase): @@ -71,19 +87,4 @@ class CalculationTimeConstrainsSimulationRead(CalculationTimeConstrainsBase): simulation: CalculationResultsRead -@dataclass -class EquipmentResult: - corrective_costs: List[float] - overhaul_costs: List[float] - daily_failures: List[float] - equipment_id: str - material_cost: float - service_cost: float - optimum: OptimumResult # Added optimum result for each equipment -@dataclass -class OptimumResult: - overhaul_cost: float - corrective_cost: float - num_failures: int - days: int \ No newline at end of file diff --git a/src/calculation_time_constrains/service.py b/src/calculation_time_constrains/service.py index 3974dc8..f2856fe 100644 --- a/src/calculation_time_constrains/service.py +++ b/src/calculation_time_constrains/service.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, Optional, Tuple from uuid import UUID import numpy as np from sqlalchemy import and_, func, select @@ -17,6 +17,7 @@ from src.scope_equipment.service import get_by_assetnum def get_overhaul_cost_by_time_chart(overhaul_cost: float, days: int) -> list: exponents = np.arange(0, days) results = overhaul_cost / (2 ** exponents) + results = np.where(np.isfinite(results), results, 0) return results @@ -43,24 +44,10 @@ def get_corrective_cost_time_chart(material_cost: float, service_cost: float, da async def create_param_and_data(*, db_session: DbSession, calculation_param_in: CalculationTimeConstrainsParametersCreate, created_by: str, parameter_id: Optional[UUID] = None): """Creates a new document.""" - if calculation_param_in.scopeOH is None and calculation_param_in.assetnum is None: + if calculation_param_in.ohSessionId is None: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail="Either scope_id or assetnum must be provided" - ) - - if calculation_param_in.scopeOH is not None and calculation_param_in.assetnum is not None: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Only one of scope_id or assetnum must be provided" - ) - - scope = await get_by_scope_name(db_session=db_session, scope_name=calculation_param_in.scopeOH) if calculation_param_in.scopeOH is not None else None - - if calculation_param_in.scopeOH is not None and scope is None: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Scope not found" + detail="overhaul_session_id is required" ) calculationData = await CalculationData.create_with_param( @@ -217,7 +204,7 @@ async def create_calculation_result_service( corrective_costs=corrective_costs.tolist(), overhaul_costs=overhaul_cost_points.tolist(), daily_failures=daily_failures.tolist(), - equipment_id=eq.id, + assetnum=eq.assetnum, material_cost=eq.material_cost, service_cost=eq.service_cost, optimum=equipment_optimum @@ -262,7 +249,6 @@ async def create_calculation_result_service( # Return results including individual equipment data return CalculationTimeConstrainsRead( id=calculation.id, - name=calculation.name, reference=calculation.overhaul_session_id, results=calculation_results, optimum_oh=optimum, diff --git a/src/overhaul_scope/model.py b/src/overhaul_scope/model.py index 4728f84..58dcf18 100644 --- a/src/overhaul_scope/model.py +++ b/src/overhaul_scope/model.py @@ -18,4 +18,4 @@ class OverhaulScope(Base, DefaultMixin): activity_equipments = relationship( "OverhaulActivity", lazy="selectin" - ) + ) \ No newline at end of file diff --git a/src/overhaul_scope/service.py b/src/overhaul_scope/service.py index 8e66229..1e48a3f 100644 --- a/src/overhaul_scope/service.py +++ b/src/overhaul_scope/service.py @@ -8,6 +8,7 @@ from src.scope_equipment.service import get_by_scope_name from src.utils import time_now from .model import OverhaulScope from .schema import ScopeCreate, ScopeUpdate +from .utils import get_material_cost, get_service_cost from typing import Optional from src.database.core import DbSession @@ -48,12 +49,15 @@ async def create(*, db_session: DbSession, scope_in: ScopeCreate): scope_name=scope_name ) + material_cost = get_material_cost(scope=overhaul_session.type, total_equipment=len(equipments)) + service_cost = get_service_cost(scope=overhaul_session.type, total_equipment=len(equipments)) + scope_equipments = [ OverhaulActivity( assetnum=equipment.assetnum, overhaul_scope_id=overhaul_session.id, - material_cost=100000, - service_cost=100000, + material_cost=material_cost, + service_cost=service_cost, ) for equipment in equipments ] diff --git a/src/overhaul_scope/utils.py b/src/overhaul_scope/utils.py new file mode 100644 index 0000000..6675945 --- /dev/null +++ b/src/overhaul_scope/utils.py @@ -0,0 +1,33 @@ +from decimal import Decimal, getcontext + +def get_material_cost(scope, total_equipment): + # Set precision to 28 digits (maximum precision for Decimal) + getcontext().prec = 28 + + if not total_equipment: # Guard against division by zero + return float(0) + + if scope == 'B': + result = Decimal('365539731101') / Decimal(str(total_equipment)) + return float(result) + else: + result = Decimal('8565468127') / Decimal(str(total_equipment)) + return float(result) + + return float(0) + +def get_service_cost(scope, total_equipment): + # Set precision to 28 digits (maximum precision for Decimal) + getcontext().prec = 28 + + if not total_equipment: # Guard against division by zero + return float(0) + + if scope == 'B': + result = Decimal('36405830225') / Decimal(str(total_equipment)) + return float(result) + else: + result = Decimal('36000000000') / Decimal(str(total_equipment)) + return float(result) + + return float(0) \ No newline at end of file