feat(fin,ops): Facturación y Cobranza (Diag. 4), bitácora de embarque (Diag. 3) y subida a MinIO
- schema fin: fin.invoices + fin.invoice_items + fin.payments; totales con IVA, estados borrador→emitida→enviada→pagada, cobranza (pagos) y saldo automático - generar-factura-desde-embarque (toma conceptos de venta de la cotización) - ops.shipment_events: bitácora/hitos del embarque con secuencia por defecto según operación (importación/exportación) — cubre Diagrama 3 - subida de documentos a MinIO: POST /crm/uploads (multipart) + URL firmada - migración c4d5e6f7a8b9, routers/permisos (fin), seed del flujo hasta factura - 58 tests pytest en verde Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,26 @@ class Shipment(Base, TenantScopedMixin, TimestampMixin):
|
||||
updated_by: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
|
||||
|
||||
class ShipmentEvent(Base, TenantScopedMixin, TimestampMixin):
|
||||
"""Hito / bitácora del embarque (Diagramas 2 y 3). Timeline de la operación."""
|
||||
|
||||
__tablename__ = "shipment_events"
|
||||
__table_args__ = {"schema": "ops"}
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
|
||||
shipment_id: Mapped[int] = mapped_column(
|
||||
Integer, ForeignKey("ops.shipments.id"), nullable=False, index=True
|
||||
)
|
||||
event_type: Mapped[str | None] = mapped_column(String(60), nullable=True) # clave del hito
|
||||
title: Mapped[str] = mapped_column(String(160), nullable=False)
|
||||
# pendiente | completado | omitido
|
||||
status: Mapped[str] = mapped_column(String(20), nullable=False, server_default=text("'pendiente'"))
|
||||
position: Mapped[int] = mapped_column(Integer, nullable=False, server_default=text("0"))
|
||||
planned_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
actual_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
|
||||
class ShipmentDocument(Base, TenantScopedMixin, TimestampMixin):
|
||||
"""Documento de transporte del embarque (Master/House: MBL, HBL, MAWB, HAWB, CMR, etc.)."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user