From 153fca9ad7a7374c21bb9db2c018f7e82dab1a96 Mon Sep 17 00:00:00 2001 From: Kevin_Ramirez Date: Fri, 19 Dec 2025 17:25:12 -0600 Subject: [PATCH] Se agrego un modal provicional para el fomrulario y creacion de los registros en la base de datos. Aun faltan 3 catalogos para la integracion con la base de datos --- .../classification_concepts/models.py | 1 + .../a76/general_catalogs/company/routes.py | 32 +- .../a76/general_catalogs/company/service.py | 31 +- .../a76/general_catalogs/concepts/dto.py | 4 +- .../a76/general_catalogs/concepts/models.py | 14 + .../customs_broker_concepts/dto.py | 3 +- .../customs_broker_concepts/models.py | 8 +- .../customs_broker_concepts/routes.py | 2 +- .../general_catalogs/equivalencies/models.py | 4 + .../general_catalogs/error_catalogs/models.py | 8 +- .../general_catalogs/exchange_rate/models.py | 3 + .../a76/general_catalogs/identifiers/dto.py | 17 +- .../general_catalogs/identifiers/models.py | 4 + .../modules/a76/general_catalogs/inpc/dto.py | 6 +- .../a76/general_catalogs/inpc/models.py | 3 + .../a76/general_catalogs/inpc/routes.py | 14 +- .../a76/general_catalogs/legends/dto.py | 2 + .../a76/general_catalogs/legends/models.py | 2 + .../a76/general_catalogs/legends/routes.py | 2 +- .../multi_currency_types/dto.py | 4 +- .../multi_currency_types/models.py | 5 + .../a76/general_catalogs/packages/models.py | 2 +- .../a76/general_catalogs/signatures/dto.py | 3 + .../a76/general_catalogs/signatures/models.py | 1 + .../general_catalogs/unit_conversions/dto.py | 18 +- .../unit_conversions/models.py | 3 + .../units_of_measure/models.py | 2 +- .../classification-concepts.ts | 83 +++-- .../dashboard/a76/general_catalogs/company.ts | 164 ++++----- .../a76/general_catalogs/concepts.ts | 118 ++++--- .../customs-broker-concepts.ts | 100 +++--- .../a76/general_catalogs/error-catalogs.ts | 143 ++++++-- .../a76/general_catalogs/identifiers.ts | 34 +- .../dashboard/a76/general_catalogs/inpc.ts | 91 ++--- .../dashboard/a76/general_catalogs/legends.ts | 85 ++--- .../a76/general_catalogs/locations.ts | 99 +++--- .../general_catalogs/multi-currency-types.ts | 90 +++-- .../a76/general_catalogs/packages.ts | 77 +++-- .../a76/general_catalogs/signatures.ts | 93 +++--- .../a76/general_catalogs/unit-conversions.ts | 90 ++--- .../src/lib/api/dashboard/a76/invoices.ts | 2 +- .../company/create-edit-dialog.svelte | 127 ------- .../exchange-rate/create-edit-dialog.svelte | 313 ++++++++++-------- .../classification/create-edit-dialog.svelte | 115 +++++++ .../{ => general_catalogs}/company/columns.ts | 0 .../company/create-edit-dialog.svelte | 296 +++++++++++++++++ .../company/data-table-actions.svelte | 0 .../concepts/create-edit-dialog.svelte | 213 ++++++++++++ .../create-edite-dialoge.svelte | 165 +++++++++ .../create-edite-dialoge.svelte | 141 ++++++++ .../inpc/create-edite-dialoge.svelte | 166 ++++++++++ .../legend/create-edite-dialoge.svelte | 149 +++++++++ .../locations/create-edite-dialog.svelte | 152 +++++++++ .../create-edit-dialog.svelte | 196 +++++++++++ .../signatures/create-edit-dialog.svelte | 163 +++++++++ .../create-edite-dialoge.svelte | 164 +++++++++ .../identifiers/create-edit-dialog.svelte | 267 ++++++++------- .../packages/create-edit-dialog.svelte | 6 +- .../dashboard/packages/data-table.svelte | 169 +++++----- .../classification_concepts/+page.svelte | 6 + .../company_information/+page.svelte | 4 +- .../general_catalogs/concepts/+page.svelte | 6 + .../customs_broker_concepts/+page.svelte | 6 + .../error_catalogs/+page.svelte | 9 + .../exchange-rate/+page.svelte | 14 +- .../general_catalogs/inpc/+page.svelte | 6 + .../general_catalogs/legends/+page.svelte | 6 + .../general_catalogs/locations/+page.svelte | 88 ++--- .../multi_currency_types/+page.svelte | 7 + .../general_catalogs/signatures/+page.svelte | 9 +- .../unit_conversions/+page.svelte | 7 + 71 files changed, 3316 insertions(+), 1121 deletions(-) delete mode 100644 frontend/src/lib/components/dashboard/company/create-edit-dialog.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/classification/create-edit-dialog.svelte rename frontend/src/lib/components/dashboard/{ => general_catalogs}/company/columns.ts (100%) create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/company/create-edit-dialog.svelte rename frontend/src/lib/components/dashboard/{ => general_catalogs}/company/data-table-actions.svelte (100%) create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/concepts/create-edit-dialog.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/customs_broker_concepts/create-edite-dialoge.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/error_catalogs/create-edite-dialoge.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/inpc/create-edite-dialoge.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/legend/create-edite-dialoge.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/locations/create-edite-dialog.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/multi_currency_types/create-edit-dialog.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/signatures/create-edit-dialog.svelte create mode 100644 frontend/src/lib/components/dashboard/general_catalogs/unit-conversion/create-edite-dialoge.svelte diff --git a/backend/api/v1/modules/a76/general_catalogs/classification_concepts/models.py b/backend/api/v1/modules/a76/general_catalogs/classification_concepts/models.py index 9789731e..129d05fc 100644 --- a/backend/api/v1/modules/a76/general_catalogs/classification_concepts/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/classification_concepts/models.py @@ -14,5 +14,6 @@ class ClassificationConcept(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + classification: Mapped[str] = mapped_column( String(30), nullable=False) # CLASIFICACION diff --git a/backend/api/v1/modules/a76/general_catalogs/company/routes.py b/backend/api/v1/modules/a76/general_catalogs/company/routes.py index 0095bc4d..8a948f6b 100644 --- a/backend/api/v1/modules/a76/general_catalogs/company/routes.py +++ b/backend/api/v1/modules/a76/general_catalogs/company/routes.py @@ -2,7 +2,7 @@ Rutas para gestión de empresa """ -from typing import List +from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session @@ -17,7 +17,29 @@ from .service import CompanyService # Main router that includes base CRUD router = APIRouter(prefix="/company") -# Custom endpoints +@router.post( + "", # Se suma al prefix, queda POST /api/v1/a76/company + response_model=CompanyResponseDTO, + status_code=status.HTTP_201_CREATED, + summary="Create a new company", +) +async def create_company( + data: CompanyCreateDTO, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user), +): + + tenant_id = current_user.get("tenant_id") + if not tenant_id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Tenant ID not found in user data", + ) + + service = CompanyService(db) + return service.create_company_manually(data, tenant_id=tenant_id) + + @router.get( "/my-companies", response_model=List[CompanyResponseDTO], @@ -166,11 +188,10 @@ async def get_program_info( "prosec": company.prosec, "prosec_authorization": company.prosec_authorization, } - -# Base CRUD routes using TenantCRUDRoutes + base_router = TenantCRUDRoutes( service=CompanyService, - create_schema=CompanyCreateDTO, + create_schema=None, update_schema=CompanyUpdateDTO, response_schema=CompanyResponseDTO, prefix="", @@ -179,4 +200,5 @@ base_router = TenantCRUDRoutes( enable_list=True, enable_filters=True, ).router + router.include_router(base_router) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/company/service.py b/backend/api/v1/modules/a76/general_catalogs/company/service.py index a42250a5..f3c03827 100644 --- a/backend/api/v1/modules/a76/general_catalogs/company/service.py +++ b/backend/api/v1/modules/a76/general_catalogs/company/service.py @@ -64,6 +64,7 @@ class CompanyService: .first() ) + # ESTE ES EL MÉTODO VIEJO QUE CAUSABA PROBLEMAS (Lo dejamos por si acaso) @staticmethod def create( db: Session, @@ -71,7 +72,7 @@ class CompanyService: tenant_id: int, company_id: int, ) -> Company: - """Create a new company""" + """Create a new company (MÉTODO GENÉRICO - NO USAR PARA CREACIÓN MANUAL)""" try: db_company = Company( **company_data.model_dump(exclude_unset=True), @@ -159,3 +160,31 @@ class CompanyService: .first() is not None ) + + def create_company_manually(self, data: CompanyCreateDTO, tenant_id: int) -> Company: + + try: + # 1. Preparar datos + obj_data = data.model_dump(exclude_unset=True) + + # 2. Crear objeto SQLAlchemy + db_obj = Company(**obj_data, tenant_id=tenant_id) + + # 3. Guardar + self.db.add(db_obj) + self.db.commit() + self.db.refresh(db_obj) + + return db_obj + + except IntegrityError as e: + self.db.rollback() + logger.error(f"IntegrityError creating company manually: {str(e)}") + raise HTTPException( + status_code=400, + detail="Error de integridad: Es posible que esta empresa ya exista.", + ) + except Exception as e: + self.db.rollback() + logger.error(f"Error creating company manually: {str(e)}") + raise HTTPException(status_code=500, detail=f"Error creando empresa: {str(e)}") \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/concepts/dto.py b/backend/api/v1/modules/a76/general_catalogs/concepts/dto.py index e4b391ab..e8c030e0 100644 --- a/backend/api/v1/modules/a76/general_catalogs/concepts/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/concepts/dto.py @@ -4,6 +4,7 @@ from pydantic import BaseModel, Field, ConfigDict class ConceptBase(BaseModel): code: str = Field(..., max_length=15, description="Concept Code (CLAVE)") + company_id: int = Field(..., description="Company ID") description: Optional[str] = Field( None, max_length=120, description="Description") description_en: Optional[str] = Field( @@ -18,7 +19,6 @@ class ConceptBase(BaseModel): section: Optional[int] = Field(None, description="Section") classification: Optional[str] = Field( None, max_length=30, description="Classification") - company_id: int = Field(..., description="Company ID") class ConceptCreate(ConceptBase): @@ -32,7 +32,7 @@ class ConceptUpdate(BaseModel): detailed_description: Optional[str] = Field(None, max_length=1000) priority: Optional[int] = None priority_ame: Optional[int] = None - first_total: Optional[bool] = None + first_total: Optional[bool] = None type: Optional[str] = Field(None, max_length=9) is_printed: Optional[bool] = None section: Optional[int] = None diff --git a/backend/api/v1/modules/a76/general_catalogs/concepts/models.py b/backend/api/v1/modules/a76/general_catalogs/concepts/models.py index 8c13fc34..d3824d1d 100644 --- a/backend/api/v1/modules/a76/general_catalogs/concepts/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/concepts/models.py @@ -18,25 +18,39 @@ class Concept(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + + company_id: Mapped[int] = mapped_column( + Integer, nullable=False) # IDEMPRESA + code: Mapped[str] = mapped_column(String(15), nullable=False) # CLAVE + description: Mapped[Optional[str]] = mapped_column( String(120), nullable=True) # DESCRIPCION + description_en: Mapped[Optional[str]] = mapped_column( String(120), nullable=True) # DESCRIPCIONINGLES + detailed_description: Mapped[Optional[str]] = mapped_column( String(1000), nullable=True) # DESCRIPCIONDETALLADA + priority: Mapped[Optional[int]] = mapped_column( Integer, nullable=True) # PRIORIDAD + priority_ame: Mapped[Optional[int]] = mapped_column( Integer, nullable=True) # PRIORIDADAME + first_total: Mapped[Optional[bool]] = mapped_column( Boolean, nullable=True) # PRIMERTOTAL + type: Mapped[Optional[str]] = mapped_column( String(9), nullable=True) # TIPO + is_printed: Mapped[Optional[bool]] = mapped_column( Boolean, nullable=True) # SEIMPRIME + section: Mapped[Optional[int]] = mapped_column( Integer, nullable=True) # SECCION + classification: Mapped[Optional[str]] = mapped_column(String(30), ForeignKey( "a76.classification_concepts.classification"), nullable=True) # CLASIFICACION diff --git a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/dto.py b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/dto.py index 470de77a..30416dea 100644 --- a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/dto.py @@ -4,8 +4,7 @@ from pydantic import BaseModel, Field, ConfigDict class CustomsBrokerConceptBase(BaseModel): - broker_key: str = Field(..., max_length=5, - description="Customs Broker Key (CLAVEAA)") + broker_key: str = Field(..., max_length=5, description="Customs Broker Key (CLAVEAA)") concept: str = Field(..., max_length=15, description="Concept") amount: Optional[Decimal] = Field(None, description="Amount") priority: Optional[int] = Field(None, description="Priority") diff --git a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/models.py b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/models.py index f55c97c4..301e8d48 100644 --- a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/models.py @@ -9,17 +9,23 @@ from core.database import Base class CustomsBrokerConcept(Base, TenantScopedMixin, TimestampMixin): __tablename__ = "customs_broker_concepts" __table_args__ = ( - UniqueConstraint("broker_key", "concept", name="uq_broker_concept"), + UniqueConstraint("broker_key", "concept", "company_id", name="uq_broker_concept"), {"schema": "a76"} ) id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + + company_id: Mapped[int] = mapped_column(Integer, nullable=False) + broker_key: Mapped[str] = mapped_column( String(5), nullable=False) # CLAVEAA + concept: Mapped[str] = mapped_column( String(15), nullable=False) # CONCEPTO + amount: Mapped[Optional[Decimal]] = mapped_column( Numeric(11, 2), nullable=True) # IMPORTE + priority: Mapped[Optional[int]] = mapped_column( Integer, nullable=True) # PRIORIDAD diff --git a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/routes.py b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/routes.py index eeb5bfab..c8ec83ad 100644 --- a/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/routes.py +++ b/backend/api/v1/modules/a76/general_catalogs/customs_broker_concepts/routes.py @@ -7,7 +7,7 @@ router = TenantCRUDRoutes( create_schema=CustomsBrokerConceptCreate, update_schema=CustomsBrokerConceptUpdate, response_schema=CustomsBrokerConceptResponse, - prefix="/customs-broker-concepts", + prefix="/customs-broker-concepts", tags=["a76.general_catalogs.customs_broker_concepts"], resource_name="Customs Broker Concept", enable_list=True, diff --git a/backend/api/v1/modules/a76/general_catalogs/equivalencies/models.py b/backend/api/v1/modules/a76/general_catalogs/equivalencies/models.py index 7bcc724a..1d4b3d7c 100644 --- a/backend/api/v1/modules/a76/general_catalogs/equivalencies/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/equivalencies/models.py @@ -39,11 +39,15 @@ class EquivalencyItem(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + equivalency_id: Mapped[int] = mapped_column( Integer, ForeignKey("a76.equivalencies.id"), nullable=False) + original_field: Mapped[str] = mapped_column( String(100), nullable=False) # Relation to Unit of Measure + external_field: Mapped[str] = mapped_column(String(100), nullable=False) equivalency: Mapped["Equivalency"] = relationship(back_populates="items") + unit_of_measure: Mapped["UnitOfMeasure"] = relationship() diff --git a/backend/api/v1/modules/a76/general_catalogs/error_catalogs/models.py b/backend/api/v1/modules/a76/general_catalogs/error_catalogs/models.py index af8d053d..147770c3 100644 --- a/backend/api/v1/modules/a76/general_catalogs/error_catalogs/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/error_catalogs/models.py @@ -24,7 +24,8 @@ class ErrorClassification(Base, TenantScopedMixin, TimestampMixin): # Primary key id: Mapped[int] = mapped_column( - Integer, primary_key=True, autoincrement=True) + Integer, primary_key=True, autoincrement=True + ) # Classification code (unique) code: Mapped[str] = mapped_column(String(100), nullable=False, unique=True) @@ -60,7 +61,8 @@ class ErrorCatalog(Base, TenantScopedMixin, TimestampMixin): # Primary key id: Mapped[int] = mapped_column( - Integer, primary_key=True, autoincrement=True) + Integer, primary_key=True, autoincrement=True + ) # Error code (unique) code: Mapped[str] = mapped_column(String(15), nullable=False, unique=True) @@ -77,4 +79,4 @@ class ErrorCatalog(Base, TenantScopedMixin, TimestampMixin): ) def __repr__(self): - return f"" + return f"" \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/exchange_rate/models.py b/backend/api/v1/modules/a76/general_catalogs/exchange_rate/models.py index 5e9d95b4..92f8e4f7 100644 --- a/backend/api/v1/modules/a76/general_catalogs/exchange_rate/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/exchange_rate/models.py @@ -30,6 +30,9 @@ class ExchangeRate(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column(Integer, primary_key=True) date: Mapped[datetime] = mapped_column(DateTime) + value: Mapped[Optional[Decimal]] = mapped_column(DECIMAL(13, 6)) + local_currency: Mapped[Optional[str]] = mapped_column(String(7)) + foreign_currency: Mapped[Optional[str]] = mapped_column(String(7)) diff --git a/backend/api/v1/modules/a76/general_catalogs/identifiers/dto.py b/backend/api/v1/modules/a76/general_catalogs/identifiers/dto.py index 718da777..9432a023 100644 --- a/backend/api/v1/modules/a76/general_catalogs/identifiers/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/identifiers/dto.py @@ -1,9 +1,6 @@ from typing import Optional from pydantic import BaseModel, Field, ConfigDict -# Identifier DTOs - - class IdentifierBase(BaseModel): code: str = Field(..., max_length=2, description="Identifier Code (CLAVE)") description: Optional[str] = Field( @@ -11,28 +8,23 @@ class IdentifierBase(BaseModel): level: Optional[str] = Field(None, max_length=1, description="Level") complement: Optional[str] = Field( None, max_length=5000, description="Complement") - company_id: int = Field(..., description="Company ID") - class IdentifierCreate(IdentifierBase): pass - class IdentifierUpdate(BaseModel): code: Optional[str] = Field(None, max_length=2) description: Optional[str] = Field(None, max_length=1000) level: Optional[str] = Field(None, max_length=1) complement: Optional[str] = Field(None, max_length=5000) - class IdentifierResponse(IdentifierBase): id: int tenant_id: int + company_id: int model_config = ConfigDict(from_attributes=True) -# Identifier Detail DTOs - class IdentifierDetailBase(BaseModel): invoice_consecutive: Optional[int] = Field( @@ -47,13 +39,10 @@ class IdentifierDetailBase(BaseModel): None, max_length=51, description="Complement 2") complement3: Optional[str] = Field( None, max_length=50, description="Complement 3") - company_id: int = Field(..., description="Company ID") - class IdentifierDetailCreate(IdentifierDetailBase): pass - class IdentifierDetailUpdate(BaseModel): invoice_consecutive: Optional[int] = None part_line: Optional[int] = None @@ -63,9 +52,9 @@ class IdentifierDetailUpdate(BaseModel): complement2: Optional[str] = Field(None, max_length=51) complement3: Optional[str] = Field(None, max_length=50) - class IdentifierDetailResponse(IdentifierDetailBase): id: int tenant_id: int + company_id: int - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(from_attributes=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/identifiers/models.py b/backend/api/v1/modules/a76/general_catalogs/identifiers/models.py index 27174064..daabe759 100644 --- a/backend/api/v1/modules/a76/general_catalogs/identifiers/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/identifiers/models.py @@ -14,11 +14,15 @@ class Identifier(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + code: Mapped[str] = mapped_column(String(2), nullable=False) # CLAVE + description: Mapped[Optional[str]] = mapped_column( String(1000), nullable=True) # DESCRIPCION + level: Mapped[Optional[str]] = mapped_column( String(1), nullable=True) # NIVEL + complement: Mapped[Optional[str]] = mapped_column( String(5000), nullable=True) # COMPLEMENTO diff --git a/backend/api/v1/modules/a76/general_catalogs/inpc/dto.py b/backend/api/v1/modules/a76/general_catalogs/inpc/dto.py index 7718a927..72afc5c6 100644 --- a/backend/api/v1/modules/a76/general_catalogs/inpc/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/inpc/dto.py @@ -2,7 +2,6 @@ from typing import Optional from decimal import Decimal from pydantic import BaseModel, Field, ConfigDict - class INPCBase(BaseModel): year: str = Field(..., max_length=4, description="Year (YYYY)") month: str = Field(..., max_length=2, description="Month (MM)") @@ -12,7 +11,6 @@ class INPCBase(BaseModel): class INPCCreate(INPCBase): pass - class INPCUpdate(BaseModel): year: Optional[str] = Field(None, max_length=4) month: Optional[str] = Field(None, max_length=2) @@ -21,5 +19,7 @@ class INPCUpdate(BaseModel): class INPCResponse(INPCBase): id: int + tenant_id: int + company_id: int - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(from_attributes=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/inpc/models.py b/backend/api/v1/modules/a76/general_catalogs/inpc/models.py index 7a41d26b..65e79049 100644 --- a/backend/api/v1/modules/a76/general_catalogs/inpc/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/inpc/models.py @@ -16,7 +16,10 @@ class INPC(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + year: Mapped[str] = mapped_column(String(4), nullable=False) # ANIO + month: Mapped[str] = mapped_column(String(2), nullable=False) # MES + value: Mapped[Optional[Decimal]] = mapped_column( Numeric(19, 8), nullable=True) # VALOR diff --git a/backend/api/v1/modules/a76/general_catalogs/inpc/routes.py b/backend/api/v1/modules/a76/general_catalogs/inpc/routes.py index dd2b6cdb..a91b276d 100644 --- a/backend/api/v1/modules/a76/general_catalogs/inpc/routes.py +++ b/backend/api/v1/modules/a76/general_catalogs/inpc/routes.py @@ -1,20 +1,16 @@ -from fastapi import APIRouter from api.v1.common.tenant_crud_routes import TenantCRUDRoutes from .models import INPC from .dto import INPCCreate, INPCResponse, INPCUpdate from .service import INPCService -router = APIRouter(prefix="/inpc", tags=["a76.general_catalogs.inpc"]) - -inpc_crud = TenantCRUDRoutes( +# Usamos TenantCRUDRoutes directamente +router = TenantCRUDRoutes( service=INPCService, create_schema=INPCCreate, update_schema=INPCUpdate, response_schema=INPCResponse, - prefix="", - tags=["INPC"], + prefix="/inpc", + tags=["a76.general_catalogs.inpc"], resource_name="INPC", enable_list=True, -) - -router.include_router(inpc_crud.router) +).router \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/legends/dto.py b/backend/api/v1/modules/a76/general_catalogs/legends/dto.py index c3900566..2f3b9570 100644 --- a/backend/api/v1/modules/a76/general_catalogs/legends/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/legends/dto.py @@ -21,3 +21,5 @@ class LegendResponse(LegendBase): id: int model_config = ConfigDict(from_attributes=True) + tenant_id : int + company_id : int diff --git a/backend/api/v1/modules/a76/general_catalogs/legends/models.py b/backend/api/v1/modules/a76/general_catalogs/legends/models.py index eaea60a1..f6ea4591 100644 --- a/backend/api/v1/modules/a76/general_catalogs/legends/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/legends/models.py @@ -15,6 +15,8 @@ class Legend(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + code: Mapped[int] = mapped_column(Integer, nullable=False) # CLAVELEY + description: Mapped[Optional[str]] = mapped_column( String(2000), nullable=True) # DESCLEYENDA diff --git a/backend/api/v1/modules/a76/general_catalogs/legends/routes.py b/backend/api/v1/modules/a76/general_catalogs/legends/routes.py index e053c4d5..92f4a64b 100644 --- a/backend/api/v1/modules/a76/general_catalogs/legends/routes.py +++ b/backend/api/v1/modules/a76/general_catalogs/legends/routes.py @@ -11,7 +11,7 @@ legend_crud = TenantCRUDRoutes( create_schema=LegendCreate, update_schema=LegendUpdate, response_schema=LegendResponse, - prefix="", + prefix="/legends", tags=["Legends"], resource_name="Legend", enable_list=True, diff --git a/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/dto.py b/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/dto.py index 6bbdfe9c..b76b798f 100644 --- a/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/dto.py @@ -27,5 +27,7 @@ class MultiCurrencyTypeUpdate(BaseModel): class MultiCurrencyTypeResponse(MultiCurrencyTypeBase): id: int - + company_id: int + tenant_id: int + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/models.py b/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/models.py index 91751a9a..e119b8b8 100644 --- a/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/multi_currency_types/models.py @@ -18,13 +18,18 @@ class MultiCurrencyType(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + currency_type_code: Mapped[str] = mapped_column( String(3), ForeignKey("public.currency_types.code"), nullable=False) + country_key: Mapped[Optional[str]] = mapped_column( String(3), ForeignKey("public.countries.m3_key"), nullable=True) + conversion_factor: Mapped[Optional[Decimal]] = mapped_column( Numeric(13, 6), nullable=True) + publication_date: Mapped[int] = mapped_column(Integer, nullable=False) currency_type: Mapped["CurrencyType"] = relationship() + country: Mapped[Optional["Country"]] = relationship() diff --git a/backend/api/v1/modules/a76/general_catalogs/packages/models.py b/backend/api/v1/modules/a76/general_catalogs/packages/models.py index 98e560d3..f191fa94 100644 --- a/backend/api/v1/modules/a76/general_catalogs/packages/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/packages/models.py @@ -31,4 +31,4 @@ class Package(Base, TenantScopedMixin, TimestampMixin): plurals: Mapped[Optional[str]] = mapped_column(String(4)) plural_in: Mapped[Optional[str]] = mapped_column(String(4)) code_ace: Mapped[Optional[str]] = mapped_column(String(4)) - code_aamex: Mapped[Optional[str]] = mapped_column(String(9)) + code_aamex: Mapped[Optional[str]] = mapped_column(String(9)) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/signatures/dto.py b/backend/api/v1/modules/a76/general_catalogs/signatures/dto.py index 4524f91c..aeee8ca3 100644 --- a/backend/api/v1/modules/a76/general_catalogs/signatures/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/signatures/dto.py @@ -11,6 +11,7 @@ class SignatureCreateDTO(BaseModel): """DTO para crear una firma""" code: str = Field(..., max_length=10, description="Signature code") + signature: Optional[str] = Field( None, max_length=1000, description="Signature") photo_path: Optional[str] = Field( @@ -39,6 +40,8 @@ class SignatureResponseDTO(BaseModel): code: str signature: Optional[str] = None photo_path: Optional[str] = None + intenant_id: int + company_id: int class Config: from_attributes = True diff --git a/backend/api/v1/modules/a76/general_catalogs/signatures/models.py b/backend/api/v1/modules/a76/general_catalogs/signatures/models.py index e3d04b63..0885a276 100644 --- a/backend/api/v1/modules/a76/general_catalogs/signatures/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/signatures/models.py @@ -32,6 +32,7 @@ class Signature(Base, TenantScopedMixin, TimestampMixin): # Signature information signature: Mapped[Optional[str]] = mapped_column(String(1000)) + photo_path: Mapped[Optional[str]] = mapped_column(String(1000)) def __repr__(self): diff --git a/backend/api/v1/modules/a76/general_catalogs/unit_conversions/dto.py b/backend/api/v1/modules/a76/general_catalogs/unit_conversions/dto.py index 85fd2ad9..0bb41aed 100644 --- a/backend/api/v1/modules/a76/general_catalogs/unit_conversions/dto.py +++ b/backend/api/v1/modules/a76/general_catalogs/unit_conversions/dto.py @@ -2,27 +2,23 @@ from typing import Optional from decimal import Decimal from pydantic import BaseModel, Field, ConfigDict - class UnitConversionBase(BaseModel): - from_unit_code: str = Field(..., max_length=5, - description="Source Unit Code") - to_unit_code: str = Field(..., max_length=5, - description="Target Unit Code") - conversion_factor: Optional[Decimal] = Field( - None, description="Conversion Factor") - + # 👇 OJO: Son códigos (Strings), no IDs + from_unit_code: str = Field(..., max_length=5, description="Source Unit Code") + to_unit_code: str = Field(..., max_length=5, description="Target Unit Code") + conversion_factor: Optional[Decimal] = Field(None, description="Conversion Factor") class UnitConversionCreate(UnitConversionBase): pass - class UnitConversionUpdate(BaseModel): from_unit_code: Optional[str] = Field(None, max_length=5) to_unit_code: Optional[str] = Field(None, max_length=5) conversion_factor: Optional[Decimal] = None - class UnitConversionResponse(UnitConversionBase): id: int + tenant_id: int + company_id: int - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(from_attributes=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/general_catalogs/unit_conversions/models.py b/backend/api/v1/modules/a76/general_catalogs/unit_conversions/models.py index 65122a4c..26893749 100644 --- a/backend/api/v1/modules/a76/general_catalogs/unit_conversions/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/unit_conversions/models.py @@ -27,8 +27,11 @@ class UnitConversion(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True) + from_unit_code: Mapped[str] = mapped_column(String(5), nullable=False) + to_unit_code: Mapped[str] = mapped_column(String(5), nullable=False) + conversion_factor: Mapped[Optional[Decimal]] = mapped_column( Numeric(13, 6), nullable=True) diff --git a/backend/api/v1/modules/a76/general_catalogs/units_of_measure/models.py b/backend/api/v1/modules/a76/general_catalogs/units_of_measure/models.py index 04cae220..ffd359db 100644 --- a/backend/api/v1/modules/a76/general_catalogs/units_of_measure/models.py +++ b/backend/api/v1/modules/a76/general_catalogs/units_of_measure/models.py @@ -181,4 +181,4 @@ class UnitOfMeasureGeneral(Base, TenantScopedMixin, TimestampMixin): String(4), nullable=True) # CLAVEACE customs_unit: Mapped[Optional["UnitOfMeasureCustoms"]] = relationship() - ace_unit: Mapped[Optional["UnitOfMeasureACE"]] = relationship() + ace_unit: Mapped[Optional["UnitOfMeasureACE"]] = relationship(overlaps="customs_unit") diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/classification-concepts.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/classification-concepts.ts index 6179c188..984cc4c0 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/classification-concepts.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/classification-concepts.ts @@ -2,60 +2,71 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface ClassificationConcept { - id: number; - classification: string; - description?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + classification: string; + tenant_id: number; + company_id: number; + created_at: string; + updated_at?: string; } export interface ClassificationConceptCreate { - classification: string; - description?: string; + classification: string; } export interface ClassificationConceptUpdate extends Partial {} export interface ClassificationConceptListResponse { - items: ClassificationConcept[]; - total: number; - page: number; - page_size: number; - pages: number; + items: ClassificationConcept[]; + total: number; + page: number; + page_size: number; + pages: number; } export async function getClassificationConcepts( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/classification_concepts?${params.toString()}`); - return response.data; + + const response = await api.get(`/v1/a76/classification-concepts/?${params.toString()}`); + return response.data; } -export async function getClassificationConcept(id: number): Promise { - const response = await api.get(`/a76/classification_concepts/${id}`); - return response.data; +export async function getClassificationConcept(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/classification-concepts/${id}/?company_id=${companyId}`); + return response.data; } -export async function createClassificationConcept(data: ClassificationConceptCreate): Promise { - const response = await api.post('/a76/classification_concepts', data); - return response.data; +export async function createClassificationConcept( + data: ClassificationConceptCreate, + companyId: number +): Promise { + // 👇 AQUÍ ESTABA EL ERROR GRAVE + const response = await api.post(`/v1/a76/classification-concepts/?company_id=${companyId}`, data); + return response.data; } -export async function updateClassificationConcept(id: number, data: ClassificationConceptUpdate): Promise { - const response = await api.patch(`/a76/classification_concepts/${id}`, data); - return response.data; + +export async function updateClassificationConcept( + id: number, + data: ClassificationConceptUpdate, + companyId: number // <-- Faltaba esto +): Promise { + const response = await api.put(`/v1/a76/classification-concepts/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteClassificationConcept(id: number): Promise { - await api.delete(`/a76/classification_concepts/${id}`); -} + +export async function deleteClassificationConcept(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/classification-concepts/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/company.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/company.ts index 3806c386..05f4682f 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/company.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/company.ts @@ -1,91 +1,91 @@ -import { api } from '$lib/api'; -import type { ApiResponse } from '$lib/api'; + import { api } from '$lib/api'; + import type { ApiResponse } from '$lib/api'; -export interface Company { - id: number; - tenant_id: number; - name: string | null; - rfc: string | null; - main_activity: string | null; - program: string | null; - program_number: string | null; - prosec: number | null; - prosec_authorization: string | null; - manufacturer_id: string | null; - broker_company: string | null; - responsible: string | null; - responsible_name: string | null; - responsible_last_name: string | null; - responsible_mother_last_name: string | null; - created_at: string | null; - updated_at: string | null; -} + export interface Company { + id: number; + tenant_id: number; + name: string | null; + rfc: string | null; + main_activity: string | null; + program: string | null; + program_number: string | null; + prosec: number | null; + prosec_authorization: string | null; + manufacturer_id: string | null; + broker_company: string | null; + responsible: string | null; + responsible_name: string | null; + responsible_last_name: string | null; + responsible_mother_last_name: string | null; + created_at: string | null; + updated_at: string | null; + } -export interface CompanyCreate { - name?: string | null; - rfc?: string | null; - main_activity?: string | null; - program?: string | null; - program_number?: string | null; - prosec?: number | null; - prosec_authorization?: string | null; - manufacturer_id?: string | null; - broker_company?: string | null; - responsible?: string | null; - responsible_name?: string | null; - responsible_last_name?: string | null; - responsible_mother_last_name?: string | null; -} + export interface CompanyCreate { + name?: string | null; + rfc?: string | null; + main_activity?: string | null; + program?: string | null; + program_number?: string | null; + prosec?: number | null; + prosec_authorization?: string | null; + manufacturer_id?: string | null; + broker_company?: string | null; + responsible?: string | null; + responsible_name?: string | null; + responsible_last_name?: string | null; + responsible_mother_last_name?: string | null; + } -export interface CompanyUpdate { - name?: string | null; - rfc?: string | null; - main_activity?: string | null; - program?: string | null; - program_number?: string | null; - prosec?: number | null; - prosec_authorization?: string | null; - manufacturer_id?: string | null; - broker_company?: string | null; - responsible?: string | null; - responsible_name?: string | null; - responsible_last_name?: string | null; - responsible_mother_last_name?: string | null; -} + export interface CompanyUpdate { + name?: string | null; + rfc?: string | null; + main_activity?: string | null; + program?: string | null; + program_number?: string | null; + prosec?: number | null; + prosec_authorization?: string | null; + manufacturer_id?: string | null; + broker_company?: string | null; + responsible?: string | null; + responsible_name?: string | null; + responsible_last_name?: string | null; + responsible_mother_last_name?: string | null; + } -export interface CompanyListResponse { - items: Company[]; - total: number; - page: number; - page_size: number; - pages: number; -} + export interface CompanyListResponse { + items: Company[]; + total: number; + page: number; + page_size: number; + pages: number; + } -export async function getCompanies( - page = 1, - pageSize = 50, - filters: Record = {} -): Promise> { - const queryParams = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); - return await api.get(`/a76/company?${queryParams.toString()}`); -} + export async function getCompanies( + page = 1, + pageSize = 50, + filters: Record = {} + ): Promise> { + const queryParams = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + return await api.get(`/a76/company?${queryParams.toString()}`); + } -export async function getCompany(id: number): Promise> { - return await api.get(`/a76/company/${id}`); -} + export async function getCompany(id: number): Promise> { + return await api.get(`/a76/company/${id}`); + } -export async function createCompany(data: CompanyCreate): Promise> { - return await api.post(`/a76/company`, data); -} + export async function createCompany(data: CompanyCreate): Promise> { + return await api.post(`/v1/a76/company`, data); + } -export async function updateCompany(id: number, data: CompanyUpdate): Promise> { - return await api.put(`/a76/company/${id}`, data); -} + export async function updateCompany(id: number, data: CompanyUpdate): Promise> { + return await api.put(`/a76/company/${id}`, data); + } -export async function deleteCompany(id: number): Promise> { - return await api.delete(`/a76/company/${id}`); -} + export async function deleteCompany(id: number): Promise> { + return await api.delete(`/a76/company/${id}`); + } diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/concepts.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/concepts.ts index aa723d72..2371e1c4 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/concepts.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/concepts.ts @@ -2,78 +2,88 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface Concept { - id: number; - code: string; - description?: string; - description_en?: string; - detailed_description?: string; - priority?: number; - priority_ame?: number; - first_total?: boolean; - type?: string; - is_printed?: boolean; - section?: number; - classification?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + code: string; + description?: string; + description_en?: string; + detailed_description?: string; + priority?: number; + priority_ame?: number; + first_total?: boolean; + type?: string; + is_printed?: boolean; + section?: number; + classification?: string; + tenant_id: string; + company_id?: string; + created_at: string; + updated_at?: string; } export interface ConceptCreate { - code: string; - description?: string; - description_en?: string; - detailed_description?: string; - priority?: number; - priority_ame?: number; - first_total?: boolean; - type?: string; - is_printed?: boolean; - section?: number; - classification?: string; + code: string; + description?: string; + description_en?: string; + detailed_description?: string; + priority?: number; + priority_ame?: number; + first_total?: boolean; + type?: string; + is_printed?: boolean; + section?: number; + classification?: string; } export interface ConceptUpdate extends Partial {} export interface ConceptListResponse { - items: Concept[]; - total: number; - page: number; - page_size: number; - pages: number; + items: Concept[]; + total: number; + page: number; + page_size: number; + pages: number; } export async function getConcepts( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {}, ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/concepts?${params.toString()}`); - return response.data; + const response = await api.get(`/v1/a76/concepts/?${params.toString()}`); + return response.data; } -export async function getConcept(id: number): Promise { - const response = await api.get(`/a76/concepts/${id}`); - return response.data; + +export async function getConcept(id: number, companyId: number): Promise { + + const response = await api.get(`/v1/a76/concepts/${id}/?company_id=${companyId}`); + return response.data; } -export async function createConcept(data: ConceptCreate): Promise { - const response = await api.post('/a76/concepts', data); - return response.data; + +export async function createConcept(data: ConceptCreate, companyId: number): Promise { + + const response = await api.post(`/v1/a76/concepts/?company_id=${companyId}`, data); + return response.data; } -export async function updateConcept(id: number, data: ConceptUpdate): Promise { - const response = await api.patch(`/a76/concepts/${id}`, data); - return response.data; + +export async function updateConcept(id: number, data: ConceptUpdate, companyId: number): Promise { + + const response = await api.put(`/v1/a76/concepts/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteConcept(id: number): Promise { - await api.delete(`/a76/concepts/${id}`); -} + +export async function deleteConcept(id: number, companyId: number): Promise { + + await api.delete(`/v1/a76/concepts/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/customs-broker-concepts.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/customs-broker-concepts.ts index 5e296fb8..3e40b598 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/customs-broker-concepts.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/customs-broker-concepts.ts @@ -2,76 +2,68 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface CustomsBrokerConcept { - id: number; - code: string; - description?: string; - description_en?: string; - detailed_description?: string; - priority?: number; - first_total?: boolean; - type?: string; - is_printed?: boolean; - section?: number; - classification?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + broker_key: string; + concept: string; + amount?: number; + priority?: number; } export interface CustomsBrokerConceptCreate { - code: string; - description?: string; - description_en?: string; - detailed_description?: string; - priority?: number; - first_total?: boolean; - type?: string; - is_printed?: boolean; - section?: number; - classification?: string; + broker_key: string; + concept?: string; + amount?: number; + priority?: number; } export interface CustomsBrokerConceptUpdate extends Partial {} export interface CustomsBrokerConceptListResponse { - items: CustomsBrokerConcept[]; - total: number; - page: number; - page_size: number; - pages: number; + items: CustomsBrokerConcept[]; + total: number; + page: number; + page_size: number; + pages: number; } + export async function getCustomsBrokerConcepts( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, // <-- Nuevo + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/customs_broker_concepts?${params.toString()}`); - return response.data; + + const response = await api.get(`/v1/a76/customs-broker-concepts/?${params.toString()}`); + return response.data; } -export async function getCustomsBrokerConcept(id: number): Promise { - const response = await api.get(`/a76/customs_broker_concepts/${id}`); - return response.data; +export async function createCustomsBrokerConcept( + data: CustomsBrokerConceptCreate, + companyId: number +): Promise { + + const response = await api.post(`/v1/a76/customs-broker-concepts/?company_id=${companyId}`, data); + return response.data; } -export async function createCustomsBrokerConcept(data: CustomsBrokerConceptCreate): Promise { - const response = await api.post('/a76/customs_broker_concepts', data); - return response.data; +export async function updateCustomsBrokerConcept( + id: number, + data: CustomsBrokerConceptUpdate, + companyId: number +): Promise { + + const response = await api.put(`/v1/a76/customs-broker-concepts/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function updateCustomsBrokerConcept(id: number, data: CustomsBrokerConceptUpdate): Promise { - const response = await api.patch(`/a76/customs_broker_concepts/${id}`, data); - return response.data; -} - -export async function deleteCustomsBrokerConcept(id: number): Promise { - await api.delete(`/a76/customs_broker_concepts/${id}`); -} +export async function deleteCustomsBrokerConcept(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/customs-broker-concepts/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/error-catalogs.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/error-catalogs.ts index 994caa7f..b5dc471d 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/error-catalogs.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/error-catalogs.ts @@ -1,61 +1,134 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; +// ========================================== +// ERROR CLASSIFICATION +// ========================================== + +export interface ErrorClassification { + id: number; + code: string; + level?: string; + errors?: ErrorCatalog[]; + tenant_id?: string; + created_at?: string; + updated_at?: string; +} + +export interface ErrorClassificationCreate { + code: string; + level?: string; +} + +export interface ErrorClassificationUpdate { + level?: string; +} + +export interface ErrorClassificationListResponse { + items: ErrorClassification[]; + total: number; + page: number; + page_size: number; + pages: number; +} + + export interface ErrorCatalog { - id: number; - code: string; - description?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + code: string; + description?: string; + classification_id?: number; + classification?: ErrorClassification; + tenant_id?: string; + created_at?: string; + updated_at?: string; } export interface ErrorCatalogCreate { - code: string; - description?: string; + code: string; + description?: string; + classification_id?: number; } -export interface ErrorCatalogUpdate extends Partial {} +export interface ErrorCatalogUpdate { + description?: string; + classification_id?: number; +} export interface ErrorCatalogListResponse { - items: ErrorCatalog[]; - total: number; - page: number; - page_size: number; - pages: number; + items: ErrorCatalog[]; + total: number; + page: number; + page_size: number; + pages: number; } -export async function getErrorCatalogs( - page: number = 1, - pageSize: number = 50, - filters: Record = {} -): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); +export async function getErrorClassifications( + page: number = 1, + pageSize: number = 50, + filters: Record = {} +): Promise> { + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); - const response = await api.get(`/a76/error_catalogs?${params.toString()}`); - return response.data; + const response = await api.get(`/a76/error_classifications?${params.toString()}`); + return response.data; +} + +export async function getErrorClassification(id: number): Promise { + const response = await api.get(`/a76/error_classifications/${id}`); + return response.data; +} + +export async function createErrorClassification(data: ErrorClassificationCreate): Promise { + const response = await api.post('/a76/error_classifications', data); + return response.data; +} + +export async function updateErrorClassification(id: number, data: ErrorClassificationUpdate): Promise { + const response = await api.patch(`/a76/error_classifications/${id}`, data); + return response.data; +} + +export async function deleteErrorClassification(id: number): Promise { + await api.delete(`/a76/error_classifications/${id}`); +} + +// --- Catalogs --- + +export async function getErrorCatalogs( + page: number = 1, + pageSize: number = 50, + filters: Record = {} +): Promise> { + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters + }); + + const response = await api.get(`/a76/error_catalogs?${params.toString()}`); + return response.data; } export async function getErrorCatalog(id: number): Promise { - const response = await api.get(`/a76/error_catalogs/${id}`); - return response.data; + const response = await api.get(`/a76/error_catalogs/${id}`); + return response.data; } export async function createErrorCatalog(data: ErrorCatalogCreate): Promise { - const response = await api.post('/a76/error_catalogs', data); - return response.data; + const response = await api.post('/a76/error_catalogs', data); + return response.data; } export async function updateErrorCatalog(id: number, data: ErrorCatalogUpdate): Promise { - const response = await api.patch(`/a76/error_catalogs/${id}`, data); - return response.data; + const response = await api.patch(`/a76/error_catalogs/${id}`, data); + return response.data; } export async function deleteErrorCatalog(id: number): Promise { - await api.delete(`/a76/error_catalogs/${id}`); -} + await api.delete(`/a76/error_catalogs/${id}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/identifiers.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/identifiers.ts index 5a2ca8d3..98660069 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/identifiers.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/identifiers.ts @@ -7,8 +7,8 @@ export interface Identifier { description: string | null; level: string | null; complement: string | null; - company_id: number; - tenant_id: number; + company_id: number; + tenant_id: number; created_at: string | null; updated_at: string | null; } @@ -18,7 +18,6 @@ export interface IdentifierCreate { description?: string | null; level?: string | null; complement?: string | null; - company_id: number; } export interface IdentifierUpdate { @@ -39,24 +38,37 @@ export interface IdentifierListResponse { export async function getIdentifiers( page = 1, pageSize = 50, + companyId: number, filters: Record = {} ): Promise> { const queryParams = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), + company_id: companyId.toString(), ...filters }); - return await api.get(`/a76/identifiers?${queryParams.toString()}`); + + return await api.get(`/v1/a76/identifiers/?${queryParams.toString()}`); } -export async function createIdentifier(data: IdentifierCreate): Promise> { - return await api.post('/a76/identifiers', data); +export async function createIdentifier( + data: IdentifierCreate, + companyId: number +): Promise> { + return await api.post(`/v1/a76/identifiers/?company_id=${companyId}`, data); } -export async function updateIdentifier(id: number, data: IdentifierUpdate): Promise> { - return await api.put(`/a76/identifiers/${id}`, data); +export async function updateIdentifier( + id: number, + data: IdentifierUpdate, + companyId: number +): Promise> { + return await api.put(`/v1/a76/identifiers/${id}/?company_id=${companyId}`, data); } -export async function deleteIdentifier(id: number): Promise> { - return await api.delete(`/a76/identifiers/${id}`); -} +export async function deleteIdentifier( + id: number, + companyId: number +): Promise> { + return await api.delete(`/v1/a76/identifiers/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/inpc.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/inpc.ts index 95f5d8c4..1abb0359 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/inpc.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/inpc.ts @@ -2,62 +2,77 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface INPC { - id: number; - year: string; - month: string; - value?: number; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + year: string; + month: string; + value?: number; + tenant_id: number; + company_id: number; + created_at: string; + updated_at?: string; } export interface INPCCreate { - year: string; - month: string; - value?: number; + year: string; + month: string; + value?: number; + } export interface INPCUpdate extends Partial {} export interface INPCListResponse { - items: INPC[]; - total: number; - page: number; - page_size: number; - pages: number; + items: INPC[]; + total: number; + page: number; + page_size: number; + pages: number; } + export async function getINPCs( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/inpc?${params.toString()}`); - return response.data; + const response = await api.get(`/v1/a76/inpc/?${params.toString()}`); + return response.data; } -export async function getINPC(id: number): Promise { - const response = await api.get(`/a76/inpc/${id}`); - return response.data; + +export async function getINPC(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/inpc/${id}/?company_id=${companyId}`); + return response.data; } -export async function createINPC(data: INPCCreate): Promise { - const response = await api.post('/a76/inpc', data); - return response.data; + +export async function createINPC( + data: INPCCreate, + companyId: number +): Promise { + const response = await api.post(`/v1/a76/inpc/?company_id=${companyId}`, data); + return response.data; } -export async function updateINPC(id: number, data: INPCUpdate): Promise { - const response = await api.patch(`/a76/inpc/${id}`, data); - return response.data; + +export async function updateINPC( + id: number, + data: INPCUpdate, + companyId: number +): Promise { + + const response = await api.put(`/v1/a76/inpc/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteINPC(id: number): Promise { - await api.delete(`/a76/inpc/${id}`); -} +export async function deleteINPC(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/inpc/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/legends.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/legends.ts index d04317a6..989f8d37 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/legends.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/legends.ts @@ -2,60 +2,71 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface Legend { - id: number; - code: string; - description?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + code: number; + description?: string; + tenant_id: number; + company_id: number; + created_at: string; + updated_at?: string; } export interface LegendCreate { - code: string; - description?: string; + code: number; + description?: string; } export interface LegendUpdate extends Partial {} export interface LegendListResponse { - items: Legend[]; - total: number; - page: number; - page_size: number; - pages: number; + items: Legend[]; + total: number; + page: number; + page_size: number; + pages: number; } export async function getLegends( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); - - const response = await api.get(`/a76/legends?${params.toString()}`); - return response.data; + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); + const response = await api.get(`/v1/a76/legends/?${params.toString()}`); + return response.data; } -export async function getLegend(id: number): Promise { - const response = await api.get(`/a76/legends/${id}`); - return response.data; +export async function getLegend(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/legends/${id}/?company_id=${companyId}`); + return response.data; } -export async function createLegend(data: LegendCreate): Promise { - const response = await api.post('/a76/legends', data); - return response.data; + +export async function createLegend( + data: LegendCreate, + companyId: number +): Promise { + + const response = await api.post(`/v1/a76/legends/?company_id=${companyId}`, data); + return response.data; } -export async function updateLegend(id: number, data: LegendUpdate): Promise { - const response = await api.patch(`/a76/legends/${id}`, data); - return response.data; +export async function updateLegend( + id: number, + data: LegendUpdate, + companyId: number +): Promise { + + const response = await api.put(`/v1/a76/legends/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteLegend(id: number): Promise { - await api.delete(`/a76/legends/${id}`); -} +export async function deleteLegend(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/legends/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts index 888e6f98..25426fa8 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/locations.ts @@ -1,52 +1,69 @@ -/** - * API Client para Locations - Ubicaciones relacionadas con puertos - * Basado en los campos location_code y location_description del módulo de puertos - */ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface Location { - location_code: string; - location_description: string | null; + id: number; + code: string; + description?: string; + + + tenant_id?: string; + created_at?: string; + updated_at?: string; } -/** - * Nota: Las ubicaciones están integradas en el módulo de puertos. - * Este archivo proporciona tipos para trabajar con ubicaciones, - * pero las operaciones se realizan a través del módulo de puertos. - * - * Ver: /a76/ports para operaciones relacionadas con ubicaciones - */ -/** - * Obtiene ubicaciones únicas de los puertos - * Esta función extrae las ubicaciones únicas de la lista de puertos - */ -export async function getLocationsFromPorts(): Promise> { - const portsResponse = await api.get('/a76/ports?page_size=1000'); - - if (portsResponse.error || !portsResponse.data) { - return { - error: portsResponse.error || 'Error al obtener puertos', - status: portsResponse.status - }; - } +export interface LocationCreate { + code: string; + description?: string; +} - // Extraer ubicaciones únicas - const locationMap = new Map(); - const ports = portsResponse.data.items || []; - - ports.forEach((port: any) => { - if (port.location_code && !locationMap.has(port.location_code)) { - locationMap.set(port.location_code, { - location_code: port.location_code, - location_description: port.location_description - }); - } + +export interface LocationUpdate { + code?: string; + description?: string; +} + +export interface LocationListResponse { + items: Location[]; + total: number; + page: number; + page_size: number; + pages: number; +} + + + +export async function getLocations( + page: number = 1, + pageSize: number = 50, + filters: Record = {} +): Promise> { + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + ...filters }); - return { - data: Array.from(locationMap.values()), - status: 200 - }; + const response = await api.get(`/a24/locations?${params.toString()}`); + return response.data; } + +export async function getLocation(id: number): Promise { + const response = await api.get(`/a24/locations/${id}`); + return response.data; +} + +export async function createLocation(data: LocationCreate): Promise { + const response = await api.post('/a24/locations', data); + return response.data; +} + +export async function updateLocation(id: number, data: LocationUpdate): Promise { + const response = await api.patch(`/a24/locations/${id}`, data); + return response.data; +} + +export async function deleteLocation(id: number): Promise { + await api.delete(`/a24/locations/${id}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts index d944b8c7..630a1185 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts @@ -2,60 +2,78 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface MultiCurrencyType { - id: number; - key: string; - description?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + + currency_type_code: string; + country_key: string | null; + conversion_factor: number | null; + publication_date: number; + tenant_id: number; + company_id: number; + created_at: string; + updated_at?: string; } export interface MultiCurrencyTypeCreate { - key: string; - description?: string; + currency_type_code: string; + country_key?: string | null; + conversion_factor?: number | null; + publication_date: number; } export interface MultiCurrencyTypeUpdate extends Partial {} export interface MultiCurrencyTypeListResponse { - items: MultiCurrencyType[]; - total: number; - page: number; - page_size: number; - pages: number; + items: MultiCurrencyType[]; + total: number; + page: number; + page_size: number; + pages: number; } export async function getMultiCurrencyTypes( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/multi_currency_types?${params.toString()}`); - return response.data; + // Agregamos /v1 y el path correcto + const response = await api.get(`/v1/a76/multi_currency_types/?${params.toString()}`); + return response.data; } -export async function getMultiCurrencyType(id: number): Promise { - const response = await api.get(`/a76/multi_currency_types/${id}`); - return response.data; + +export async function getMultiCurrencyType(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/multi_currency_types/${id}/?company_id=${companyId}`); + return response.data; } -export async function createMultiCurrencyType(data: MultiCurrencyTypeCreate): Promise { - const response = await api.post('/a76/multi_currency_types', data); - return response.data; +export async function createMultiCurrencyType( + data: MultiCurrencyTypeCreate, + companyId: number +): Promise { + const response = await api.post(`/v1/a76/multi_currency_types/?company_id=${companyId}`, data); + return response.data; } -export async function updateMultiCurrencyType(id: number, data: MultiCurrencyTypeUpdate): Promise { - const response = await api.patch(`/a76/multi_currency_types/${id}`, data); - return response.data; + +export async function updateMultiCurrencyType( + id: number, + data: MultiCurrencyTypeUpdate, + companyId: number +): Promise { + const response = await api.put(`/v1/a76/multi_currency_types/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteMultiCurrencyType(id: number): Promise { - await api.delete(`/a76/multi_currency_types/${id}`); -} + +export async function deleteMultiCurrencyType(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/multi_currency_types/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/packages.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/packages.ts index 7af320b2..49e620ca 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/packages.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/packages.ts @@ -4,17 +4,17 @@ import type { ApiResponse } from '$lib/api'; export interface Package { id: number; tenant_id: number; - company_id: number; - key: string; - description_es: string | null; - description_en: string | null; - weight_unit: number | null; - plurals: string | null; - plural_in: string | null; - code_ace: string | null; - code_aamex: string | null; - created_at: string | null; - updated_at: string | null; + company_id: number; + key: string; + description_es: string | null; + description_en: string | null; + weight_unit: number | null; + plurals: string | null; + plural_in: string | null; + code_ace: string | null; + code_aamex: string | null; + created_at: string; + updated_at?: string; } export interface PackageCreate { @@ -26,19 +26,9 @@ export interface PackageCreate { plural_in?: string | null; code_ace?: string | null; code_aamex?: string | null; - company_id: number; } -export interface PackageUpdate { - key?: string; - description_es?: string | null; - description_en?: string | null; - weight_unit?: number | null; - plurals?: string | null; - plural_in?: string | null; - code_ace?: string | null; - code_aamex?: string | null; -} +export interface PackageUpdate extends Partial {} export interface PackageListResponse { items: Package[]; @@ -48,31 +38,48 @@ export interface PackageListResponse { pages: number; } + export async function getPackages( - page = 1, - pageSize = 50, + page: number = 1, + pageSize: number = 50, + companyId: number, // Obligatorio por el Mixin filters: Record = {} ): Promise> { - const queryParams = new URLSearchParams({ + const params = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString(), + company_id: companyId.toString(), ...filters }); - return await api.get(`/a76/packages?${queryParams.toString()}`); + + const response = await api.get(`/v1/a76/packages/?${params.toString()}`); + return response.data; } -export async function getPackage(id: number): Promise> { - return await api.get(`/a76/packages/${id}`); + +export async function getPackage(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/packages/${id}/?company_id=${companyId}`); + return response.data; } -export async function createPackage(data: PackageCreate): Promise> { - return await api.post(`/a76/packages`, data); +export async function createPackage( + data: PackageCreate, + companyId: number +): Promise { + const response = await api.post(`/v1/a76/packages/?company_id=${companyId}`, data); + return response.data; } -export async function updatePackage(id: number, data: PackageUpdate): Promise> { - return await api.put(`/a76/packages/${id}`, data); + +export async function updatePackage( + id: number, + data: PackageUpdate, + companyId: number +): Promise { + const response = await api.put(`/v1/a76/packages/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deletePackage(id: number): Promise> { - return await api.delete(`/a76/packages/${id}`); -} +export async function deletePackage(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/packages/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/signatures.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/signatures.ts index 60073763..1d22184f 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/signatures.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/signatures.ts @@ -2,62 +2,79 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface Signature { - id: number; - name: string; - position?: string; - certificate?: string; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + + code: string; + signature: string | null; + photo_path: string | null; + + + tenant_id: number; + company_id: number; + created_at: string; + updated_at?: string; } export interface SignatureCreate { - name: string; - position?: string; - certificate?: string; + code: string; + signature?: string | null; + photo_path?: string | null; + } export interface SignatureUpdate extends Partial {} export interface SignatureListResponse { - items: Signature[]; - total: number; - page: number; - page_size: number; - pages: number; + items: Signature[]; + total: number; + page: number; + page_size: number; + pages: number; } + export async function getSignatures( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/signatures?${params.toString()}`); - return response.data; + + const response = await api.get(`/v1/a76/signatures/?${params.toString()}`); + return response.data; } -export async function getSignature(id: number): Promise { - const response = await api.get(`/a76/signatures/${id}`); - return response.data; + +export async function getSignature(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/signatures/${id}/?company_id=${companyId}`); + return response.data; } -export async function createSignature(data: SignatureCreate): Promise { - const response = await api.post('/a76/signatures', data); - return response.data; + +export async function createSignature( + data: SignatureCreate, + companyId: number +): Promise { + const response = await api.post(`/v1/a76/signatures/?company_id=${companyId}`, data); + return response.data; } -export async function updateSignature(id: number, data: SignatureUpdate): Promise { - const response = await api.patch(`/a76/signatures/${id}`, data); - return response.data; +export async function updateSignature( + id: number, + data: SignatureUpdate, + companyId: number +): Promise { + const response = await api.put(`/v1/a76/signatures/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteSignature(id: number): Promise { - await api.delete(`/a76/signatures/${id}`); -} +export async function deleteSignature(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/signatures/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-conversions.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-conversions.ts index 1494fd76..610f707d 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-conversions.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/unit-conversions.ts @@ -2,62 +2,76 @@ import { api } from '$lib/api'; import type { ApiResponse } from '$lib/api'; export interface UnitConversion { - id: number; - from_unit_id: number; - to_unit_id: number; - conversion_factor: number; - tenant_id: string; - company_id?: string; - created_at: string; - updated_at?: string; + id: number; + from_unit_code: string; + to_unit_code: string; + conversion_factor: number; + tenant_id: number; // number + company_id: number; // number + created_at: string; + updated_at?: string; } export interface UnitConversionCreate { - from_unit_id: number; - to_unit_id: number; - conversion_factor: number; + from_unit_code: string; // Ej: "KGM" + to_unit_code: string; // Ej: "LBR" + conversion_factor: number; + // company_id va en la URL } export interface UnitConversionUpdate extends Partial {} export interface UnitConversionListResponse { - items: UnitConversion[]; - total: number; - page: number; - page_size: number; - pages: number; + items: UnitConversion[]; + total: number; + page: number; + page_size: number; + pages: number; } + export async function getUnitConversions( - page: number = 1, - pageSize: number = 50, - filters: Record = {} + page: number = 1, + pageSize: number = 50, + companyId: number, // 👈 Obligatorio + filters: Record = {} ): Promise> { - const params = new URLSearchParams({ - page: page.toString(), - page_size: pageSize.toString(), - ...filters - }); + const params = new URLSearchParams({ + page: page.toString(), + page_size: pageSize.toString(), + company_id: companyId.toString(), + ...filters + }); - const response = await api.get(`/a76/unit_conversions?${params.toString()}`); - return response.data; + // Agregamos /v1 y prefijo. + // NOTA: Revisa si en tu router definiste "unit_conversions" o "unit-conversions" + const response = await api.get(`/v1/a76/unit-conversions/?${params.toString()}`); + return response.data; } -export async function getUnitConversion(id: number): Promise { - const response = await api.get(`/a76/unit_conversions/${id}`); - return response.data; +export async function getUnitConversion(id: number, companyId: number): Promise { + const response = await api.get(`/v1/a76/unit-conversions/${id}/?company_id=${companyId}`); + return response.data; } -export async function createUnitConversion(data: UnitConversionCreate): Promise { - const response = await api.post('/a76/unit_conversions', data); - return response.data; +export async function createUnitConversion( + data: UnitConversionCreate, + companyId: number +): Promise { + const response = await api.post(`/v1/a76/unit-conversions/?company_id=${companyId}`, data); + return response.data; } -export async function updateUnitConversion(id: number, data: UnitConversionUpdate): Promise { - const response = await api.patch(`/a76/unit_conversions/${id}`, data); - return response.data; + +export async function updateUnitConversion( + id: number, + data: UnitConversionUpdate, + companyId: number +): Promise { + const response = await api.put(`/v1/a76/unit-conversions/${id}/?company_id=${companyId}`, data); + return response.data; } -export async function deleteUnitConversion(id: number): Promise { - await api.delete(`/a76/unit_conversions/${id}`); -} +export async function deleteUnitConversion(id: number, companyId: number): Promise { + await api.delete(`/v1/a76/unit_conversions/${id}/?company_id=${companyId}`); +} \ No newline at end of file diff --git a/frontend/src/lib/api/dashboard/a76/invoices.ts b/frontend/src/lib/api/dashboard/a76/invoices.ts index 99a23601..461b8346 100644 --- a/frontend/src/lib/api/dashboard/a76/invoices.ts +++ b/frontend/src/lib/api/dashboard/a76/invoices.ts @@ -124,7 +124,7 @@ export interface InvoiceListResponse { page_size: number; } -export interface CreateInvoiceData { +export interface InvoiceData { operation_type?: OperationType | null; invoice_type?: string | null; invoice_number?: string | null; diff --git a/frontend/src/lib/components/dashboard/company/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/company/create-edit-dialog.svelte deleted file mode 100644 index 96ed1222..00000000 --- a/frontend/src/lib/components/dashboard/company/create-edit-dialog.svelte +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - {title} - - -
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> - {#if error} -
{error}
- {/if} - -
- - -
- -
- - -
- -
- - -
- -
- - -
- - - - - -
-
-
diff --git a/frontend/src/lib/components/dashboard/exchange-rate/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/exchange-rate/create-edit-dialog.svelte index 940e7f78..5577e18a 100644 --- a/frontend/src/lib/components/dashboard/exchange-rate/create-edit-dialog.svelte +++ b/frontend/src/lib/components/dashboard/exchange-rate/create-edit-dialog.svelte @@ -1,164 +1,187 @@ - - - - {isEdit ? 'Editar' : 'Crear'} Tipo de Cambio - + + + + {title} + -
-
- - -
+ { e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4"> + {#if error} +
+ {error} +
+ {/if} -
- - -
+
+
+ +
+ +
+
-
- - -
+
+ +
+ +

Hasta 6 decimales.

+
+
-
- - -
+
+ +
+ +
+
- {#if error} -

{error}

- {/if} +
+ +
+ +
+
+
-
- - -
-
-
-
+ + + + + +
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/classification/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/general_catalogs/classification/create-edit-dialog.svelte new file mode 100644 index 00000000..86612132 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/classification/create-edit-dialog.svelte @@ -0,0 +1,115 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ + +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/company/columns.ts b/frontend/src/lib/components/dashboard/general_catalogs/company/columns.ts similarity index 100% rename from frontend/src/lib/components/dashboard/company/columns.ts rename to frontend/src/lib/components/dashboard/general_catalogs/company/columns.ts diff --git a/frontend/src/lib/components/dashboard/general_catalogs/company/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/general_catalogs/company/create-edit-dialog.svelte new file mode 100644 index 00000000..2cc43f4a --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/company/create-edit-dialog.svelte @@ -0,0 +1,296 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> + {#if error} +
+ {error} +
+ {/if} + + + + General + Programas + Responsable + Config + + + +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/company/data-table-actions.svelte b/frontend/src/lib/components/dashboard/general_catalogs/company/data-table-actions.svelte similarity index 100% rename from frontend/src/lib/components/dashboard/company/data-table-actions.svelte rename to frontend/src/lib/components/dashboard/general_catalogs/company/data-table-actions.svelte diff --git a/frontend/src/lib/components/dashboard/general_catalogs/concepts/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/general_catalogs/concepts/create-edit-dialog.svelte new file mode 100644 index 00000000..779795b6 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/concepts/create-edit-dialog.svelte @@ -0,0 +1,213 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> + {#if error} +
+ {error} +
+ {/if} + + + +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/customs_broker_concepts/create-edite-dialoge.svelte b/frontend/src/lib/components/dashboard/general_catalogs/customs_broker_concepts/create-edite-dialoge.svelte new file mode 100644 index 00000000..c2f4cf21 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/customs_broker_concepts/create-edite-dialoge.svelte @@ -0,0 +1,165 @@ + + + + + + {title} + + {isEdit ? 'Modifica el concepto del agente aduanal' : 'Crea un nuevo concepto'} + + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/error_catalogs/create-edite-dialoge.svelte b/frontend/src/lib/components/dashboard/general_catalogs/error_catalogs/create-edite-dialoge.svelte new file mode 100644 index 00000000..1a8b1db0 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/error_catalogs/create-edite-dialoge.svelte @@ -0,0 +1,141 @@ + + +{#if open} +
+ +
+ +
+

+ {classification ? 'Editar Clasificación' : 'Nueva Clasificación'} +

+ +
+ +
+ +
+ + + {#if classification} +

El código no se puede cambiar.

+ {/if} +
+ +
+ + +
+ + {#if classification} +
+
+ Creado: + {formatDate(classification.created_at)} +
+ {#if classification.updated_at} +
+ Actualizado: + {formatDate(classification.updated_at)} +
+ {/if} +
+ {/if} + +
+ + +
+ +
+
+
+{/if} \ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/inpc/create-edite-dialoge.svelte b/frontend/src/lib/components/dashboard/general_catalogs/inpc/create-edite-dialoge.svelte new file mode 100644 index 00000000..bb314713 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/inpc/create-edite-dialoge.svelte @@ -0,0 +1,166 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ +
+ +
+
+ +
+ +
+ +

Formato MM (Ej: 01, 12)

+
+
+ +
+ +
+ +

Hasta 8 decimales

+
+
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/legend/create-edite-dialoge.svelte b/frontend/src/lib/components/dashboard/general_catalogs/legend/create-edite-dialoge.svelte new file mode 100644 index 00000000..8e61a795 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/legend/create-edite-dialoge.svelte @@ -0,0 +1,149 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ +
+ +

Debe ser un número entero.

+
+
+ +
+ +
+ +
+ + {#if location} +
+
+ Creado: + {formatDate(location.created_at)} +
+ {#if location.updated_at} +
+ Actualizado: + {formatDate(location.updated_at)} +
+ {/if} +
+ {/if} + +
+ + +
+ + +
+
+{/if} \ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/multi_currency_types/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/general_catalogs/multi_currency_types/create-edit-dialog.svelte new file mode 100644 index 00000000..738d2fb7 --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/multi_currency_types/create-edit-dialog.svelte @@ -0,0 +1,196 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ +
+ +

Código de moneda (FK).

+
+
+ +
+ +
+ +

Clave M3 del país (FK).

+
+
+ +
+ +
+ +

Se guarda como entero (YYYYMMDD).

+
+
+ +
+ +
+ +
+
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/general_catalogs/signatures/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/general_catalogs/signatures/create-edit-dialog.svelte new file mode 100644 index 00000000..ec69a2fa --- /dev/null +++ b/frontend/src/lib/components/dashboard/general_catalogs/signatures/create-edit-dialog.svelte @@ -0,0 +1,163 @@ + + + + + + {title} + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4 py-4"> + {#if error} +
+ {error} +
+ {/if} + +
+
+ +
+ +

Máximo 10 caracteres.

+
+
+ +
+ +
+