feat(fin): partidas de factura capturadas desde el catálogo de conceptos
El selector de concepto de la partida deja de ser una lista fija en el código y se alimenta del catálogo de conceptos de la empresa: al elegir uno se manda concept_id y el backend copia la descripción a la columna de texto libre que consume el PDF. Si el concepto trae precio unitario, se precarga en la partida. Las claves genéricas anteriores quedan en un segundo grupo del mismo selector, marcadas como "sin clave del SAT", para no bloquear a las empresas que aún no tienen catálogo; si está vacío se enlaza al alta de conceptos. El listado de partidas etiqueta con la clave y descripción del catálogo cuando la partida lo referencia, y cae al texto libre para las facturas anteriores. Los tipos de Invoice e InvoiceItem se completan con las claves fiscales que el backend ya devuelve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,7 @@ from api.v1.modules.fin.catalogs.seed_data import CATALOGS, sync_catalogs
|
||||
from api.v1.modules.fin.concepts import service as concepts_service
|
||||
from api.v1.modules.fin.concepts.dto import ConceptCreate, ConceptUpdate
|
||||
from api.v1.modules.fin.invoices import service as invoices_service
|
||||
from api.v1.modules.fin.invoices.dto import InvoiceCreate, InvoiceItemCreate
|
||||
from api.v1.modules.fin.invoices.dto import InvoiceCreate, InvoiceItemCreate, InvoiceItemResponse
|
||||
from api.v1.modules.fin.issuer import service as issuer_service
|
||||
from api.v1.modules.fin.issuer.dto import IssuerSettingsInput
|
||||
from api.v1.modules.fin.issuer.models import IssuerSettings
|
||||
@@ -279,6 +279,12 @@ def test_invoice_item_inherits_concept_description(db):
|
||||
assert item.concept == concept.description # copiada del catálogo para el PDF
|
||||
assert item.concept_id == concept.id
|
||||
|
||||
# La respuesta expone las claves fiscales: el frontend etiqueta la partida con ellas.
|
||||
payload = InvoiceItemResponse.model_validate(item).model_dump()
|
||||
assert payload["concept_id"] == concept.id
|
||||
assert payload["concept"] == concept.description
|
||||
assert {"product_service_id", "unit_of_measure_id", "tax_object_id"} <= payload.keys()
|
||||
|
||||
# Si el cliente sí manda el texto, se respeta tal cual.
|
||||
explicit = invoices_service.create_item(
|
||||
db,
|
||||
|
||||
Reference in New Issue
Block a user