Merge branch 'development' of https://git.aduanasoft.com/ADUANASOFT/anexo76 into development
This commit is contained in:
@@ -3,7 +3,7 @@ import logging
|
||||
|
||||
from core.database import get_core_db
|
||||
from core.security import get_current_user, validate_access_to_resource
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, Path, Query
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, Path, Query, Request
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -137,6 +137,7 @@ class TenantCRUDRoutes(
|
||||
description=f"Get paginated list of {self.resource_name}s with optional filters",
|
||||
)
|
||||
async def list_resources(
|
||||
request: Request,
|
||||
company_id: int = Query(..., description="Company ID"),
|
||||
page: int = Query(1, ge=1, description="Page number"),
|
||||
page_size: int = Query(
|
||||
@@ -145,13 +146,6 @@ class TenantCRUDRoutes(
|
||||
le=self.max_page_size,
|
||||
description="Page size",
|
||||
),
|
||||
status: Optional[str] = Query(None, description="Filter by status"),
|
||||
operation_type: Optional[str] = Query(
|
||||
None, description="Filter by operation type"
|
||||
),
|
||||
invoice_type: Optional[str] = Query(
|
||||
None, description="Filter by invoice type"
|
||||
),
|
||||
db: Session = Depends(self.db_dependency),
|
||||
current_user: Dict[str, Any] = Depends(self.auth_dependency),
|
||||
):
|
||||
@@ -164,13 +158,15 @@ class TenantCRUDRoutes(
|
||||
)
|
||||
|
||||
skip = (page - 1) * page_size
|
||||
filters = {}
|
||||
if status:
|
||||
filters["status"] = status
|
||||
if operation_type:
|
||||
filters["operation_type"] = operation_type
|
||||
if invoice_type:
|
||||
filters["invoice_type"] = invoice_type
|
||||
|
||||
# Extraer todos los parámetros de búsqueda dinámicamente
|
||||
# Excluimos los parámetros estándar de paginación y control
|
||||
standard_params = {"company_id", "page", "page_size"}
|
||||
filters = {
|
||||
k: v
|
||||
for k, v in request.query_params.items()
|
||||
if k not in standard_params and v is not None and v != ""
|
||||
}
|
||||
|
||||
items, total = self.service.get_all(
|
||||
db, tenant_id, company_id, skip, page_size, filters
|
||||
|
||||
@@ -46,7 +46,7 @@ class ClientProviderProgramsDTO(BaseModel):
|
||||
program_number: Optional[str] = Field(
|
||||
None, max_length=40, description="Program number"
|
||||
)
|
||||
prosec: Optional[int] = Field(None, description="PROSEC")
|
||||
prosec: Optional[str] = Field(None, max_length=8, description="PROSEC")
|
||||
prosec_authorization: Optional[str] = Field(
|
||||
None, max_length=20, description="PROSEC authorization"
|
||||
)
|
||||
|
||||
@@ -136,7 +136,7 @@ class ClientProviderPrograms(Base, TenantScopedMixin, TimestampMixin):
|
||||
# Program information
|
||||
program: Mapped[Optional[str]] = mapped_column(String(7))
|
||||
program_number: Mapped[Optional[str]] = mapped_column(String(40))
|
||||
prosec: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
prosec: Mapped[Optional[str]] = mapped_column(String(8))
|
||||
prosec_authorization: Mapped[Optional[str]] = mapped_column(String(20))
|
||||
secon_auth_date: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
manufacturer_id: Mapped[Optional[str]] = mapped_column(String(25))
|
||||
|
||||
@@ -43,7 +43,7 @@ class CustomsBrokerResponseDTO(CustomsBrokerBaseDTO):
|
||||
broker_key: str
|
||||
tenant_id: int
|
||||
company_id: int
|
||||
vu: Optional["CustomsBrokerVUCreateDTO"] = None
|
||||
vu: Optional["CustomsBrokerVUResponseDTO"] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@@ -95,6 +95,11 @@ class CustomsBrokerVUCreateDTO(BaseModel):
|
||||
doda_web_service_access_key: Optional[str] = None
|
||||
doda_fiel_access_key: Optional[str] = None
|
||||
doda_xml_files_path: Optional[str] = None
|
||||
tenant_id: Optional[int] = None
|
||||
company_id: Optional[int] = None
|
||||
|
||||
class CustomsBrokerVUResponseDTO(CustomsBrokerVUCreateDTO):
|
||||
customs_broker_id: int
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@@ -112,6 +117,8 @@ class CustomsBrokerPersonnelDTO(BaseModel):
|
||||
last_name: Optional[str] = None
|
||||
middle_name: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
tenant_id: Optional[int] = None
|
||||
company_id: Optional[int] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
@@ -62,7 +62,7 @@ def update_customs_broker(
|
||||
|
||||
@router.put(
|
||||
"/customs-broker-vu/{broker_key}",
|
||||
response_model=dto.CustomsBrokerVUCreateDTO,
|
||||
response_model=dto.CustomsBrokerVUResponseDTO,
|
||||
)
|
||||
def update_customs_broker_vu(
|
||||
broker_key: str,
|
||||
@@ -77,7 +77,7 @@ def update_customs_broker_vu(
|
||||
if not broker:
|
||||
raise HTTPException(status_code=404, detail="Customs Broker not found")
|
||||
|
||||
updated_vu = services.CustomsBrokerVUService.update_vu(db, broker_key, vu_data)
|
||||
updated_vu = services.CustomsBrokerVUService.update_vu(db, broker_key, vu_data, tenant_id, company_id)
|
||||
if not updated_vu:
|
||||
raise HTTPException(status_code=404, detail="Customs Broker VU not found")
|
||||
return updated_vu
|
||||
@@ -102,7 +102,7 @@ def update_customs_broker_personnel(
|
||||
raise HTTPException(status_code=404, detail="Customs Broker not found")
|
||||
|
||||
updated_personnel = services.CustomsBrokerPersonnelService.update_personnel(
|
||||
db, broker_key, line, personnel_data
|
||||
db, broker_key, line, personnel_data, tenant_id, company_id
|
||||
)
|
||||
if not updated_personnel:
|
||||
raise HTTPException(
|
||||
|
||||
@@ -90,9 +90,17 @@ class CustomsBrokerVUService:
|
||||
return new_vu
|
||||
|
||||
@staticmethod
|
||||
def update_vu(db: Session, broker_key: str, vu_data: dto.CustomsBrokerVUCreateDTO):
|
||||
def update_vu(db: Session, broker_key: str, vu_data: dto.CustomsBrokerVUCreateDTO, tenant_id: int, company_id: int):
|
||||
# We need the custom broker ID to insert a new VU
|
||||
broker = db.query(models.CustomsBroker).filter(models.CustomsBroker.broker_key == broker_key).first()
|
||||
broker = (
|
||||
db.query(models.CustomsBroker)
|
||||
.filter(
|
||||
models.CustomsBroker.broker_key == broker_key,
|
||||
models.CustomsBroker.tenant_id == tenant_id,
|
||||
models.CustomsBroker.company_id == company_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if not broker:
|
||||
return None
|
||||
|
||||
@@ -108,6 +116,8 @@ class CustomsBrokerVUService:
|
||||
else:
|
||||
# Create new
|
||||
new_vu_data = vu_data.model_dump()
|
||||
new_vu_data["tenant_id"] = tenant_id
|
||||
new_vu_data["company_id"] = company_id
|
||||
new_vu = models.CustomsBrokerVU(customs_broker_id=broker.id, **new_vu_data)
|
||||
db.add(new_vu)
|
||||
db.commit()
|
||||
@@ -125,24 +135,36 @@ class CustomsBrokerVUService:
|
||||
|
||||
class CustomsBrokerPersonnelService:
|
||||
@staticmethod
|
||||
def get_by_broker_key_and_line(db: Session, broker_key: str, line: int):
|
||||
def get_by_broker_key_and_line(db: Session, broker_key: str, line: int, tenant_id: int, company_id: int):
|
||||
return (
|
||||
db.query(models.CustomsBrokerPersonnel)
|
||||
.join(models.CustomsBroker)
|
||||
.filter(
|
||||
models.CustomsBroker.broker_key == broker_key,
|
||||
models.CustomsBrokerPersonnel.line == line,
|
||||
models.CustomsBroker.tenant_id == tenant_id,
|
||||
models.CustomsBroker.company_id == company_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def create_personnel(db: Session, broker_key: str, personnel_data: dto.CustomsBrokerPersonnelDTO):
|
||||
broker = db.query(models.CustomsBroker).filter(models.CustomsBroker.broker_key == broker_key).first()
|
||||
def create_personnel(db: Session, broker_key: str, personnel_data: dto.CustomsBrokerPersonnelDTO, tenant_id: int, company_id: int):
|
||||
broker = (
|
||||
db.query(models.CustomsBroker)
|
||||
.filter(
|
||||
models.CustomsBroker.broker_key == broker_key,
|
||||
models.CustomsBroker.tenant_id == tenant_id,
|
||||
models.CustomsBroker.company_id == company_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if not broker:
|
||||
return None
|
||||
|
||||
new_personnel_data = personnel_data.model_dump()
|
||||
new_personnel_data["tenant_id"] = tenant_id
|
||||
new_personnel_data["company_id"] = company_id
|
||||
new_personnel = models.CustomsBrokerPersonnel(customs_broker_id=broker.id, **new_personnel_data)
|
||||
db.add(new_personnel)
|
||||
db.commit()
|
||||
@@ -155,16 +177,22 @@ class CustomsBrokerPersonnelService:
|
||||
broker_key: str,
|
||||
line: int,
|
||||
personnel_data: dto.CustomsBrokerPersonnelDTO,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
):
|
||||
personnel = CustomsBrokerPersonnelService.get_by_broker_key_and_line(
|
||||
db, broker_key, line
|
||||
db, broker_key, line, tenant_id, company_id
|
||||
)
|
||||
if personnel:
|
||||
for key, value in personnel_data.model_dump(exclude_unset=True).items():
|
||||
setattr(personnel, key, value)
|
||||
db.commit()
|
||||
db.refresh(personnel)
|
||||
return personnel
|
||||
return personnel
|
||||
else:
|
||||
return CustomsBrokerPersonnelService.create_personnel(
|
||||
db, broker_key, personnel_data, tenant_id, company_id
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def delete_personnel(db: Session, broker_key: str, line: int):
|
||||
|
||||
@@ -6,6 +6,8 @@ from sqlalchemy.orm import Session
|
||||
from api.v1.modules.public.reference_data.pedimento_codes.models import PedimentoCode
|
||||
from api.v1.modules.public.reference_data.customs_sections.models import CustomsSection
|
||||
from api.v1.modules.public.reference_data.code_pedimento_regimens.models import CodePedimentoRegimen
|
||||
from api.v1.modules.public.reference_data.transport_types.models import TransportType
|
||||
from api.v1.modules.public.reference_data.transport_modes.models import TransportMode
|
||||
|
||||
# Import A76 Services
|
||||
from api.v1.modules.a76.customs_brokers.services import CustomsBrokerService
|
||||
@@ -15,6 +17,8 @@ from api.v1.modules.a76.clients_and_providers.service import ClientProviderServi
|
||||
from api.v1.modules.public.reference_data.pedimento_codes.dto import PedimentoCodeDTO
|
||||
from api.v1.modules.public.reference_data.customs_sections.dto import CustomsSectionDTO
|
||||
from api.v1.modules.public.reference_data.code_pedimento_regimens.dto import CodePedimentoRegimenDTO
|
||||
from api.v1.modules.public.reference_data.transport_types.dto import TransportTypeDTO
|
||||
from api.v1.modules.public.reference_data.transport_modes.dto import TransportModeDTO
|
||||
from api.v1.modules.a76.customs_brokers.dto import CustomsBrokerResponseDTO
|
||||
from api.v1.modules.a76.clients_and_providers.dto import ClientProviderResponseDTO
|
||||
from .dtos.pedimentos import PedimentosResponse
|
||||
@@ -53,6 +57,20 @@ class PedimentoCatalogService:
|
||||
except Exception as e:
|
||||
print(f"Error fetching code_pedimento_regimens: {e}")
|
||||
|
||||
try:
|
||||
response.transport_types = [
|
||||
TransportTypeDTO.model_validate(obj) for obj in db.query(TransportType).limit(200).all()
|
||||
]
|
||||
except Exception as e:
|
||||
print(f"Error fetching transport_types: {e}")
|
||||
|
||||
try:
|
||||
response.transport_modes = [
|
||||
TransportModeDTO.model_validate(obj) for obj in db.query(TransportMode).limit(100).all()
|
||||
]
|
||||
except Exception as e:
|
||||
print(f"Error fetching transport_modes: {e}")
|
||||
|
||||
# Helper to fetch tenant/company specific data
|
||||
def fetch_tenant_data():
|
||||
# Customs Brokers
|
||||
|
||||
@@ -11,6 +11,8 @@ from api.v1.modules.public.reference_data.customs_sections.dto import CustomsSec
|
||||
from api.v1.modules.public.reference_data.code_pedimento_regimens.dto import CodePedimentoRegimenDTO
|
||||
from api.v1.modules.a76.customs_brokers.dto import CustomsBrokerResponseDTO
|
||||
from api.v1.modules.a76.clients_and_providers.dto import ClientProviderResponseDTO
|
||||
from api.v1.modules.public.reference_data.transport_types.dto import TransportTypeDTO
|
||||
from api.v1.modules.public.reference_data.transport_modes.dto import TransportModeDTO
|
||||
from .dtos.pedimentos import PedimentosResponse
|
||||
|
||||
|
||||
@@ -22,6 +24,8 @@ class PedimentoCatalogsResponse(BaseModel):
|
||||
code_pedimento_regimens: List[CodePedimentoRegimenDTO] = []
|
||||
customs_brokers: List[CustomsBrokerResponseDTO] = []
|
||||
clients: List[ClientProviderResponseDTO] = []
|
||||
transport_types: List[TransportTypeDTO] = []
|
||||
transport_modes: List[TransportModeDTO] = []
|
||||
|
||||
|
||||
class PedimentoCreationResponse(PedimentoCatalogsResponse):
|
||||
|
||||
@@ -25,6 +25,10 @@ class TrailerService:
|
||||
|
||||
# Apply filters if provided
|
||||
if filters:
|
||||
if filters.get("trailer_number"):
|
||||
query = query.filter(
|
||||
models.Trailer.trailer_number.ilike(f"%{filters['trailer_number']}%")
|
||||
)
|
||||
if filters.get("plate_number"):
|
||||
query = query.filter(
|
||||
models.Trailer.plate_number.ilike(f"%{filters['plate_number']}%")
|
||||
@@ -75,8 +79,8 @@ class TrailerService:
|
||||
db: Session,
|
||||
trailer_number: str,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
trailer_data: dto.TrailerUpdateDTO,
|
||||
company_id: int,
|
||||
) -> Optional[models.Trailer]:
|
||||
"""Update a trailer"""
|
||||
trailer = TrailerService.get_by_id(db, trailer_number, tenant_id, company_id)
|
||||
|
||||
@@ -9,7 +9,7 @@ class Transporter(Base, TenantScopedMixin, TimestampMixin):
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
transporter_key = Column(String(5), primary_key=True, nullable=False)
|
||||
transporter_key = Column(String(23), primary_key=True, nullable=False)
|
||||
name = Column(String(256), nullable=True)
|
||||
short_name = Column(String(10), nullable=True)
|
||||
responsible = Column(String(100), nullable=True)
|
||||
@@ -27,4 +27,4 @@ class Transporter(Base, TenantScopedMixin, TimestampMixin):
|
||||
ftp_user = Column(String(200), nullable=True)
|
||||
ftp_password = Column(String(100), nullable=True)
|
||||
ftp_directory = Column(String(1000), nullable=True)
|
||||
filler_code = Column(String(4), nullable=True)
|
||||
filler_code = Column(String(20), nullable=True)
|
||||
|
||||
@@ -25,6 +25,10 @@ class TransporterService:
|
||||
|
||||
# Apply filters if provided
|
||||
if filters:
|
||||
if filters.get("transporter_key"):
|
||||
query = query.filter(
|
||||
models.Transporter.transporter_key.ilike(f"%{filters['transporter_key']}%")
|
||||
)
|
||||
if filters.get("name"):
|
||||
query = query.filter(
|
||||
models.Transporter.name.ilike(f"%{filters['name']}%")
|
||||
@@ -75,8 +79,8 @@ class TransporterService:
|
||||
db: Session,
|
||||
transporter_key: str,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
transporter_data: dto.TransporterUpdateDTO,
|
||||
company_id: int,
|
||||
) -> Optional[models.Transporter]:
|
||||
"""Update a transporter"""
|
||||
transporter = TransporterService.get_by_id(
|
||||
|
||||
@@ -25,6 +25,10 @@ class VehicleService:
|
||||
|
||||
# Apply filters if provided
|
||||
if filters:
|
||||
if filters.get("vehicle_key"):
|
||||
query = query.filter(
|
||||
models.Vehicle.vehicle_key.ilike(f"%{filters['vehicle_key']}%")
|
||||
)
|
||||
if filters.get("plate_number"):
|
||||
query = query.filter(
|
||||
models.Vehicle.plate_number.ilike(f"%{filters['plate_number']}%")
|
||||
@@ -75,8 +79,8 @@ class VehicleService:
|
||||
db: Session,
|
||||
vehicle_key: str,
|
||||
tenant_id: int,
|
||||
company_id: int,
|
||||
vehicle_data: dto.VehicleUpdateDTO,
|
||||
company_id: int,
|
||||
) -> Optional[models.Vehicle]:
|
||||
"""Update a vehicle"""
|
||||
vehicle = VehicleService.get_by_id(db, vehicle_key, tenant_id, company_id)
|
||||
|
||||
Reference in New Issue
Block a user