add new endpoint

main
Cizz22 1 year ago
parent 63dd671ef7
commit b1f21c8c48

@ -25,6 +25,7 @@ from src.scope_equipment.router import router as scope_equipment_router
from src.overhaul_scope.router import router as scope_router from src.overhaul_scope.router import router as scope_router
from src.overhaul_activity.router import router as overhaul_activity_router 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.calculation_target_reliability.router import router as calculation_target_reliability
from src.scope_equipment_job.router import router as scope_equipment_job_router
class ErrorMessage(BaseModel): class ErrorMessage(BaseModel):
msg: str msg: str
@ -70,6 +71,10 @@ authenticated_api_router.include_router(
overhaul_activity_router, prefix="/overhaul-activity", tags=["activity"] overhaul_activity_router, prefix="/overhaul-activity", tags=["activity"]
) )
authenticated_api_router.include_router(
scope_equipment_job_router, prefix="/scope-equipment-jobs"
)
# authenticated_api_router.include_router( # authenticated_api_router.include_router(
# overhaul_history_router, prefix="/overhaul-history", tags=["overhaul_history"] # overhaul_history_router, prefix="/overhaul-history", tags=["overhaul_history"]
# ) # )

@ -8,21 +8,21 @@ from sqlalchemy.ext.hybrid import hybrid_property
class MasterActivity(Base, DefaultMixin): class MasterActivity(Base, DefaultMixin):
__tablename__ = "oh_ms_activity" __tablename__ = "oh_ms_job"
name = Column(String, nullable=False) name = Column(String, nullable=False)
details = relationship( # details = relationship(
"MasterActivityDetail", # "MasterActivityDetail",
lazy="raise", # lazy="raise",
primaryjoin="and_(MasterActivity.id == foreign(MasterActivityDetail.activity_id))", # primaryjoin="and_(MasterActivity.id == foreign(MasterActivityDetail.activity_id))",
) # )
class MasterActivityDetail(Base, DefaultMixin): # class MasterActivityDetail(Base, DefaultMixin):
__tablename__ = "oh_ms_activity_detail" # __tablename__ = "oh_ms_activity_detail"
name = Column(String, nullable=False) # name = Column(String, nullable=False)
activity_id = Column(UUID(as_uuid=True)) # activity_id = Column(UUID(as_uuid=True))

@ -13,8 +13,7 @@ class OverhaulActivityBase(DefultBase):
class OverhaulActivityCreate(OverhaulActivityBase): class OverhaulActivityCreate(OverhaulActivityBase):
material_cost: Optional[float] = Field(0) assetnums: List[str]
service_cost: Optional[float] = Field(0)
class OverhaulActivityUpdate(OverhaulActivityBase): class OverhaulActivityUpdate(OverhaulActivityBase):

@ -1,11 +1,13 @@
import asyncio
from uuid import UUID from uuid import UUID
from sqlalchemy import Select, Delete from sqlalchemy import Select, Delete, func, insert, select, update as sqlUpdate
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from typing import List, Optional from typing import List, Optional
from src.scope_equipment.model import ScopeEquipment from src.overhaul_activity.utils import get_material_cost, get_service_cost
from src.overhaul_scope.model import OverhaulScope
from .model import OverhaulActivity from .model import OverhaulActivity
from .schema import OverhaulActivityCreate, OverhaulActivityUpdate, OverhaulActivityRead from .schema import OverhaulActivityCreate, OverhaulActivityUpdate, OverhaulActivityRead
@ -13,6 +15,7 @@ from .schema import OverhaulActivityCreate, OverhaulActivityUpdate, OverhaulActi
from src.database.core import DbSession from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate from src.database.service import CommonParameters, search_filter_sort_paginate
from src.auth.service import CurrentUser from src.auth.service import CurrentUser
from src.overhaul_scope.service import get as get_session
async def get(*, db_session: DbSession, assetnum: str, overhaul_session_id: Optional[UUID] = None) -> Optional[OverhaulActivityRead]: async def get(*, db_session: DbSession, assetnum: str, overhaul_session_id: Optional[UUID] = None) -> Optional[OverhaulActivityRead]:
@ -45,38 +48,83 @@ async def get_all(*, common: CommonParameters, overhaul_session_id: UUID, assetn
return results return results
# async def create(*, db_session: DbSession, overhaul_activty_in: OverhaulActivityCreate, overhaul_session_id: UUID):
# # Check if the combination of assetnum and activity_id already exists
# existing_equipment_query = (
# Select(OverhaulActivity)
# .where(
# OverhaulActivity.assetnum == overhaul_activty_in.assetnum,
# OverhaulActivity.overhaul_scope_id == overhaul_session_id
# )
# )
# result = await db_session.execute(existing_equipment_query)
# existing_activity = result.scalar_one_or_none()
# # If the combination exists, raise an exception or return the existing activity
# if existing_activity:
# raise ValueError("This assetnum already exist.")
# activity = OverhaulActivity(
# **overhaul_activty_in.model_dump(),
# overhaul_scope_id=overhaul_session_id)
# db_session.add(activity)
# await db_session.commit()
# # Refresh and load relationships using joinedload
# query = (
# Select(OverhaulActivity)
# .options(joinedload(OverhaulActivity.equipment))
# .where(OverhaulActivity.id == activity.id)
# )
# result = await db_session.execute(query)
# activity_with_relationship = result.scalar_one()
# return activity_with_relationship
async def create(*, db_session: DbSession, overhaul_activty_in: OverhaulActivityCreate, overhaul_session_id: UUID): async def create(*, db_session: DbSession, overhaul_activty_in: OverhaulActivityCreate, overhaul_session_id: UUID):
# Check if the combination of assetnum and activity_id already exists """Creates a new document."""
existing_equipment_query = ( assetnums = overhaul_activty_in.assetnums
Select(OverhaulActivity) if not assetnums:
.where( return []
OverhaulActivity.assetnum == overhaul_activty_in.assetnum,
OverhaulActivity.overhaul_scope_id == overhaul_session_id # Get session and count in parallel
session, equipment_count = await asyncio.gather(
get_session(db_session=db_session, overhaul_session_id=overhaul_session_id),
db_session.scalar(
select(func.count())
.select_from(OverhaulActivity)
.where(OverhaulActivity.overhaul_scope_id == overhaul_session_id)
) )
) )
result = await db_session.execute(existing_equipment_query)
existing_activity = result.scalar_one_or_none()
# If the combination exists, raise an exception or return the existing activity
if existing_activity:
raise ValueError("This assetnum already exist.")
activity = OverhaulActivity( # Calculate costs for all records
**overhaul_activty_in.model_dump(), total_equipment = equipment_count + len(assetnums)
overhaul_scope_id=overhaul_session_id) material_cost = get_material_cost(scope=session.type, total_equipment=total_equipment)
db_session.add(activity) service_cost = get_service_cost(scope=session.type, total_equipment=total_equipment)
await db_session.commit()
# Bulk create new activities
# Refresh and load relationships using joinedload overhaul_activities = [
query = ( OverhaulActivity(
Select(OverhaulActivity) assetnum=assetnum,
.options(joinedload(OverhaulActivity.equipment)) overhaul_scope_id=overhaul_session_id,
.where(OverhaulActivity.id == activity.id) material_cost=material_cost,
service_cost=service_cost
)
for assetnum in assetnums
]
# Add new records and update all existing records in parallel
await asyncio.gather(
db_session.add_all(overhaul_activities),
db_session.execute(
update(OverhaulActivity)
.where(OverhaulActivity.overhaul_scope_id == overhaul_session_id)
.values(material_cost=material_cost, service_cost=service_cost)
)
) )
result = await db_session.execute(query)
activity_with_relationship = result.scalar_one() await db_session.commit()
return assetnums
return activity_with_relationship
async def update(*, db_session: DbSession, activity: OverhaulActivity, overhaul_activity_in: OverhaulActivityUpdate): async def update(*, db_session: DbSession, activity: OverhaulActivity, overhaul_activity_in: OverhaulActivityUpdate):

@ -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)

@ -0,0 +1,22 @@
from sqlalchemy import UUID, Column, Float, Integer, String, ForeignKey
from src.database.core import Base
from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
from sqlalchemy.orm import relationship
from src.workorder.model import MasterWorkOrder
from sqlalchemy.ext.hybrid import hybrid_property
class ScopeEquipmentJob(Base, DefaultMixin):
__tablename__ = "oh_mas_scope_equipment_job"
assetnum = Column(String, nullable=False)
job_id = Column(UUID(as_uuid=True), ForeignKey(
"oh_ms_job.id", ondelete="cascade"))
master_equipments = relationship(
"MasterEquipment", lazy="raise", primaryjoin="and_(ScopeEquipmentJob.assetnum == foreign(MasterEquipment.assetnum))", uselist=False)
job = relationship(
"MasterActivity", lazy="raise"
)

@ -0,0 +1,41 @@
from typing import Dict, List
from fastapi import APIRouter, HTTPException, Query, status
from .service import get_all, delete, create
from .schema import ScopeEquipmentJobCreate, ScopeEquipmentJobPagination
from src.models import StandardResponse
from src.database.service import CommonParameters, search_filter_sort_paginate, DbSession
router = APIRouter()
@router.get("/{assetnum}", response_model=StandardResponse[ScopeEquipmentJobPagination])
async def get_scope_equipment_jobs(db_session: DbSession, assetnum, common: CommonParameters):
"""Get all scope activity pagination."""
# return
data = await get_all(db_session=db_session, assetnum=assetnum, common=common)
return StandardResponse(
data=data,
message="Data retrieved successfully",
)
@router.post("/{assetnum}", response_model=StandardResponse[None])
async def create_scope_equipment_jobs(db_session: DbSession, assetnum, scope_job_in: ScopeEquipmentJobCreate):
"""Get all scope activity pagination."""
# return
await create(db_session=db_session, assetnum=assetnum, scope_job_in=scope_job_in)
return StandardResponse(
data=None,
message="Data created successfully",
)
@router.delete("/{assetnum}", response_model=StandardResponse[None])
async def delete_scope_equipment_job(db_session: DbSession, assetnum, scope_job_id):
await delete(db_session=db_session, assetnum=assetnum, scope_job_id=scope_job_id)

@ -0,0 +1,70 @@
from datetime import datetime
from typing import Any, Dict, List, Optional
from uuid import UUID
from pydantic import Field, BaseModel
from src.job.schema import ActivityMasterRead
from src.models import DefultBase, Pagination
class ScopeEquipmentJobBase(DefultBase):
assetnum: str = Field(..., description="Assetnum is required")
class ScopeEquipmentJobCreate(ScopeEquipmentJobBase):
job_ids: Optional[List[UUID]] = []
class ScopeEquipmentJobUpdate(ScopeEquipmentJobBase):
name: Optional[str] = Field(None)
cost: Optional[str] = Field(0)
class ScopeEquipmentJobRead(ScopeEquipmentJobBase):
id: UUID
assetnum: str
job: ActivityMasterRead
class ScopeEquipmentJobPagination(Pagination):
items: List[ScopeEquipmentJobRead] = []
# {
# "overview": {
# "totalEquipment": 30,
# "nextSchedule": {
# "date": "2025-01-12",
# "Overhaul": "B",
# "equipmentCount": 30
# }
# },
# "criticalParts": [
# "Boiler feed pump",
# "Boiler reheater system",
# "Drum Level (Right) Root Valve A",
# "BCP A Discharge Valve",
# "BFPT A EXH Press HI Root VLV"
# ],
# "schedules": [
# {
# "date": "2025-01-12",
# "Overhaul": "B",
# "status": "upcoming"
# }
# // ... other scheduled overhauls
# ],
# "systemComponents": {
# "boiler": {
# "status": "operational",
# "lastOverhaul": "2024-06-15"
# },
# "turbine": {
# "hpt": { "status": "operational" },
# "ipt": { "status": "operational" },
# "lpt": { "status": "operational" }
# }
# // ... other major components
# }
# }

@ -0,0 +1,94 @@
import random
from sqlalchemy import Select, Delete, and_
from sqlalchemy.orm import selectinload
from typing import Optional
from src.scope_equipment.model import MasterEquipment, MasterEquipmentTree
from src.scope_equipment.service import get_equipment_level_by_no
from .model import ScopeEquipmentJob
from .schema import ScopeEquipmentJobCreate
from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from src.auth.service import CurrentUser
# async def get(*, db_session: DbSession, scope_equipment_activity_id: str) -> Optional[ScopeEquipmentActivity]:
# """Returns a document based on the given document id."""
# result = await db_session.get(ScopeEquipmentActivity, scope_equipment_activity_id)
# return result
async def get_all(db_session: DbSession, assetnum: Optional[str], common):
# Example usage
if not assetnum:
raise ValueError("assetnum parameter is required")
# First get the parent equipment
equipment_stmt = Select(MasterEquipment).where(
MasterEquipment.assetnum == assetnum)
equipment: MasterEquipment = await db_session.scalar(equipment_stmt)
if not equipment:
raise ValueError(f"No equipment found with assetnum: {assetnum}")
# Build query for parts
stmt = (
Select(ScopeEquipmentJob)
.where(
ScopeEquipmentJob.assetnum == assetnum
).options(selectinload(ScopeEquipmentJob.job))
)
results = await search_filter_sort_paginate(model=stmt, **common)
return results
async def create(*, db_session: DbSession, assetnum, scope_job_in: ScopeEquipmentJobCreate):
scope_jobs = []
if not assetnum:
raise ValueError("assetnum parameter is required")
# First get the parent equipment
equipment_stmt = Select(MasterEquipment).where(
MasterEquipment.assetnum == assetnum)
equipment: MasterEquipment = await db_session.scalar(equipment_stmt)
if not equipment:
raise ValueError(f"No equipment found with assetnum: {assetnum}")
for job_id in scope_job_in.job_ids:
scope_equipment_job = ScopeEquipmentJob(
assetnum=assetnum, job_id=job_id)
scope_jobs.appeand(scope_equipment_job)
db_session.add_all(scope_jobs)
await db_session.commit()
return
# async def update(*, db_session: DbSession, activity: ScopeEquipmentActivity, scope_equipment_activty_in: ScopeEquipmentActivityUpdate):
# """Updates a document."""
# data = scope_equipment_activty_in.model_dump()
# update_data = scope_equipment_activty_in.model_dump(exclude_defaults=True)
# for field in data:
# if field in update_data:
# setattr(activity, field, update_data[field])
# await db_session.commit()
# return activity
async def delete(*, db_session: DbSession, assetnum, scope_job_id):
"""Deletes a document."""
activity = await db_session.get(ScopeEquipmentJob, scope_job_id)
await db_session.delete(activity)
await db_session.commit()
Loading…
Cancel
Save