128 lines
4.8 KiB
Python
128 lines
4.8 KiB
Python
from typing import List, Optional, Dict, Any
|
|
|
|
from fastapi import APIRouter, Depends, Query, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from core.database import get_core_db
|
|
from core.security import get_current_user, validate_access_to_resource
|
|
from .dtos import (
|
|
ManifestCreateDTO,
|
|
ManifestUpdateDTO,
|
|
ManifestResponseDTO,
|
|
ManifestListDTO,
|
|
InvoiceManifestUpdateDTO,
|
|
)
|
|
from .service import ManifestService
|
|
|
|
router = APIRouter(prefix="/manifests")
|
|
|
|
|
|
@router.get("/", response_model=ManifestListDTO)
|
|
async def list_manifests(
|
|
company_id: int = Query(..., description="Company ID"),
|
|
search: Optional[str] = Query(None, description="Search term"),
|
|
manifest_number: Optional[str] = Query(None, description="Manifest number"),
|
|
start_date: Optional[int] = Query(None, description="Start date (YYYYMMDD)"),
|
|
end_date: Optional[int] = Query(None, description="End date (YYYYMMDD)"),
|
|
skip: int = Query(0, ge=0, description="Skip"),
|
|
limit: int = Query(50, ge=1, le=100, description="Limit"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: Dict[str, Any] = Depends(get_current_user),
|
|
):
|
|
"""
|
|
List all manifests for a company with pagination and filters
|
|
"""
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["export_manifest.view"])
|
|
filters = {
|
|
"search": search,
|
|
"manifest_number": manifest_number,
|
|
"start_date": start_date,
|
|
"end_date": end_date,
|
|
}
|
|
items, total = ManifestService.get_all(
|
|
db, tenant_id, company_id, skip=skip, limit=limit, filters=filters
|
|
)
|
|
return {
|
|
"items": [ManifestResponseDTO.model_validate(item) for item in items],
|
|
"total": total,
|
|
"page": (skip // limit) + 1,
|
|
"page_size": limit,
|
|
}
|
|
|
|
|
|
@router.post("/", response_model=ManifestResponseDTO)
|
|
async def create_manifest(
|
|
manifest_data: ManifestCreateDTO,
|
|
company_id: int = Query(..., description="Company ID"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["export_manifest.view"])
|
|
return ManifestService.create(db, manifest_data, tenant_id, company_id)
|
|
|
|
|
|
@router.get("/{manifest_id}", response_model=ManifestResponseDTO)
|
|
async def get_manifest(
|
|
manifest_id: int,
|
|
company_id: int = Query(..., description="Company ID"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["export_manifest.view"])
|
|
manifest = ManifestService.get_by_id(db, manifest_id, tenant_id, company_id)
|
|
if not manifest:
|
|
raise HTTPException(status_code=404, detail="Manifest not found")
|
|
return manifest
|
|
|
|
|
|
@router.patch("/{manifest_id}", response_model=ManifestResponseDTO)
|
|
async def update_manifest(
|
|
manifest_id: int,
|
|
manifest_data: ManifestUpdateDTO,
|
|
company_id: int = Query(..., description="Company ID"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["export_manifest.view"])
|
|
manifest = ManifestService.update(
|
|
db, manifest_id, tenant_id, company_id, manifest_data
|
|
)
|
|
if not manifest:
|
|
raise HTTPException(status_code=404, detail="Manifest not found")
|
|
return manifest
|
|
|
|
|
|
@router.delete("/{manifest_id}", response_model=bool)
|
|
async def delete_manifest(
|
|
manifest_id: int,
|
|
company_id: int = Query(..., description="Company ID"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["export_manifest.view"])
|
|
success = ManifestService.delete(db, manifest_id, tenant_id, company_id)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Manifest not found")
|
|
return success
|
|
|
|
|
|
@router.patch("/invoices/{invoice_id}/compliance", response_model=bool)
|
|
async def update_invoice_manifest(
|
|
invoice_id: int,
|
|
data: InvoiceManifestUpdateDTO,
|
|
company_id: int = Query(..., description="Company ID"),
|
|
db: Session = Depends(get_core_db),
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
"""
|
|
Dedicated endpoint to update manifest_number for an invoice.
|
|
Safely bypasses all core invoice update validations.
|
|
"""
|
|
tenant_id = validate_access_to_resource(db, company_id, current_user)
|
|
success = ManifestService.update_invoice_manifest(
|
|
db, invoice_id, tenant_id, company_id, data.manifest_number
|
|
)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Invoice not found")
|
|
return success
|