feat(docs): actualizar documentación de configuración fiscal de Proforma y agregar notas sobre obsolescencia
This commit is contained in:
parent
3d8f110cb7
commit
77851f5dba
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
> Estado: **HISTÓRICO — NO NORMATIVO**.
|
> Estado: **HISTÓRICO — NO NORMATIVO**.
|
||||||
>
|
>
|
||||||
|
> Nota de obsolescencia fiscal: para el comportamiento CURRENT de Proforma, disponibilidad,
|
||||||
|
> snapshot de IssuedInvoice, grouping P10 y estado de DELETE de TaxDefinition, consultar
|
||||||
|
> [Proforma Tax Config](../../customer-invoices/proforma-tax-config.md). Este documento no se
|
||||||
|
> actualiza retrospectivamente.
|
||||||
|
>
|
||||||
> Las reglas transversales vigentes están distribuidas por responsabilidad en [../backend-architecture.md](../backend-architecture.md), [../dependency-injection.md](../dependency-injection.md), [../http-request-flow.md](../http-request-flow.md), [../dto-guidelines.md](../dto-guidelines.md), [../module-boundaries.md](../module-boundaries.md) y [../testing-guidelines.md](../testing-guidelines.md).
|
> Las reglas transversales vigentes están distribuidas por responsabilidad en [../backend-architecture.md](../backend-architecture.md), [../dependency-injection.md](../dependency-injection.md), [../http-request-flow.md](../http-request-flow.md), [../dto-guidelines.md](../dto-guidelines.md), [../module-boundaries.md](../module-boundaries.md) y [../testing-guidelines.md](../testing-guidelines.md).
|
||||||
>
|
>
|
||||||
> En particular, el flujo `RequestDTO → RequestMapper → Command → PropsMapper` que aparece más abajo no es una norma vigente: RequestMapper es opcional y se usa solo cuando existe adaptación HTTP propia.
|
> En particular, el flujo `RequestDTO → RequestMapper → Command → PropsMapper` que aparece más abajo no es una norma vigente: RequestMapper es opcional y se usa solo cuando existe adaptación HTTP propia.
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
# Proforma Tax Config
|
# Proforma Tax Config
|
||||||
|
|
||||||
|
> Estado: **CURRENT — SSOT fiscal** para Proforma e IssuedInvoice. Las propuestas futuras
|
||||||
|
> deben identificarse expresamente como TARGET; la protección de DELETE de TaxDefinition
|
||||||
|
> permanece **APARCADA**.
|
||||||
|
|
||||||
## Objetivo
|
## Objetivo
|
||||||
|
|
||||||
Persistir la configuracion fiscal de cabecera de una proforma sin confundirla con los impuestos realmente calculados desde lineas valoradas.
|
Persistir la configuracion fiscal de cabecera de una proforma sin confundirla con los impuestos realmente calculados desde lineas valoradas.
|
||||||
@ -20,6 +24,34 @@ Persistir la configuracion fiscal de cabecera de una proforma sin confundirla co
|
|||||||
- `uses_retention`
|
- `uses_retention`
|
||||||
- `default_retention_code`
|
- `default_retention_code`
|
||||||
|
|
||||||
|
Estos códigos son referencias fiscales persistidas de la Proforma. No existe todavía una
|
||||||
|
protección transversal consolidada que impida borrar una `TaxDefinition` por estar referenciada.
|
||||||
|
|
||||||
|
## Fiscalidad viva de Proforma
|
||||||
|
|
||||||
|
Una Proforma es fiscalmente viva. Al cargarla, si existe la `TaxDefinition` de la empresa para
|
||||||
|
un código, prevalece la definición actual: `code`, `name`, porcentaje/rate, family/group y
|
||||||
|
`calculationBehavior`. Por ejemplo, una línea persistida como `IVA21` al 21 % se presenta al
|
||||||
|
22 % si la definición viva `IVA21` se actualizó al 22 %.
|
||||||
|
|
||||||
|
La línea conserva además un respaldo persistido completo: código, nombre, porcentaje, group y
|
||||||
|
calculation behavior (más los importes calculados). Ese respaldo no es fuente funcional primaria
|
||||||
|
cuando existe catálogo vivo; sirve para recuperación, diagnóstico y lectura ante inconsistencias.
|
||||||
|
|
||||||
|
## Disponibilidad fiscal
|
||||||
|
|
||||||
|
La disponibilidad se evalúa por `companyId`, código fiscal y `proformaDate`:
|
||||||
|
|
||||||
|
- `available`: puede asignarse, cambiar de estado y emitirse.
|
||||||
|
- `inactive` o `out_of_validity`: una lectura existente se resuelve live, pero no admite nueva
|
||||||
|
asignación, cambio de estado ni emisión.
|
||||||
|
- `missing`: la lectura hace fallback al Tax persistido; no permite nueva asignación, cambio de
|
||||||
|
estado ni emisión.
|
||||||
|
|
||||||
|
No hay fallback a defaults de Customer o Company. Readiness expone blockers `tax_unavailable`
|
||||||
|
con razón `inactive`, `out_of_validity` o `missing`; la emisión revalida en ese instante y no
|
||||||
|
confía en un readiness previo.
|
||||||
|
|
||||||
## Contrato publico
|
## Contrato publico
|
||||||
|
|
||||||
`GET /proformas/:id` debe devolver:
|
`GET /proformas/:id` debe devolver:
|
||||||
@ -78,6 +110,32 @@ No debe reconstruirse desde:
|
|||||||
- el cliente actual
|
- el cliente actual
|
||||||
- defaults implícitos de frontend
|
- defaults implícitos de frontend
|
||||||
|
|
||||||
|
Para `items`: `undefined` no toca la colección ni revalida su fiscalidad existente; `[]` borra
|
||||||
|
todas las líneas; una lista reemplaza completamente las líneas y valida todos sus impuestos como
|
||||||
|
activos y vigentes. No existe mantenimiento diferencial por `itemId`.
|
||||||
|
|
||||||
|
## IssuedInvoice: snapshot histórico
|
||||||
|
|
||||||
|
Una factura emitida es un snapshot histórico inmutable. `IssuedInvoiceItem` e
|
||||||
|
`IssuedInvoiceTax` conservan, por IVA/REC/retención según corresponda, código, nombre,
|
||||||
|
porcentaje e importe. Rehidratar, construir DTO o reporte no consulta `TaxDefinition` ni
|
||||||
|
Proforma; cambios posteriores de nombre, porcentaje, actividad o vigencia no alteran la factura.
|
||||||
|
|
||||||
|
No existe fallback `name = code`: `code != null && name == null` es una inconsistencia legacy.
|
||||||
|
|
||||||
|
## Grouping fiscal actual (P10)
|
||||||
|
|
||||||
|
La identidad actual del breakdown es `ivaCode | recCode | retentionCode`: las tres dimensiones
|
||||||
|
participan, no solo IVA. El porcentaje no forma parte de la key, pero dentro de un grupo el mismo
|
||||||
|
código con nombre distinto o porcentaje distinto produce fail-fast. Esto no afirma que un código
|
||||||
|
tenga un porcentaje históricamente inmutable; afirma que no pueden coexistir valores contradictorios
|
||||||
|
para el mismo código dentro del mismo documento.
|
||||||
|
|
||||||
|
Se eliminaron las constraints equivalentes a `UNIQUE(document_id, iva_code)` de los breakdowns
|
||||||
|
de Proforma e IssuedInvoice: contradecían la identidad con REC/retención. El dominio garantiza
|
||||||
|
la agrupación única; la BD todavía no tiene una UNIQUE exacta para los tres slots nullable debido
|
||||||
|
a la semántica SQL de `NULL`. Es deuda futura no bloqueante.
|
||||||
|
|
||||||
## No incluido
|
## No incluido
|
||||||
|
|
||||||
- nueva tabla para configuracion fiscal
|
- nueva tabla para configuracion fiscal
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import type { Criteria } from "@repo/rdx-criteria/server";
|
import type { Criteria } from "@repo/rdx-criteria/server";
|
||||||
import type { UniqueID } from "@repo/rdx-ddd";
|
import type { UniqueID } from "@repo/rdx-ddd";
|
||||||
import type { Collection, Result } from "@repo/rdx-utils";
|
import { Collection, Result } from "@repo/rdx-utils";
|
||||||
|
|
||||||
import type { Proforma } from "../../../domain";
|
import type { Proforma } from "../../../domain";
|
||||||
import type { ProformaStatusCounts, ProformaSummary } from "../models";
|
import type { ProformaStatusCounts, ProformaSummary } from "../models";
|
||||||
import type { IProformaRepository } from "../repositories";
|
import type { IProformaRepository } from "../repositories";
|
||||||
import type { ProformaListScope } from "../use-cases";
|
import type { ProformaListScope } from "../use-cases";
|
||||||
|
|
||||||
import type { ProformaTaxResolver } from "./catalog-resolver";
|
import type { ProformaTaxResolver } from "./catalog-resolver";
|
||||||
|
|
||||||
export interface IProformaFinder {
|
export interface IProformaFinder {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user