feature/seed-digitalizacion

This commit is contained in:
2026-05-25 11:03:24 -06:00
parent 9cb77d6e16
commit 676a6fe413
11 changed files with 116 additions and 66 deletions

View File

@@ -6,7 +6,6 @@ class DocumentTypeDigitizationBase(BaseModel):
code: str = Field(..., max_length=10, description="Código del tipo de documento")
description: str = Field(..., description="Descripción del tipo de documento")
active: bool = Field(default=True, description="Indica si el tipo está activo")
class DocumentTypeDigitizationCreate(DocumentTypeDigitizationBase):
@@ -20,7 +19,6 @@ class DocumentTypeDigitizationUpdate(BaseModel):
code: str | None = Field(None, max_length=10)
description: str | None = None
active: bool | None = None
class DocumentTypeDigitizationResponse(DocumentTypeDigitizationBase):

View File

@@ -1,7 +1,6 @@
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
from core.database import Base
from sqlalchemy import (
Boolean,
Integer,
PrimaryKeyConstraint,
String,
@@ -29,4 +28,3 @@ class DocumentTypeDigitization(Base, TenantScopedMixin, TimestampMixin):
id: Mapped[int] = mapped_column(Integer)
code: Mapped[str] = mapped_column(String(10), nullable=False, index=True)
description: Mapped[str] = mapped_column(Text, nullable=False)
active: Mapped[bool] = mapped_column(Boolean, default=True, server_default="true")

View File

@@ -19,7 +19,6 @@ async def list_document_types(
page: int = Query(1, ge=1, description='Page number'),
page_size: int = Query(50, ge=1, le=2000, description='Page size'),
search: Optional[str] = Query(None, description='Search by code or description'),
active_only: bool = Query(False, description='Only active records'),
sort_by: Optional[str] = Query('code', description='Column to sort by'),
sort_order: str = Query('asc', pattern='^(asc|desc)$', description='Sort order'),
db: Session = Depends(get_core_db),
@@ -31,8 +30,6 @@ async def list_document_types(
if search:
filters['search'] = search
if active_only:
filters['active_only'] = True
items, total = DocumentTypeDigitizationService.get_all(
db,

View File

@@ -0,0 +1,40 @@
# Catálogo SAT — tipos de documentos para digitalización (Ventanilla Única)
seed = [
('168', 'Calca o fotografía digital del NIV del vehículo.'),
('169', 'Aviso.'),
('170', 'Factura.'),
('171', 'Documento con el que se acredite la propiedad de la mercancía.'),
('172', 'Contratos.'),
('176', 'Documentación relacionada con la garantía otorgada en términos de los artículos 84.'),
('177', 'Identificación Oficial.'),
('179', 'Comprobante de domicilio.'),
('184', 'Documento que ampara el avaluó de las mercancías.'),
('185', 'Documentos de adjudicación judicial de las mercancías.'),
('187', 'Solicitud de retiro de mercancías que causaron abandono.'),
('189', 'Actas.'),
('192', 'Escritos.'),
('420', 'Certificado de peso o volumen.'),
('421', 'Comprobante de la importación temporal de la embarcación debidamente formalizado.'),
('422', 'Comprobante expedido por donataria.'),
('423', 'Consulta en la que conste que el vehículo no se encuentra reportado como robado,'),
('424', 'Clave Unica del Registro de Población.'),
('425', 'Declaración de internación o extracción de cantidades en efectivo y/o documentos p'),
('426', 'Declaración de operaciones que no confieren origen en países no parte de acuerdo'),
('427', 'Declaración en la que se señalen los motivos por los que efectúa la devolución de m'),
('428', 'Documentación con información que permita la identificación, análisis y control en tér'),
('429', 'Documentación que acredite que acepta y subsana la irregularidad.'),
('430', 'Documentación que ampara la importación temporal del vehículo de que se trate.'),
('431', 'Documentación que compruebe que la adquisición de las mercancías fue efectuada '),
('433', 'Documento con base en el cual se determine la procedencia y el origen de las merca'),
('434', 'Documento con que se acredite el reintegro del IVA, en caso de que el contribuyente '),
('435', 'Documentos previstos en la regla 8.7., fracciones I a IV de la Resolución del TLCAN.'),
('436', 'El Documento que compruebe el cumplimiento de las regulaciones y restricciones no '),
('438', 'Guía aérea, conocimiento de embarque o carta de porte.'),
('439', 'Hoja con los datos de la matrícula y nombre del barco, el lugar donde se localiza y se '),
('440', 'Manifiesto de carga.'),
('441', 'Oficios emitidos por autoridad.'),
('442', 'Pedimentos.'),
('443', 'Programa IMMEX.'),
('444', 'Relación de candados.'),
('445', 'Relación de certificados de origen.'),
]

View File

@@ -18,14 +18,6 @@ class DocumentTypeDigitizationService:
def _normalize_description(description: str) -> str:
return (description or '').strip()
@staticmethod
def _is_truthy_filter(value: Any, default: bool = False) -> bool:
if value is None:
return default
if isinstance(value, bool):
return value
return str(value).strip().lower() in {'1', 'true', 'yes', 'si'}
@staticmethod
def get_all(
db: Session,
@@ -45,15 +37,8 @@ class DocumentTypeDigitizationService:
query = query.filter(DocumentTypeDigitization.company_id == company_id)
filters = filters or {}
active_only = DocumentTypeDigitizationService._is_truthy_filter(
filters.get('active_only'),
default=False,
)
search = (filters.get('search') or '').strip()
if active_only:
query = query.filter(DocumentTypeDigitization.active.is_(True))
if search:
like = f'%{search}%'
query = query.filter(
@@ -69,7 +54,6 @@ class DocumentTypeDigitizationService:
'id': DocumentTypeDigitization.id,
'code': DocumentTypeDigitization.code,
'description': DocumentTypeDigitization.description,
'active': DocumentTypeDigitization.active,
}.get(sort_by or 'code', DocumentTypeDigitization.code)
if sort_order == 'desc':
@@ -195,17 +179,3 @@ class DocumentTypeDigitizationService:
db.refresh(db_obj)
return db_obj
@staticmethod
def delete(
db: Session,
id: int,
tenant_id: int,
company_id: int,
) -> bool:
db_obj = DocumentTypeDigitizationService.get_by_id(db, id, tenant_id, company_id)
if not db_obj:
return False
db_obj.active = False
db.commit()
return True

View File

@@ -21,6 +21,7 @@ from ..units_of_measure.seed import seed as units_of_measure_seed
from ..fractions.historical_tariff_fractions.seed import seed as historical_tariff_fractions_seed
from ..fractions.warning_fractions.seed import seed as warning_fractions_seed
from ..sectors.seed import seed as sectors_seed
from ...doc_types_dig.seed import seed as doc_types_dig_seed
from core.context import get_user_context
from sqlalchemy import text
@@ -812,6 +813,20 @@ class CompanyService:
ON CONFLICT (key, tenant_id, company_id) DO NOTHING;
"""))
# 5. Document Types for Digitization
values_doc_types = ", ".join(
[
f"({format_value(code)}, {format_value(description)}, {tenant_id}, {company_id})"
for code, description in doc_types_dig_seed
]
)
if values_doc_types:
db.execute(text(f"""
INSERT INTO a76.document_types_digitization (code, description, tenant_id, company_id)
VALUES {values_doc_types}
ON CONFLICT (tenant_id, company_id, code) DO NOTHING;
"""))
def get_companies_by_tenant(self, tenant_id: int) -> List[Company]:
"""Get all companies for a tenant"""
return (