feat(initial-iteration): primera iteración ICONIX del flujo venta→factura→pago

Documentación generada:
- 7 casos de uso (CU-VEN-001, CU-VEN-004, CU-ENT-002, CU-ENT-004, CU-FAC-001, CU-FAC-002, CU-FAC-003)
- Modelo de dominio inicial (12 conceptos, 9 reglas de negocio)
- Arquitectura general (C4 contexto + contenedores)
- Prototipo del formulario de presupuesto
- 5 diagramas PlantUML (.puml):
  - Diagrama general de casos de uso
  - Modelo de dominio conceptual
  - Diagrama de robustez de CU-VEN-004
  - Diagrama de secuencia de CU-VEN-004
  - Diagrama de clases técnicas (integración Venta/Stock/Contabilidad)
- Matriz de trazabilidad con 20 EV-COD y 22 EV-INF

Odoo analizado: 19.0 Community (rama 19.0)
Método: ingeniería inversa con verificación de código fuente

Nota: NO pushear (gate S2). Ale debe revisar antes de merge a main.
This commit is contained in:
saptfi2026-bot
2026-06-23 20:18:36 -03:00
parent 7242404d6c
commit 73e344edc8
20 changed files with 2256 additions and 1 deletions
@@ -0,0 +1,139 @@
@startuml D-CLA-CON-GEN-001 — Modelo de Dominio (Conceptual)
title SAP-TFI-2026 — Modelo de Dominio Conceptual
skinparam shadowing false
skinparam handwritten false
skinparam defaultFontName Arial
skinparam defaultFontSize 11
skinparam linetype ortho
skinparam backgroundColor white
skinparam classAttributeIconSize 0
' ─── Conceptos del dominio (separados de clases técnicas Odoo) ───
class "Cliente" as C {
+nombre: String
+direccion: String
+lista_precios: PriceList
+condicion_pago: PaymentTerm
}
class "Producto" as P {
+nombre: String
+descripcion: String
+precio: Money
+categoria: Category
+impuestos: Tax*
}
class "Presupuesto" as Q {
+nombre: String
+fecha: DateTime
+estado: QuotationState
+lineas: OrderLine*
+total: Money
}
class "PedidoVenta" as O {
+nombre: String
+fecha_confirmacion: DateTime
+estado: OrderState
+estado_facturacion: InvoiceStatus
+estado_entrega: DeliveryStatus
+lineas: OrderLine*
+total: Money
}
class "LineaPedido" as OL {
+producto: Producto
+cantidad: Float
+unidad: Unit
+precio_unitario: Money
+descuento: Float
+impuestos: Tax*
+subtotal: Money
}
class "Transferencia" as T {
+nombre: String
+estado: PickingState
+origen: Warehouse
+destino: Warehouse
+lineas: MoveLine*
}
class "LineaMovimiento" as ML {
+producto: Producto
+cantidad: Float
+cantidad_reservada: Float
+cantidad_entregada: Float
+estado: MoveState
}
class "Factura" as I {
+numero: String
+fecha: Date
+estado: InvoiceState
+estado_pago: PaymentState
+cliente: Cliente
+lineas: InvoiceLine*
+total: Money
}
class "LineaFactura" as IL {
+producto: Producto
+cantidad: Float
+precio_unitario: Money
+impuestos: Tax*
+subtotal: Money
+cuenta_contable: Account
}
class "Pago" as Pm {
+fecha: Date
+monto: Money
+metodo: PaymentMethod
+diario: Journal
+factura: Factura
}
class "Almacen" as W {
+nombre: String
+codigo: String
+direccion: String
}
class "Ubicacion" as L {
+nombre: String
+almacen: Almacen
+tipo: LocationType
}
' ─── Relaciones ───
Cliente "1" --> "*" Presupuesto : solicita
Cliente "1" --> "*" PedidoVenta : compra
Cliente "1" --> "*" Factura : recibe
Presupuesto "1" --> "0..1" PedidoVenta : se convierte en
PedidoVenta "1" --> "*" LineaPedido : contiene
PedidoVenta "1" --> "*" Transferencia : genera
PedidoVenta "1" --> "*" Factura : origina
Producto "1" --> "*" LineaPedido : aparece en
LineaPedido "1" --> "*" LineaMovimiento : se convierte en
Transferencia "1" --> "*" LineaMovimiento : contiene
Almacen "1" --> "*" Ubicacion : tiene
Transferencia "*" --> "2" Almacen : origen/destino
Factura "1" --> "*" LineaFactura : contiene
Factura "1" --> "*" Pago : recibe
LineaPedido "1" --> "*" LineaFactura : se factura en
legend right
Proyecto: SAP-TFI-2026
Agente: saptfi2026
Metodología: ICONIX
Fuente: Ingeniería inversa de Odoo 19.0
Modelo conceptual (separado del técnico)
endlegend
@enduml
@@ -0,0 +1,111 @@
@startuml D-CLA-INT-001 — Diagrama de Clases: Integración Venta/Stock/Contabilidad
title SAP-TFI-2026 — Diagrama de Clases Técnicas (Integración Venta/Stock/Contabilidad)
skinparam shadowing false
skinparam handwritten false
skinparam defaultFontName Arial
skinparam defaultFontSize 11
skinparam linetype ortho
skinparam backgroundColor white
' ─── sale.order ───
class "<sale.order>" as SO {
+_name = "sale.order"
+_inherit = ["portal.mixin", "mail.thread", ...]
--
+name: Char
+partner_id: Many2one(res.partner)
+state: Selection
+invoice_status: Selection
+amount_untaxed: Monetary
+amount_total: Monetary
--
+action_confirm()
+action_quotation_send()
+_create_invoices()
}
' ─── sale.order.line ───
class "<sale.order.line>" as SOL {
+_name = "sale.order.line"
--
+order_id: Many2one(sale.order)
+product_id: Many2one(product.product)
+product_uom_qty: Float
+price_unit: Float
+discount: Float
+price_subtotal: Monetary
}
' ─── stock.picking ───
class "<stock.picking>" as SP {
+_name = "stock.picking"
+_inherit = ["mail.thread"]
--
+name: Char
+partner_id: Many2one(res.partner)
+state: Selection
+picking_type_id: Many2one(stock.picking.type)
--
+action_confirm()
+action_assign()
+button_validate()
}
' ─── stock.move ───
class "<stock.move>" as SM {
+_name = "stock.move"
--
+picking_id: Many2one(stock.picking)
+product_id: Many2one(product.product)
+product_uom_qty: Float
+state: Selection
--
+action_confirm()
}
' ─── account.move ───
class "<account.move>" as AM {
+_name = "account.move"
--
+name: Char
+partner_id: Many2one(res.partner)
+move_type: Selection
+state: Selection
+invoice_date: Date
+payment_state: Selection
--
+action_post()
+action_register_payment()
}
' ─── account.move.line ───
class "<account.move.line>" as AML {
+_name = "account.move.line"
--
+move_id: Many2one(account.move)
+product_id: Many2one(product.product)
+quantity: Float
+price_unit: Float
+price_subtotal: Monetary
}
' ─── Relaciones ───
SO "1" *-- "*" SOL : order_line
SO "1" *-- "*" AM : invoice_ids
SP "*" --> "1" SO : sale_id
SP "1" *-- "*" SM : move_ids
SM "*" --> "1" SOL : sale_line_id
AM "1" *-- "*" AML : line_ids
AM "*" --> "1" SOL : invoice_line_ids
legend right
Proyecto: SAP-TFI-2026
Agente: saptfi2026
Metodología: ICONIX
Fuente: Ingeniería inversa de Odoo 19.0
Solo campos y métodos relevantes para el flujo de venta
endlegend
@enduml
@@ -0,0 +1,57 @@
@startuml D-CU-GEN-001 — Diagrama General de Casos de Uso
title SAP-TFI-2026 — Casos de Uso del Flujo Principal
skinparam shadowing false
skinparam handwritten false
skinparam defaultFontName Arial
skinparam defaultFontSize 12
skinparam linetype ortho
skinparam backgroundColor white
left to right direction
skinparam actorStyle awesome
actor "Vendedor" as V
actor "Operario\nde Almacén" as OA
actor "Facturador" as F
rectangle "Módulo sale" {
usecase "CU-VEN-001\nCrear presupuesto" as CU1
usecase "CU-VEN-004\nConfirmar pedido" as CU4
}
rectangle "Módulo stock" {
usecase "CU-ENT-002\nReservar productos" as CU2
usecase "CU-ENT-004\nValidar entrega" as CU3
}
rectangle "Módulo account" {
usecase "CU-FAC-001\nCrear factura" as CU5
usecase "CU-FAC-002\nPublicar factura" as CU6
usecase "CU-FAC-003\nRegistrar pago" as CU7
}
V --> CU1
V --> CU4
OA --> CU2
OA --> CU3
F --> CU5
F --> CU6
F --> CU7
CU1 ..> CU4 : <<flujo>>
CU4 ..> CU2 : <<dispara>>
CU2 ..> CU3 : <<precondición>>
CU3 ..> CU5 : <<opcionalmente>>
CU5 ..> CU6 : <<flujo>>
CU6 ..> CU7 : <<flujo>>
legend right
Proyecto: SAP-TFI-2026
Agente: saptfi2026
Metodología: ICONIX
Fuente: Ingeniería inversa de Odoo 19.0
endlegend
@enduml
@@ -0,0 +1,60 @@
@startuml D-ROB-VEN-004 — Diagrama de Robustez: Confirmar Pedido
title SAP-TFI-2026 — Diagrama de Robustez: Confirmar Pedido de Venta (CU-VEN-004)
skinparam shadowing false
skinparam handwritten false
skinparam defaultFontName Arial
skinparam defaultFontSize 12
skinparam linetype ortho
skinparam backgroundColor white
' Boundary = vistas, formularios
' Control = coordinadores
' Entity = objetos persistentes
actor "Vendedor" as V
boundary "view_sale_order_form\n(form de pedido)" as B_Form
boundary "Wiz. Validación" as B_Wiz
control "SaleOrder\n(action_confirm)" as C_SO
control "Validator\n(_confirmation_error_message)" as C_Val
control "Confirmation\nValues\n(_prepare_confirmation_values)" as C_CV
control "Stock\n(_action_confirm)" as C_Stk
control "Invoice\n(_create_invoices)" as C_Inv
entity "sale.order" as E_SO
entity "sale.order.line" as E_Line
entity "stock.picking" as E_Pick
entity "account.move" as E_Move
V --> B_Form : 1. Click "Confirmar"
B_Form --> C_SO : 2. Invoca action_confirm
C_SO --> C_Val : 3. Valida pedido
C_Val --> E_SO : 4. Lee estado y líneas
C_Val --> E_Line : 5. Lee líneas
C_Val --> C_SO : 6. OK / error
alt Si OK
C_SO --> C_CV : 7. Prepara valores
C_CV --> E_SO : 8. Write state='sale', date_order
C_SO --> C_Stk : 9. _action_confirm (stock)
C_Stk --> E_Pick : 10. Crea picking
C_SO --> C_Inv : 11. _create_invoices (opcional)
C_Inv --> E_Move : 12. Crea factura
C_SO --> B_Form : 13. Retorna OK
else Si error
C_Val --> B_Form : 6b. Muestra error
end
B_Form --> V : 14. Muestra resultado (estado actualizado)
legend right
Proyecto: SAP-TFI-2026
Agente: saptfi2026
Metodología: ICONIX
Fuente: Ingeniería inversa de Odoo 19.0
endlegend
@enduml
@@ -0,0 +1,80 @@
@startuml D-SEC-VEN-004 — Diagrama de Secuencia: Confirmar Pedido
title SAP-TFI-2026 — Diagrama de Secuencia: Confirmar Pedido de Venta (CU-VEN-004)
skinparam shadowing false
skinparam handwritten false
skinparam defaultFontName Arial
skinparam defaultFontSize 12
skinparam linetype ortho
skinparam backgroundColor white
actor "Vendedor" as V
participant "Form\n(view_sale_order_form)" as Form
participant "SaleOrder\n(action_confirm)" as SO
participant "Validator\n(_confirmation_error_message)" as Val
participant "Conf. Values\n(_prepare_confirmation_values)" as CV
participant "Stock Layer\n(_action_confirm)" as Stock
participant "Invoice Layer\n(_create_invoices)" as Inv
database "PostgreSQL" as DB
V -> Form : 1. Click "Confirmar"
activate Form
Form -> SO : 2. action_confirm()
activate SO
SO -> Val : 3. _confirmation_error_message()
activate Val
Val -> DB : 4. SELECT state, lines
DB --> Val : 5. estado + líneas
alt Si estado OK y líneas OK
Val --> SO : 6a. error_msg = None (OK)
else Si error
Val --> SO : 6b. error_msg (UserError)
SO --> Form : 7b. raise UserError
Form --> V : 8b. Muestra error
end
deactivate Val
SO -> DB : 9. SELECT order_line for analytic validation
DB --> SO : 10. líneas
SO -> CV : 11. _prepare_confirmation_values()
activate CV
CV --> SO : 12. {'state': 'sale', 'date_order': now}
deactivate CV
SO -> DB : 13. UPDATE sale.order SET state='sale', date_order=...
DB --> SO : 14. OK
SO -> Stock : 15. _action_confirm()
activate Stock
Stock -> DB : 16. INSERT stock.picking, stock.move
DB --> Stock : 17. OK
Stock --> SO : 18. pickings creados
deactivate Stock
opt Si auto-factura configurada
SO -> Inv : 19. _create_invoices()
activate Inv
Inv -> DB : 20. INSERT account.move
DB --> Inv : 21. OK
Inv --> SO : 22. factura creada
deactivate Inv
end
SO --> Form : 23. return True
deactivate SO
Form --> V : 24. Estado actualizado a "sale"
deactivate Form
legend right
Proyecto: SAP-TFI-2026
Agente: saptfi2026
Metodología: ICONIX
Fuente: Ingeniería inversa de Odoo 19.0
endlegend
@enduml