import logging from typing import List, Optional, Dict, Any, Tuple from fastapi import HTTPException from sqlalchemy import or_ from sqlalchemy.orm import Session from .models import ManifestDriver from .dtos import ManifestDriverCreateDTO, ManifestDriverUpdateDTO logger = logging.getLogger(__name__) class ManifestDriverService: @staticmethod def get_all( db: Session, tenant_id: int, company_id: int, skip: int = 0, limit: int = 100, filters: Optional[Dict[str, Any]] = None, ) -> Tuple[List[ManifestDriver], int]: query = db.query(ManifestDriver).filter( ManifestDriver.tenant_id == tenant_id, ManifestDriver.company_id == company_id, ) if filters: if filters.get("search"): search_pattern = f"%{filters['search']}%" query = query.filter( or_( ManifestDriver.manifest_number.ilike(search_pattern), ManifestDriver.driver_name.ilike(search_pattern), ) ) if filters.get("manifest_number"): query = query.filter(ManifestDriver.manifest_number == filters["manifest_number"]) total = query.count() items = query.offset(skip).limit(limit).all() return items, total @staticmethod def get_by_pk( db: Session, manifest_number: str, driver_name: str, tenant_id: int, company_id: int ) -> Optional[ManifestDriver]: return ( db.query(ManifestDriver) .filter( ManifestDriver.manifest_number == manifest_number, ManifestDriver.driver_name == driver_name, ManifestDriver.tenant_id == tenant_id, ManifestDriver.company_id == company_id, ) .first() ) @staticmethod def create( db: Session, data: ManifestDriverCreateDTO, tenant_id: int, company_id: int, ) -> ManifestDriver: try: db_item = ManifestDriver( **data.model_dump(exclude_unset=True), tenant_id=tenant_id, company_id=company_id, ) db.add(db_item) db.commit() db.refresh(db_item) return db_item except Exception as e: db.rollback() logger.error(f"Error creating manifest driver: {str(e)}") raise HTTPException(status_code=500, detail="Error creating manifest driver") @staticmethod def update( db: Session, manifest_number: str, driver_name: str, tenant_id: int, company_id: int, data: ManifestDriverUpdateDTO, ) -> Optional[ManifestDriver]: item = ManifestDriverService.get_by_pk(db, manifest_number, driver_name, tenant_id, company_id) if not item: return None try: update_data = data.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(item, field, value) db.commit() db.refresh(item) return item except Exception as e: db.rollback() logger.error(f"Error updating manifest driver: {str(e)}") raise HTTPException(status_code=500, detail="Error updating manifest driver") @staticmethod def delete( db: Session, manifest_number: str, driver_name: str, tenant_id: int, company_id: int ) -> bool: item = ManifestDriverService.get_by_pk(db, manifest_number, driver_name, tenant_id, company_id) if not item: return False try: db.delete(item) db.commit() return True except Exception as e: db.rollback() logger.error(f"Error deleting manifest driver: {str(e)}") raise HTTPException(status_code=500, detail="Error deleting manifest driver")