add requests

feature/reliability_stat
Cizz22 6 months ago
parent 3421ce4dff
commit e6e87b0d9d

@ -9,17 +9,21 @@ from src.calculation_budget_constrains.router import \
router as calculation_budget_constraint
from src.calculation_target_reliability.router import \
router as calculation_target_reliability
from src.calculation_time_constrains.router import \
router as calculation_time_constrains_router
from src.job.router import router as job_router
# from src.calculation_time_constrains.router import \
# router as calculation_time_constrains_router
# from src.job.router import router as job_router
from src.overhaul.router import router as overhaul_router
from src.standard_scope.router import router as standard_scope_router
from src.overhaul_activity.router import router as overhaul_activity_router
from src.overhaul_job.router import router as job_overhaul_router
from src.overhaul_scope.router import router as scope_router
from src.scope_equipment.router import router as scope_equipment_router
from src.scope_equipment_job.router import router as scope_equipment_job_router
from src.overhaul_schedule.router import router as overhaul_schedule_router
from src.overhaul_gantt.router import router as gantt_router
from src.workscope_group.router import router as workscope_group_router
from src.equipment_workscope_group.router import router as equipment_workscope_group_router
# from src.overhaul_job.router import router as job_overhaul_router
# from src.overhaul_scope.router import router as scope_router
# from src.scope_equipment.router import router as scope_equipment_router
# from src.scope_equipment_job.router import router as scope_equipment_job_router
# from src.overhaul_schedule.router import router as overhaul_schedule_router
# from src.overhaul_gantt.router import router as gantt_router
# from src.overhaul_scope.router import router as scope_router
@ -67,15 +71,15 @@ authenticated_api_router.include_router(
overhaul_router, prefix="/overhauls", tags=["overhaul"]
)
authenticated_api_router.include_router(job_router, prefix="/jobs", tags=["job"])
# authenticated_api_router.include_router(job_router, prefix="/jobs", tags=["job"])
# # Overhaul session data
authenticated_api_router.include_router(
scope_router, prefix="/overhaul-session", tags=["overhaul-session"]
)
# # # Overhaul session data
# authenticated_api_router.include_router(
# scope_router, prefix="/overhaul-session", tags=["overhaul-session"]
# )
authenticated_api_router.include_router(
scope_equipment_router, prefix="/scope-equipments", tags=["scope_equipment"]
standard_scope_router, prefix="/scope-equipments", tags=["scope_equipment"]
)
authenticated_api_router.include_router(
@ -83,24 +87,33 @@ authenticated_api_router.include_router(
)
authenticated_api_router.include_router(
scope_equipment_job_router,
prefix="/scope-equipment-jobs",
tags=["scope_equipment", "job"],
workscope_group_router, prefix="/workscopes", tags=["workscope_groups"]
)
authenticated_api_router.include_router(
overhaul_schedule_router,
prefix="/overhaul-schedules",
tags=["overhaul_schedule"],
equipment_workscope_group_router,
prefix="/equipment-workscopes",
tags=["equipment_workscope_groups"],
)
# authenticated_api_router.include_router(
# scope_equipment_job_router,
# prefix="/scope-equipment-jobs",
# tags=["scope_equipment", "job"],
# )
authenticated_api_router.include_router(
job_overhaul_router, prefix="/overhaul-jobs", tags=["job", "overhaul"]
)
# authenticated_api_router.include_router(
# overhaul_schedule_router,
# prefix="/overhaul-schedules",
# tags=["overhaul_schedule"],
# )
authenticated_api_router.include_router(
gantt_router, prefix="/overhaul-gantt", tags=["gantt"]
)
# authenticated_api_router.include_router(
# job_overhaul_router, prefix="/overhaul-jobs", tags=["job", "overhaul"]
# )
# authenticated_api_router.include_router(
# gantt_router, prefix="/overhaul-gantt", tags=["gantt"]
# )
# authenticated_api_router.include_router(
# overhaul_history_router, prefix="/overhaul-history", tags=["overhaul_history"]
@ -125,12 +138,12 @@ 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(

@ -5,8 +5,8 @@ from sqlalchemy import Delete, Select
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.scope_equipment.model import ScopeEquipment
from src.scope_equipment.service import get_by_scope_name
# from src.scope_equipment.model import ScopeEquipment
# from src.scope_equipment.service import get_by_scope_name
from src.overhaul_activity.service import get_all_by_session_id
# async def get_all_budget_constrains(

@ -4,9 +4,9 @@ from sqlalchemy import Delete, Select
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.scope_equipment.model import ScopeEquipment
from src.scope_equipment.service import get_by_scope_name
from src.scope_equipment_job.service import get_equipment_level_by_no
# from src.scope_equipment.model import ScopeEquipment
# from src.scope_equipment.service import get_by_scope_name
# from src.scope_equipment_job.service import get_equipment_level_by_no
from datetime import datetime, timedelta
import random
from typing import List

@ -10,7 +10,7 @@ from sqlalchemy import and_, case, func, select, update
from sqlalchemy.orm import joinedload
from src.database.core import DbSession
from src.overhaul_activity.service import get_all_by_session_id
from src.overhaul_activity.service import get_all as get_all_by_session_id
from src.overhaul_scope.service import get as get_scope, get_prev_oh
from src.utils import get_latest_numOfFail
from src.workorder.model import MasterWorkOrder
@ -264,9 +264,9 @@ class SparePartsService:
return projected_stock
async def reduce_stock(self, db_session, assetnum: str):
async def reduce_stock(self, db_session, location_tag: str):
requirements_query = select(ScopeEquipmentPart).where(
ScopeEquipmentPart.assetnum == assetnum
ScopeEquipmentPart.location_tag == location_tag
)
requirements = await db_session.execute(requirements_query)
@ -293,7 +293,7 @@ class SparePartsService:
all_available = True
requirements_query = select(ScopeEquipmentPart).where(
ScopeEquipmentPart.assetnum == equipment.assetnum
ScopeEquipmentPart.location_tag == equipment.location_tag
)
requirements = await db_session.execute(requirements_query)
@ -504,7 +504,7 @@ class OverhaulCalculator:
)
#reduce sparepart stock
await self.spare_parts_service.reduce_stock(db_session, equipment.assetnum)
await self.spare_parts_service.reduce_stock(db_session, equipment.location_tag)
# Aggregate costs
corrective_costs = [r["corrective_cost"] for r in all_results]
@ -1035,7 +1035,7 @@ async def get_calculation_result(db_session: DbSession, calculation_id: str):
for eq in scope_calculation.equipment_results:
if eq.procurement_details[i]:
result["procurement_details"][eq.assetnum] = {
result["procurement_details"][eq.location_tag] = {
"is_included": eq.is_included,
"details": eq.procurement_details[i],
}
@ -1280,14 +1280,14 @@ async def create_calculation_result_service(
total = []
predicted_num_failures = await get_number_of_failures(
location_tag=eq.equipment.location_tag,
location_tag=eq.location_tag,
start_date=start_date,
end_date=end_date,
token=token
)
foh_value = await get_equipment_foh(
location_tag=eq.equipment.location_tag,
location_tag=eq.location_tag,
token=token
)
@ -1310,7 +1310,7 @@ async def create_calculation_result_service(
service_cost=eq.service_cost,
optimum_day=optimal_result['interval'],
calculation_data_id=calculation.id,
master_equipment=eq.equipment,
master_equipment=eq.master_equipment,
)
)

@ -12,7 +12,7 @@ class ScopeEquipmentPart(Base, DefaultMixin):
required_stock = Column(Float, nullable=False, default=0)
sparepart_id = Column(UUID(as_uuid=True), ForeignKey("oh_ms_sparepart.id"), nullable=False)
assetnum = Column(String, nullable=False)
location_tag = Column(String, nullable=False)
location_tag = Column(String, nullable=False)
part = relationship(

@ -7,8 +7,6 @@ from sqlalchemy.orm import selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from src.scope_equipment.model import MasterEquipment, MasterEquipmentTree
from src.scope_equipment.service import get_equipment_level_by_no
from .model import ScopeEquipmentPart
from .schema import ScopeEquipmentActivityCreate, ScopeEquipmentActivityUpdate

@ -0,0 +1,22 @@
from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
from src.database.core import Base
from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
from src.workorder.model import MasterWorkOrder
class EquipmentWorkscopeGroup(Base, DefaultMixin):
__tablename__ = "oh_tr_equipment_workscope_group"
workscope_group_id = Column(UUID(as_uuid=True), ForeignKey('oh_ms_workscope_group.id'))
location_tag = Column(String, nullable=False)
workscope_group = relationship("MasterActivity", lazy="selectin", back_populates="equipment_workscope_groups")
equipment = relationship(
"StandardScope",
lazy="raise",
primaryjoin="and_(EquipmentWorkscopeGroup.location_tag == foreign(StandardScope.location_tag))",
uselist=False, # Add this if it's a one-to-one relationship
)

@ -12,16 +12,16 @@ from .service import create, delete, get_all
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."""
@router.get(
"/{location_tag}", response_model=StandardResponse[OverhaulJobPagination]
)
async def get_jobs(common: CommonParameters, location_tag: str, scope: Optional[str] = Query(None)):
"""Get all scope pagination."""
# return
data = await get_all(db_session=db_session, assetnum=assetnum, common=common)
results = await get_all(common=common, location_tag=location_tag, scope=scope)
return StandardResponse(
data=data,
data=results,
message="Data retrieved successfully",
)

@ -22,32 +22,51 @@ from .schema import ScopeEquipmentJobCreate
# 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),
selectinload(ScopeEquipmentJob.overhaul_jobs)
.selectinload(OverhaulJob.overhaul_activity)
.selectinload(OverhaulActivity.overhaul_scope),
)
# 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),
# selectinload(ScopeEquipmentJob.overhaul_jobs)
# .selectinload(OverhaulJob.overhaul_activity)
# .selectinload(OverhaulActivity.overhaul_scope),
# )
# )
# results = await search_filter_sort_paginate(model=stmt, **common)
# return results
async def get_all(*, common, location_tag: str, scope: Optional[str] = None):
"""Returns all documents."""
query = (
Select(EquipmentWorkscopeGroup)
.where(EquipmentWorkscopeGroup.location_tag == location_tag)
)
results = await search_filter_sort_paginate(model=stmt, **common)
if scope:
query = (
query
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.join(WorkscopeOHType.oh_type)
.filter(MaintenanceType.name == scope)
)
results = await search_filter_sort_paginate(model=query, **common)
return results

@ -18,26 +18,26 @@ class OverhaulActivity(Base, DefaultMixin):
service_cost = Column(Float, nullable=False, default=0)
status = Column(String, nullable=False, default="pending")
equipment = relationship(
"MasterEquipment",
lazy="raise",
primaryjoin="and_(OverhaulActivity.assetnum == foreign(MasterEquipment.assetnum))",
uselist=False, # Add this if it's a one-to-one relationship
)
# sparepart_equipments = relationship(
# "ScopeEquipmentPart",
# lazy="select", # or "joined", "subquery", "dynamic" depending on your needs
# primaryjoin="OverhaulActivity.assetnum == foreign(ScopeEquipmentPart.assetnum)",
# uselist=True
# )
overhaul_scope = relationship(
"OverhaulScope",
lazy="raise",
)
overhaul_jobs = relationship(
"OverhaulJob", back_populates="overhaul_activity", lazy="raise"
)
# equipment = relationship(
# "MasterEquipment",
# lazy="raise",
# primaryjoin="and_(OverhaulActivity.assetnum == foreign(MasterEquipment.assetnum))",
# uselist=False, # Add this if it's a one-to-one relationship
# )
# # sparepart_equipments = relationship(
# # "ScopeEquipmentPart",
# # lazy="select", # or "joined", "subquery", "dynamic" depending on your needs
# # primaryjoin="OverhaulActivity.assetnum == foreign(ScopeEquipmentPart.assetnum)",
# # uselist=True
# # )
# overhaul_scope = relationship(
# "OverhaulScope",
# lazy="raise",
# )
# overhaul_jobs = relationship(
# "OverhaulJob", back_populates="overhaul_activity", lazy="raise"
# )

@ -15,10 +15,10 @@ router = APIRouter()
@router.get(
"/{overhaul_session}", response_model=StandardResponse[OverhaulActivityPagination]
"/{overhaul_session}", response_model=StandardResponse[List[OverhaulActivityRead]]
)
async def get_scope_equipments(
common: CommonParameters,
db_session: DbSession,
overhaul_session: str,
assetnum: Optional[str] = Query(None),
scope_name: Optional[str] = Query(None),
@ -26,7 +26,7 @@ async def get_scope_equipments(
"""Get all scope activity pagination."""
# return
data = await get_all(
common=common,
db_session=db_session,
assetnum=assetnum,
scope_name=scope_name,
overhaul_session_id=overhaul_session,

@ -5,8 +5,8 @@ from uuid import UUID
from pydantic import Field
from src.models import DefultBase, Pagination
from src.scope_equipment.schema import MasterEquipmentTree
from src.job.schema import ActivityMasterRead
from src.standard_scope.schema import MasterEquipmentTree
from src.workscope_group.schema import ActivityMasterRead
class OverhaulActivityBase(DefultBase):
pass
@ -38,11 +38,12 @@ class OverhaulActivityRead(OverhaulActivityBase):
id: UUID
material_cost: Optional[float] = Field(0)
service_cost: Optional[float] = Field(0)
assetnum: str = Field(..., description="Assetnum is required")
status: str
equipment: MasterEquipmentTree
overhaul_scope: OverhaulScope
overhaul_jobs: Optional[List[OverhaulJob]] = Field([])
location_tag: str
equipment_name: Optional[str]
oh_scope: str
# equipment: MasterEquipmentTree
# overhaul_scope: OverhaulScope
# overhaul_jobs: Optional[List[OverhaulJob]] = Field([])
class OverhaulActivityPagination(Pagination):

@ -13,9 +13,10 @@ from src.database.service import CommonParameters, search_filter_sort_paginate
from src.overhaul_activity.utils import get_material_cost, get_service_cost
from src.overhaul_scope.model import OverhaulScope
from src.overhaul_scope.service import get as get_session
from src.scope_equipment.model import MasterEquipment
from src.job.model import MasterActivity
from src.scope_equipment_job.model import ScopeEquipmentJob
from src.standard_scope.model import MasterEquipment
from src.standard_scope.service import get_by_oh_session_id
from src.workscope_group.model import MasterActivity
from src.equipment_workscope_group.model import EquipmentWorkscopeGroup
from src.overhaul_job.model import OverhaulJob
from .model import OverhaulActivity
@ -43,32 +44,50 @@ async def get(
async def get_all(
*,
common: CommonParameters,
db_session: DbSession,
overhaul_session_id: UUID,
assetnum: Optional[str] = None,
scope_name: Optional[str] = None
):
query = (
Select(OverhaulActivity)
.where(OverhaulActivity.overhaul_scope_id == overhaul_session_id)
.options(joinedload(OverhaulActivity.equipment).options(joinedload(MasterEquipment.parent).options(joinedload(MasterEquipment.parent))))
.options(selectinload(OverhaulActivity.overhaul_scope))
.options(selectinload(OverhaulActivity.overhaul_jobs).options(joinedload(OverhaulJob.scope_equipment_job).options(joinedload(ScopeEquipmentJob.job))))
# query = (
# Select(OverhaulActivity)
# .where(OverhaulActivity.overhaul_scope_id == overhaul_session_id)
# .options(joinedload(OverhaulActivity.equipment).options(joinedload(MasterEquipment.parent).options(joinedload(MasterEquipment.parent))))
# .options(selectinload(OverhaulActivity.overhaul_scope))
# .options(selectinload(OverhaulActivity.overhaul_jobs).options(joinedload(OverhaulJob.scope_equipment_job).options(joinedload(ScopeEquipmentJob.job))))
# )
# if assetnum:
# query = query.filter(OverhaulActivity.assetnum == assetnum).options(
# joinedload(OverhaulActivity.overhaul_scope)
# )
# if scope_name:
# query = query.filter(OverhaulActivity.scope_name == scope_name).options(
# joinedload(OverhaulActivity.overhaul_scope)
# )
# results = await search_filter_sort_paginate(model=query, **common)
##raise Exception(results['items'][0].equipment.parent.__dict__)
equipments, overhaul = await get_by_oh_session_id(
db_session=db_session, oh_session_id=overhaul_session_id
)
if assetnum:
query = query.filter(OverhaulActivity.assetnum == assetnum).options(
joinedload(OverhaulActivity.overhaul_scope)
)
results = []
if scope_name:
query = query.filter(OverhaulActivity.scope_name == scope_name).options(
joinedload(OverhaulActivity.overhaul_scope)
for equipment in equipments:
res = OverhaulActivityRead(
id=equipment.id,
material_cost=35000000000,
service_cost=200000000,
location_tag=equipment.location_tag,
equipment_name=equipment.master_equipment.name if equipment.master_equipment else None,
oh_scope=overhaul.maintenance_type.name,
)
results = await search_filter_sort_paginate(model=query, **common)
##raise Exception(results['items'][0].equipment.parent.__dict__)
results.append(res)
return results

@ -6,24 +6,38 @@ from src.database.core import Base
from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
class OverhaulJob(Base, DefaultMixin):
__tablename__ = "oh_tr_overhaul_job"
overhaul_activity_id = Column(
UUID(as_uuid=True), ForeignKey("oh_tr_overhaul_activity.id"), nullable=False
class EquipmentWorkscopeGroup(Base, DefaultMixin):
__tablename__ = "oh_tr_equipment_workscope_group"
# overhaul_activity_id = Column(
# UUID(as_uuid=True), ForeignKey("oh_tr_overhaul_activity.id"), nullable=False
# )
# scope_equipment_job_id = Column(
# UUID(as_uuid=True),
# ForeignKey("oh_ms_scope_equipment_job.id", ondelete="cascade"),
# nullable=False,
# )
# notes = Column(String, nullable=True)
# status = Column(String, nullable=True, default="pending")
workscope_group_id = Column(
UUID(as_uuid=True), ForeignKey("oh_ms_workscope_group.id"), nullable=False
)
scope_equipment_job_id = Column(
UUID(as_uuid=True),
ForeignKey("oh_ms_scope_equipment_job.id", ondelete="cascade"),
nullable=False,
location_tag = Column(String, nullable=False)
equipment = relationship(
"StandardScope",
lazy="selectin",
primaryjoin="and_(OverhaulJob.location_tag == foreign(StandardScope.location_tag))",
uselist=False, # Add this if it's a one-to-one relationship
)
notes = Column(String, nullable=True)
status = Column(String, nullable=True, default="pending")
workscope_group = relationship("MasterActivity", lazy="selectin", back_populates="equipment_workscope_groups")
scope_equipment_job = relationship(
"ScopeEquipmentJob", lazy="raise", back_populates="overhaul_jobs"
)
# scope_equipment_job = relationship(
# "ScopeEquipmentJob", lazy="raise", back_populates="overhaul_jobs"
# )
overhaul_activity = relationship("OverhaulActivity", lazy="raise", back_populates="overhaul_jobs")
# overhaul_activity = relationship("OverhaulActivity", lazy="raise", back_populates="overhaul_jobs")

@ -1,6 +1,6 @@
from typing import List, Optional
from fastapi import APIRouter, HTTPException, status
from fastapi import APIRouter, HTTPException, status, Query
from src.auth.service import CurrentUser
from src.database.core import DbSession
@ -15,12 +15,12 @@ router = APIRouter()
@router.get(
"/{overhaul_equipment_id}", response_model=StandardResponse[OverhaulJobPagination]
"/{location_tag}", response_model=StandardResponse[OverhaulJobPagination]
)
async def get_jobs(common: CommonParameters, overhaul_equipment_id: str):
async def get_jobs(common: CommonParameters, location_tag: str, scope: Optional[str] = Query(None)):
"""Get all scope pagination."""
# return
results = await get_all(common=common, overhaul_equipment_id=overhaul_equipment_id)
results = await get_all(common=common, location_tag=location_tag, scope=scope)
return StandardResponse(
data=results,

@ -7,26 +7,32 @@ from sqlalchemy.orm import selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import search_filter_sort_paginate
from src.scope_equipment_job.model import ScopeEquipmentJob
from src.overhaul_activity.model import OverhaulActivity
# from src.scope_equipment_job.model import ScopeEquipmentJob
# from src.overhaul_activity.model import OverhaulActivity
from .model import OverhaulJob
from src.workscope_group.model import MasterActivity
from src.workscope_group_maintenance_type.model import WorkscopeOHType
from src.overhaul_scope.model import MaintenanceType
from .model import EquipmentWorkscopeGroup
from .schema import OverhaulJobCreate
async def get_all(*, common, overhaul_equipment_id: str):
async def get_all(*, common, location_tag: str, scope: Optional[str] = None):
"""Returns all documents."""
query = (
Select(OverhaulJob)
.where(OverhaulJob.overhaul_activity_id == overhaul_equipment_id)
.options(
selectinload(OverhaulJob.scope_equipment_job).options(
selectinload(ScopeEquipmentJob.job)),
selectinload(OverhaulJob.overhaul_activity).options(
selectinload(OverhaulActivity.overhaul_scope)),
)
Select(EquipmentWorkscopeGroup)
.where(EquipmentWorkscopeGroup.location_tag == location_tag)
)
if scope:
query = (
query
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.join(WorkscopeOHType.oh_type)
.filter(MaintenanceType.name == scope)
)
results = await search_filter_sort_paginate(model=query, **common)
return results

@ -1,4 +1,4 @@
from sqlalchemy import Column, DateTime, Float, Integer, String
from sqlalchemy import Column, DateTime, Float, Integer, String, ForeignKey, UUID
from sqlalchemy.orm import relationship
from src.database.core import Base
@ -6,12 +6,20 @@ from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
class OverhaulScope(Base, DefaultMixin):
__tablename__ = "oh_ms_overhaul_scope"
type = Column(String, nullable=False) # Changed to non-nullable to match the model
__tablename__ = "oh_ms_overhaul"
start_date = Column(DateTime(timezone=True), nullable=False) # Made non-nullable to match model
end_date = Column(DateTime(timezone=True), nullable=True) # Already nullable
duration_oh = Column(Integer, nullable=True)
crew_number = Column(Integer, nullable=True, default=1)
status = Column(String, nullable=False, default="Upcoming")
maintenance_type_id = Column(
UUID(as_uuid=True), ForeignKey("oh_ms_maintenance_type.id"), nullable=False)
activity_equipments = relationship("OverhaulActivity", lazy="selectin")
maintenance_type = relationship("MaintenanceType", lazy="selectin", backref="overhaul_scopes")
# activity_equipments = relationship("OverhaulActivity", lazy="selectin")
class MaintenanceType(Base, DefaultMixin):
__tablename__ = "oh_ms_maintenance_type"
code = Column(String, nullable=False, default="OH")
name = Column(String, nullable=False)

@ -11,9 +11,11 @@ class ScopeBase(DefultBase):
duration_oh: Optional[int] = Field(720, title="Duration OH")
crew_number: Optional[int] = Field(10, title="Crew")
status: Optional[str] = Field("Upcoming")
type: str = Field(..., title="Type") # Added title
class MaintenanceType(DefultBase):
name: str
class ScopeCreate(ScopeBase):
start_date: datetime
end_date: Optional[datetime] = Field(None)
@ -27,6 +29,7 @@ class ScopeRead(ScopeBase):
id: UUID
start_date: datetime
end_date: Optional[datetime]
maintenance_type: MaintenanceType
class ScopePagination(Pagination):

@ -1,15 +1,19 @@
from typing import Optional
from sqlalchemy import Delete, Select, func
from sqlalchemy.orm import selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import search_filter_sort_paginate
from src.overhaul_activity.model import OverhaulActivity
from src.scope_equipment.service import get_by_scope_name
from src.utils import time_now
from src.standard_scope.model import StandardScope, EquipmentOHHistory
from src.workscope_group.model import MasterActivity
from src.workscope_group_maintenance_type.model import WorkscopeOHType
from src.equipment_workscope_group.model import EquipmentWorkscopeGroup
from .model import OverhaulScope
from .model import OverhaulScope, MaintenanceType
from .schema import ScopeCreate, ScopeUpdate
from .utils import get_material_cost, get_service_cost
from datetime import datetime
@ -18,7 +22,7 @@ async def get(
*, db_session: DbSession, overhaul_session_id: str
) -> Optional[OverhaulScope]:
"""Returns a document based on the given document id."""
query = Select(OverhaulScope).filter(OverhaulScope.id == overhaul_session_id)
query = Select(OverhaulScope).filter(OverhaulScope.id == overhaul_session_id).options(selectinload(OverhaulScope.maintenance_type))
result = await db_session.execute(query)
return result.scalars().one_or_none()
@ -34,7 +38,7 @@ async def get_all(*, common, scope_name: Optional[str] = None):
query = Select(OverhaulScope)
if scope_name:
query = query.filter(OverhaulScope.type == scope_name)
query = query.filter(OverhaulScope.maintenance_type.name == scope_name)
results = await search_filter_sort_paginate(model=query, **common)
return results
@ -66,12 +70,21 @@ async def create(*, db_session: DbSession, scope_in: ScopeCreate):
if start_date and end_date:
duration_days = (end_date - start_date).days
maintenance_type = Select(MaintenanceType).where(MaintenanceType.name == scope_in.type)
maintenance_type = await db_session.execute(maintenance_type)
maintenance_type = maintenance_type.scalars().one_or_none()
if maintenance_type is None:
maintenance_type = MaintenanceType(name=scope_in.type)
db_session.add(maintenance_type)
await db_session.flush()
# Create the OverhaulScope object with all hardcoded values
overhaul_session = OverhaulScope(
start_date=scope_in.start_date,
end_date=scope_in.end_date,
type=scope_in.type, # Hardcoded type
duration_oh=duration_days, # Hardcoded duration (30 days)
maintenance_type=maintenance_type,
duration_oh=duration_days,
crew_number=scope_in.crew_number, # Hardcoded crew number
status=scope_in.status # Hardcoded status
)
@ -138,68 +151,117 @@ async def get_overview_overhaul(*, db_session: DbSession):
current_date = time_now().date()
# For ongoing overhaul with count
# 1. Check for ongoing overhaul
ongoing_query = (
Select(OverhaulScope, func.count(OverhaulActivity.id).label("equipment_count"))
.outerjoin(OverhaulScope.activity_equipments)
Select(OverhaulScope)
.where(
OverhaulScope.start_date <= current_date,
OverhaulScope.end_date >= current_date,
)
.group_by(OverhaulScope.id)
)
ongoing_result = await db_session.execute(ongoing_query)
# Use first() instead of scalar_one_or_none()
ongoing_result = ongoing_result.first()
if ongoing_result:
ongoing_overhaul, equipment_count = ongoing_result # Unpack the result tuple
return {
"status": "Ongoing",
"overhaul": {
"id": ongoing_overhaul.id,
"type": ongoing_overhaul.type,
"start_date": ongoing_overhaul.start_date,
"end_date": ongoing_overhaul.end_date,
"duration_oh": ongoing_overhaul.duration_oh,
"crew_number": ongoing_overhaul.crew_number,
"remaining_days": (ongoing_overhaul.end_date - current_date).days,
"equipment_count": equipment_count,
},
}
# For upcoming overhaul with count
upcoming_query = (
Select(OverhaulScope, func.count(OverhaulActivity.id).label("equipment_count"))
.outerjoin(OverhaulScope.activity_equipments)
.where(
OverhaulScope.start_date > current_date,
ongoing_result = await db_session.execute(ongoing_query.options(selectinload(OverhaulScope.maintenance_type)))
ongoing_overhaul = ongoing_result.first()
# 2. If no ongoing overhaul, get the closest scheduled overhaul
if ongoing_overhaul is None:
# Get the closest future overhaul (next scheduled)
next_overhaul_query = (
Select(OverhaulScope)
.where(OverhaulScope.start_date > current_date)
.order_by(OverhaulScope.start_date.asc())
.limit(1)
)
.group_by(OverhaulScope.id)
.order_by(OverhaulScope.start_date)
next_result = await db_session.execute(next_overhaul_query.options(selectinload(OverhaulScope.maintenance_type)))
next_overhaul = next_result.scalar_one_or_none()
if next_overhaul:
print(f"Next scheduled overhaul starts on: {next_overhaul.start_date}")
selected_overhaul = next_overhaul
else:
print("No upcoming overhauls scheduled")
selected_overhaul = None
else:
print(f"Ongoing overhaul found: {ongoing_overhaul.start_date} to {ongoing_overhaul.end_date}")
selected_overhaul = ongoing_overhaul
equipments = (
Select(StandardScope)
.outerjoin(StandardScope.oh_history) # Use outerjoin to handle None values
.join(StandardScope.workscope_groups)
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.filter(WorkscopeOHType.maintenance_type_id == selected_overhaul.maintenance_type_id)
.filter(
(StandardScope.is_alternating_oh == False) |
(StandardScope.oh_history == None) |
(StandardScope.oh_history.has(EquipmentOHHistory.last_oh_type != selected_overhaul.maintenance_type.name))
).distinct()
)
upcoming_result = await db_session.execute(upcoming_query)
upcoming_result = upcoming_result.first()
if upcoming_result:
upcoming_overhaul, equipment_count = upcoming_result # Unpack the result tuple
days_until = (upcoming_overhaul.start_date - current_date).days
return {
"status": "Upcoming",
"overhaul": {
"id": upcoming_overhaul.id,
"type": upcoming_overhaul.type,
"start_date": upcoming_overhaul.start_date,
"end_date": upcoming_overhaul.end_date,
"duration_oh": upcoming_overhaul.duration_oh,
"crew_number": upcoming_overhaul.crew_number,
"remaining_days": days_until,
"equipment_count": equipment_count,
},
}
return {"status": "no_overhaul", "overhaul": None}
results = await db_session.execute(equipments)
return {
"status": selected_overhaul.status,
"overhaul": {
"id": selected_overhaul.id,
"type": selected_overhaul.maintenance_type.name,
"start_date": selected_overhaul.start_date,
"end_date": selected_overhaul.end_date,
"duration_oh": selected_overhaul.duration_oh,
"crew_number": selected_overhaul.crew_number,
"remaining_days": (selected_overhaul.end_date - current_date).days,
"equipment_count": len(results.scalars().all()),
},
}
# if ongoing_result:
# ongoing_overhaul, equipment_count = ongoing_result # Unpack the result tuple
# return {
# "status": "Ongoing",
# "overhaul": {
# "id": ongoing_overhaul.id,
# "type": ongoing_overhaul.maintenance_type.name,
# "start_date": ongoing_overhaul.start_date,
# "end_date": ongoing_overhaul.end_date,
# "duration_oh": ongoing_overhaul.duration_oh,
# "crew_number": ongoing_overhaul.crew_number,
# "remaining_days": (ongoing_overhaul.end_date - current_date).days,
# "equipment_count": equipment_count,
# },
# }
# # For upcoming overhaul with count
# upcoming_query = (
# Select(OverhaulScope, func.count(OverhaulActivity.id).label("equipment_count"))
# .outerjoin(OverhaulScope.activity_equipments)
# .where(
# OverhaulScope.start_date > current_date,
# )
# .group_by(OverhaulScope.id)
# .order_by(OverhaulScope.start_date)
# )
# upcoming_result = await db_session.execute(upcoming_query)
# upcoming_result = upcoming_result.first()
# if upcoming_result:
# upcoming_overhaul, equipment_count = upcoming_result # Unpack the result tuple
# days_until = (upcoming_overhaul.start_date - current_date).days
# return {
# "status": "Upcoming",
# "overhaul": {
# "id": upcoming_overhaul.id,
# "type": upcoming_overhaul.type,
# "start_date": upcoming_overhaul.start_date,
# "end_date": upcoming_overhaul.end_date,
# "duration_oh": upcoming_overhaul.duration_oh,
# "crew_number": upcoming_overhaul.crew_number,
# "remaining_days": days_until,
# "equipment_count": equipment_count,
# },
# }
# return {"status": "no_overhaul", "overhaul": None}

@ -1,202 +0,0 @@
from datetime import datetime, timedelta
from typing import Optional, Union
from fastapi import HTTPException, status
from sqlalchemy import Delete, Select, and_, desc, func, not_, or_
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.orm import selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from src.overhaul_scope.model import OverhaulScope
from src.scope_equipment.enum import ScopeEquipmentType
from src.workorder.model import MasterWorkOrder
from .model import MasterEquipment, MasterEquipmentTree, ScopeEquipment
from .schema import ScopeEquipmentCreate, ScopeEquipmentUpdate
async def get_by_assetnum(*, db_session: DbSession, assetnum: str):
query = (
Select(ScopeEquipment)
.filter(ScopeEquipment.assetnum == assetnum)
.options(selectinload(ScopeEquipment.master_equipment))
)
result = await db_session.execute(query)
return result.unique().scalars().one_or_none()
async def get_all(*, common, scope_name: str = None):
"""Returns all documents."""
query = Select(ScopeEquipment).options(
selectinload(ScopeEquipment.master_equipment)
)
query = query.order_by(desc(ScopeEquipment.created_at))
if scope_name:
query = query.where(ScopeEquipment.scope_overhaul == scope_name)
results = await search_filter_sort_paginate(model=query, **common)
return results
async def create(*, db_session: DbSession, scope_equipment_in: ScopeEquipmentCreate):
"""Creates a new document."""
# scope_equipment = ScopeEquipment(**scope_equipment_in.model_dump())
assetnums = scope_equipment_in.assetnums
results = []
removal_date = scope_equipment_in.removal_date
if scope_equipment_in.type == ScopeEquipmentType.TEMP:
# Search for the next or ongoing overhaul session for the given scope
stmt = (
Select(OverhaulScope.end_date)
.where(
OverhaulScope.type == scope_equipment_in.scope_name,
(OverhaulScope.start_date <= datetime.now())
& (OverhaulScope.end_date >= datetime.now()) # Ongoing
| (OverhaulScope.start_date > datetime.now()), # Upcoming
)
.order_by(OverhaulScope.start_date.asc())
.limit(1)
)
result = await db_session.execute(stmt)
removal_date = result.scalar_one_or_none()
# If no overhaul found, set a default removal date or handle the error
if removal_date is None:
# Handle if no overhaul session is found, set default or raise an error
removal_date = datetime.now() + timedelta(
days=30
) # Example: 30 days from now
for assetnum in assetnums:
stmt = insert(ScopeEquipment).values(
assetnum=assetnum,
scope_overhaul=scope_equipment_in.scope_name,
type=scope_equipment_in.type,
removal_date=removal_date,
)
stmt = stmt.on_conflict_do_nothing(
index_elements=["assetnum", "scope_overhaul"]
)
await db_session.execute(stmt)
results.append(assetnum)
await db_session.commit()
return results
async def update(
*,
db_session: DbSession,
scope_equipment: ScopeEquipment,
scope_equipment_in: ScopeEquipmentUpdate
):
"""Updates a document."""
data = scope_equipment_in.model_dump()
update_data = scope_equipment_in.model_dump(exclude_defaults=True)
for field in data:
if field in update_data:
setattr(scope_equipment, field, update_data[field])
await db_session.commit()
return scope_equipment
async def delete(*, db_session: DbSession, assetnum: str):
"""Deletes a document."""
query = Delete(ScopeEquipment).where(ScopeEquipment.assetnum == assetnum)
await db_session.execute(query)
await db_session.commit()
return assetnum
# query = Select(ScopeEquipment).filter(
# ScopeEquipment.id == scope_equipment_id)
# scope_equipment = await db_session.execute(query)
# scope_equipment: ScopeEquipment = scope_equipment.scalars().one_or_none()
# if not scope_equipment:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
# detail="A data with this id does not exist.",
# )
# if not scope_equipment.scope_id:
# await db_session.delete(scope_equipment)
# else:
# if scope_equipment.current_scope_id == scope_equipment.scope_id:
# await db_session.delete(scope_equipment)
# else:
# scope_equipment.current_scope_id = scope_equipment.scope_id
# await db_session.commit()
async def get_by_scope_name(
*, db_session: DbSession, scope_name: Optional[str]
) -> Optional[ScopeEquipment]:
"""Returns a document based on the given document id."""
query = Select(ScopeEquipment).options(
selectinload(ScopeEquipment.master_equipment)
)
if scope_name:
query = query.filter(ScopeEquipment.scope_overhaul == scope_name)
result = await db_session.execute(query)
return result.scalars().all()
# async def get_exculed_scope_name(*, db_session: DbSession, scope_name: Union[str, list]) -> Optional[ScopeEquipment]:
# scope = await get_scope_by_name_service(db_session=db_session, scope_name=scope_name)
# query = Select(ScopeEquipment)
# if scope:
# query = query.filter(ScopeEquipment.current_scope_id != scope.id)
# else:
# query = query.filter(ScopeEquipment.current_scope_id != None)
# result = await db_session.execute(query)
# return result.scalars().all()
async def get_all_master_equipment(*, common: CommonParameters, scope_name):
equipments_scope = [
equip.assetnum
for equip in await get_by_scope_name(
db_session=common.get("db_session"), scope_name=scope_name
)
]
query = Select(MasterEquipment).filter(MasterEquipment.assetnum.is_not(None))
# Only add not_in filter if there are items in equipments_scope
if equipments_scope:
query = query.filter(MasterEquipment.assetnum.not_in(equipments_scope))
results = await search_filter_sort_paginate(model=query, **common)
return results
async def get_equipment_level_by_no(*, db_session: DbSession, level: int):
query = (
Select(MasterEquipment)
.join(MasterEquipment.equipment_tree)
.where(MasterEquipmentTree.level_no == level)
)
result = await db_session.execute(query)
return result.scalars().all()

@ -1,20 +0,0 @@
from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
from src.database.core import Base
from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
from src.workorder.model import MasterWorkOrder
class ScopeEquipmentJob(Base, DefaultMixin):
__tablename__ = "oh_ms_scope_equipment_job"
assetnum = Column(String, nullable=False)
job_id = Column(UUID(as_uuid=True), ForeignKey("oh_ms_job.id", ondelete="cascade"))
job = relationship("MasterActivity", lazy="selectin")
overhaul_jobs = relationship(
"OverhaulJob", back_populates="scope_equipment_job", lazy="selectin"
)

@ -1,4 +1,4 @@
from sqlalchemy import UUID, Column, Date, Float, ForeignKey, Integer, String
from sqlalchemy import UUID, Column, Date, Float, ForeignKey, Integer, String, Boolean
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
@ -7,22 +7,40 @@ from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
from src.workorder.model import MasterWorkOrder
class ScopeEquipment(Base, DefaultMixin):
__tablename__ = "oh_ms_scope_equipment"
class StandardScope(Base, DefaultMixin):
__tablename__ = "oh_ms_standard_scope"
assetnum = Column(String, nullable=True)
scope_overhaul = Column(String, nullable=False)
type = Column(String, nullable=False, default="Permanent")
removal_date = Column(Date, nullable=True)
location_tag = Column(String, nullable=False)
is_alternating_oh = Column(Boolean, nullable=False, default=False)
assigned_date = Column(Date, nullable=True)
master_equipment = relationship(
"MasterEquipment",
lazy="raise",
primaryjoin="and_(ScopeEquipment.assetnum == foreign(MasterEquipment.assetnum))",
lazy="selectin",
primaryjoin="and_(StandardScope.location_tag == foreign(MasterEquipment.location_tag))",
uselist=False, # Add this if it's a one-to-one relationship
)
oh_history = relationship(
"EquipmentOHHistory",
lazy="selectin",
primaryjoin="and_(StandardScope.location_tag == foreign(EquipmentOHHistory.location_tag))",
uselist=False, # Add this if it's a one-to-one relationship
)
workscope_groups = relationship(
"EquipmentWorkscopeGroup",
lazy="selectin",
primaryjoin="and_(EquipmentWorkscopeGroup.location_tag == foreign(StandardScope.location_tag))",
uselist=True, # Add this if it's a one-to-one relationship
)
class EquipmentOHHistory(Base, DefaultMixin):
__tablename__ = "oh_ms_equipment_oh_history"
location_tag = Column(String, nullable=False)
last_oh_date = Column(Date, nullable=True)
last_oh_type = Column(String, nullable=True)
class MasterEquipment(Base, DefaultMixin):
__tablename__ = "ms_equipment_master"

@ -8,12 +8,10 @@ from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from src.models import StandardResponse
from .model import ScopeEquipment
from .schema import (MasterEquipmentPagination, ScopeEquipmentCreate,
ScopeEquipmentPagination, ScopeEquipmentRead,
ScopeEquipmentUpdate)
from .service import (create, delete, get_all, get_all_master_equipment,
get_by_assetnum, update)
from .service import (create, delete, get_all, get_all_master_equipment, update)
router = APIRouter()
@ -22,7 +20,7 @@ router = APIRouter()
async def get_scope_equipments(common: CommonParameters, scope_name: str = Query(None)):
"""Get all scope pagination."""
# return
data = await get_all(common=common, scope_name=scope_name)
data = await get_all(common=common, oh_scope=scope_name)
return StandardResponse(
data=data,
@ -49,38 +47,38 @@ async def create_scope_equipment(
return StandardResponse(data=scope, message="Data created successfully")
@router.put("/{assetnum}", response_model=StandardResponse[ScopeEquipmentRead])
async def update_scope_equipment(
db_session: DbSession, assetnum: str, scope__equipment_in: ScopeEquipmentUpdate
):
scope_equipment = await get_by_assetnum(db_session=db_session, assetnum=assetnum)
# @router.put("/{assetnum}", response_model=StandardResponse[ScopeEquipmentRead])
# async def update_scope_equipment(
# db_session: DbSession, assetnum: str, scope__equipment_in: ScopeEquipmentUpdate
# ):
# scope_equipment = await get_by_assetnum(db_session=db_session, assetnum=assetnum)
if not scope_equipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="A data with this id does not exist.",
)
# if not scope_equipment:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
# detail="A data with this id does not exist.",
# )
return StandardResponse(
data=await update(
db_session=db_session,
scope_equipment=scope_equipment,
scope__equipment_in=scope__equipment_in,
),
message="Data updated successfully",
)
# return StandardResponse(
# data=await update(
# db_session=db_session,
# scope_equipment=scope_equipment,
# scope__equipment_in=scope__equipment_in,
# ),
# message="Data updated successfully",
# )
@router.delete("/{assetnum}", response_model=StandardResponse[None])
async def delete_scope_equipment(db_session: DbSession, assetnum: str):
scope_equipment = await get_by_assetnum(db_session=db_session, assetnum=assetnum)
# @router.delete("/{assetnum}", response_model=StandardResponse[None])
# async def delete_scope_equipment(db_session: DbSession, assetnum: str):
# scope_equipment = await get_by_assetnum(db_session=db_session, assetnum=assetnum)
if not scope_equipment:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=[{"msg": "A data with this id does not exist."}],
)
# if not scope_equipment:
# raise HTTPException(
# status_code=status.HTTP_404_NOT_FOUND,
# detail=[{"msg": "A data with this id does not exist."}],
# )
await delete(db_session=db_session, assetnum=assetnum)
# await delete(db_session=db_session, assetnum=assetnum)
return StandardResponse(message="Data deleted successfully", data=None)
# return StandardResponse(message="Data deleted successfully", data=None)

@ -32,7 +32,7 @@ class ScopeEquipmentUpdate(ScopeEquipmentBase):
class ScopeEquipmentRead(ScopeEquipmentBase):
id: UUID
assetnum: str
location_tag: str
assigned_date: datetime
master_equipment: Optional[MasterEquipmentBase] = Field(None)
@ -40,9 +40,6 @@ class ScopeEquipmentRead(ScopeEquipmentBase):
class ScopeEquipmentPagination(Pagination):
items: List[ScopeEquipmentRead] = []
class MasterEquipmentRead(DefultBase):
assetnum: Optional[str] = Field(None, title="Asset Number")
location_tag: Optional[str] = Field(None, title="Location Tag")

@ -0,0 +1,212 @@
from datetime import datetime, timedelta
from typing import Optional, Union
from fastapi import HTTPException, status
from sqlalchemy import Delete, Select, and_, desc, func, not_, or_
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.orm import selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from src.overhaul_scope.model import OverhaulScope
from src.standard_scope.enum import ScopeEquipmentType
from src.standard_scope.model import EquipmentOHHistory
from src.workorder.model import MasterWorkOrder
from src.equipment_workscope_group.model import EquipmentWorkscopeGroup
from src.workscope_group.model import MasterActivity
from src.workscope_group_maintenance_type.model import WorkscopeOHType
from src.overhaul_scope.model import MaintenanceType
from src.overhaul_scope.service import get as get_overhaul
from .model import MasterEquipment, MasterEquipmentTree, StandardScope
from .schema import ScopeEquipmentCreate, ScopeEquipmentUpdate
from uuid import UUID
async def get_by_location_tag(*, db_session: DbSession, location_tag: str):
query = (
Select(StandardScope)
.filter(StandardScope.location_tag == location_tag)
.options(selectinload(StandardScope.master_equipment))
)
result = await db_session.execute(query)
return result.unique().scalars().one_or_none()
async def get_all(*, common, oh_scope: Optional[str] = None):
"""Returns all documents."""
query = Select(StandardScope).options(
selectinload(StandardScope.master_equipment)
)
query = query.order_by(desc(StandardScope.created_at)).options(selectinload(StandardScope.master_equipment))
if oh_scope:
query = (
query
.outerjoin(StandardScope.oh_history) # Use outerjoin to handle None values
.join(StandardScope.workscope_groups)
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.join(WorkscopeOHType.oh_type)
.filter(MaintenanceType.name == oh_scope)
# .filter(
# (StandardScope.is_alternating_oh == False) |
# (StandardScope.oh_history == None) |
# (StandardScope.oh_history.has(EquipmentOHHistory.last_oh_type != selected_overhaul.maintenance_type.name))
# ).distinct()
)
results = await search_filter_sort_paginate(model=query, **common)
return results
async def get_by_oh_session_id(*, db_session: DbSession, oh_session_id: UUID):
overhaul = await get_overhaul(db_session=db_session, overhaul_session_id=oh_session_id)
query = (
Select(StandardScope)
.outerjoin(StandardScope.oh_history) # Use outerjoin to handle None values
.join(StandardScope.workscope_groups)
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.join(WorkscopeOHType.oh_type)
.filter(MaintenanceType.name == overhaul.maintenance_type.name).filter(
(StandardScope.is_alternating_oh == False) |
(StandardScope.oh_history == None) |
(StandardScope.oh_history.has(EquipmentOHHistory.last_oh_type != overhaul.maintenance_type.name))
).distinct()
)
result = await db_session.execute(query)
return result.scalars().all(), overhaul
async def create(*, db_session: DbSession, scope_equipment_in: ScopeEquipmentCreate):
"""Creates a new document."""
# scope_equipment = StandardScope(**scope_equipment_in.model_dump())
assetnums = scope_equipment_in.assetnums
results = []
removal_date = scope_equipment_in.removal_date
if scope_equipment_in.type == ScopeEquipmentType.TEMP:
# Search for the next or ongoing overhaul session for the given scope
stmt = (
Select(OverhaulScope.end_date)
.where(
OverhaulScope.type == scope_equipment_in.scope_name,
(OverhaulScope.start_date <= datetime.now())
& (OverhaulScope.end_date >= datetime.now()) # Ongoing
| (OverhaulScope.start_date > datetime.now()), # Upcoming
)
.order_by(OverhaulScope.start_date.asc())
.limit(1)
)
result = await db_session.execute(stmt)
removal_date = result.scalar_one_or_none()
# If no overhaul found, set a default removal date or handle the error
if removal_date is None:
# Handle if no overhaul session is found, set default or raise an error
removal_date = datetime.now() + timedelta(
days=30
) # Example: 30 days from now
for assetnum in assetnums:
stmt = insert(StandardScope).values(
assetnum=assetnum,
scope_overhaul=scope_equipment_in.scope_name,
type=scope_equipment_in.type,
removal_date=removal_date,
)
stmt = stmt.on_conflict_do_nothing(
index_elements=["assetnum", "scope_overhaul"]
)
await db_session.execute(stmt)
results.append(assetnum)
await db_session.commit()
return results
async def update(
*,
db_session: DbSession,
scope_equipment: StandardScope,
scope_equipment_in: ScopeEquipmentUpdate
):
"""Updates a document."""
data = scope_equipment_in.model_dump()
update_data = scope_equipment_in.model_dump(exclude_defaults=True)
for field in data:
if field in update_data:
setattr(scope_equipment, field, update_data[field])
await db_session.commit()
return scope_equipment
async def delete(*, db_session: DbSession, assetnum: str):
"""Deletes a document."""
query = Delete(StandardScope).where(StandardScope.assetnum == assetnum)
await db_session.execute(query)
await db_session.commit()
return assetnum
async def get_by_oh_scope(
*, db_session: DbSession, oh_scope: str
):
pass
query = (Select(StandardScope)
.outerjoin(StandardScope.oh_history) # Use outerjoin to handle None values
.join(StandardScope.workscope_groups)
.join(EquipmentWorkscopeGroup.workscope_group)
.join(MasterActivity.oh_types)
.join(WorkscopeOHType.oh_type)
.filter(MaintenanceType.name == oh_scope)
# .filter(
# (StandardScope.is_alternating_oh == False) |
# (StandardScope.oh_history == None) |
# (StandardScope.oh_history.has(EquipmentOHHistory.last_oh_type != selected_overhaul.maintenance_type.name))
# ).distinct()
)
results = await db_session.execute(query)
return results.scalars().all()
async def get_all_master_equipment(*, common: CommonParameters, scope_name):
equipments_scope = [
equip.location_tag
for equip in await get_by_oh_scope(
db_session=common.get("db_session"), oh_scope=scope_name
)
]
query = Select(MasterEquipment).filter(MasterEquipment.location_tag.is_not(None))
# Only add not_in filter if there are items in equipments_scope
if equipments_scope:
query = query.filter(MasterEquipment.location_tag.not_in(equipments_scope))
results = await search_filter_sort_paginate(model=query, **common)
return results
async def get_equipment_level_by_no(*, db_session: DbSession, level: int):
query = (
Select(MasterEquipment)
.join(MasterEquipment.equipment_tree)
.where(MasterEquipmentTree.level_no == level)
)
result = await db_session.execute(query)
return result.scalars().all()

@ -13,8 +13,8 @@ class MasterWorkOrder(Base, DefaultMixin):
workgroup = Column(String, nullable=True)
total_cost_max = Column(Float, nullable=True)
scope_equipments = relationship(
"ScopeEquipment",
lazy="raise",
primaryjoin="and_(MasterWorkOrder.assetnum == foreign(ScopeEquipment.assetnum))",
)
# scope_equipments = relationship(
# "ScopeEquipment",
# lazy="raise",
# primaryjoin="and_(MasterWorkOrder.assetnum == foreign(ScopeEquipment.assetnum))",
# )

@ -8,19 +8,20 @@ from src.workorder.model import MasterWorkOrder
class MasterActivitytask(Base, DefaultMixin):
__tablename__ = "oh_ms_job_task"
__tablename__ = "oh_ms_workscope_task"
description = Column(String, nullable=False)
oh_type = Column(String, nullable=False)
job_id = Column(
UUID(as_uuid=True),
ForeignKey("oh_ms_job.id", ondelete="cascade"),
ForeignKey("oh_ms_workscope_group.id", ondelete="cascade"),
nullable=False,
)
class MasterActivity(Base, DefaultMixin):
__tablename__ = "oh_ms_job"
__tablename__ = "oh_ms_workscope_group"
workscope = Column(String, nullable=True)
system = Column(String, nullable=True)
@ -31,6 +32,19 @@ class MasterActivity(Base, DefaultMixin):
lazy="selectin",
)
equipment_workscope_groups = relationship(
"EquipmentWorkscopeGroup",
lazy="selectin",
back_populates="workscope_group",
)
oh_types = relationship(
"WorkscopeOHType",
lazy="selectin",
back_populates="workscope_group",
)
# details = relationship(
# "MasterActivityDetail",
# lazy="raise",

@ -21,7 +21,6 @@ class ActivityMasterCreate(ActivityMaster):
class ActivityMasterTasks(DefultBase):
description: str
oh_type: str
class ActivityMasterRead(ActivityMaster):

@ -0,0 +1,18 @@
from sqlalchemy import UUID, Column, Float, ForeignKey, Integer, String
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
from src.database.core import Base
from src.models import DefaultMixin, IdentityMixin, TimeStampMixin
from src.workorder.model import MasterWorkOrder
class WorkscopeOHType(Base):
__tablename__ = 'oh_tr_workscope_maintenance_type'
id = Column(UUID(as_uuid=True), primary_key=True)
workscope_group_id = Column(UUID(as_uuid=True), ForeignKey('oh_ms_workscope_group.id'))
maintenance_type_id = Column(UUID(as_uuid=True), ForeignKey('oh_ms_maintenance_type.id'))
workscope_group = relationship('MasterActivity', back_populates='oh_types')
oh_type = relationship('MaintenanceType')

@ -0,0 +1,59 @@
from typing import Optional
from sqlalchemy import Delete, Select
from sqlalchemy.orm import joinedload, selectinload
from src.auth.service import CurrentUser
from src.database.core import DbSession
from src.database.service import CommonParameters, search_filter_sort_paginate
from .model import MasterActivity
from .schema import ActivityMaster, ActivityMasterCreate
async def get(*, db_session: DbSession, activity_id: str) -> Optional[ActivityMaster]:
"""Returns a document based on the given document id."""
result = await db_session.get(MasterActivity, activity_id)
return result
async def get_all(common: CommonParameters):
query = Select(MasterActivity)
results = await search_filter_sort_paginate(model=query, **common)
return results
async def create(*, db_session: DbSession, activty_in: ActivityMasterCreate):
activity = MasterActivity(**activty_in.model_dump())
db_session.add(activity)
await db_session.commit()
return activity
async def update(
*,
db_session: DbSession,
activity: MasterActivity,
activity_in: ActivityMasterCreate
):
"""Updates a document."""
data = activity_in.model_dump()
update_data = activity_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, activity_id: str):
"""Deletes a document."""
activity = await db_session.get(MasterActivity, activity_id)
await db_session.delete(activity)
await db_session.commit()
Loading…
Cancel
Save