feat(fin,ops): frontend Facturas/Cobranza, bitácora de embarque y uploader de documentos

- Facturas: lista, alta y detalle (Conceptos / Pagos-cobranza / Datos) con
  totales+IVA+saldo y acciones Emitir/Enviar/Cancelar
- Embarque: botón "Generar factura", pestaña "Bitácora" (hitos por defecto
  import/export, completar/agregar) y subida real de archivos a MinIO en documentos
- Clientes/Proveedores: subida de archivos en documentos (RelatedManager)
- clientes API fin + ops(eventos) + uploads; sidebar grupo Facturación
- svelte-check: 0 errores de tipo en archivos nuevos

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aduanasoft
2026-07-15 07:24:15 -06:00
parent 0b12ad5354
commit e724aeae50
10 changed files with 782 additions and 29 deletions

View File

@@ -39,6 +39,26 @@ export interface Shipment {
}
export type ShipmentInput = Partial<Omit<Shipment, 'id' | 'tenant_id' | 'company_id' | 'created_at' | 'updated_at' | 'created_by' | 'updated_by'>>;
export interface ShipmentEvent {
id: number;
shipment_id: number;
event_type: string | null;
title: string;
status: string;
position: number;
planned_date: string | null;
actual_date: string | null;
notes: string | null;
tenant_id: number;
company_id: number;
created_at: string;
updated_at: string;
}
export type ShipmentEventInput = Partial<Omit<ShipmentEvent, 'id' | 'tenant_id' | 'company_id' | 'created_at' | 'updated_at'>> & {
shipment_id: number;
title: string;
};
export interface ShipmentDocument {
id: number;
shipment_id: number;
@@ -80,7 +100,18 @@ export const shipmentsAPI = {
update: (id: number, data: Partial<ShipmentInput>, companyId: number) => unwrap<Shipment>(api.patch(`/v1/ops/shipments/${id}?${qp(companyId)}`, data)),
remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/ops/shipments/${id}?${qp(companyId)}`)),
documents: (shipmentId: number, companyId: number) =>
unwrap<ShipmentDocument[]>(api.get(`/v1/ops/shipments/${shipmentId}/documents?${qp(companyId)}`))
unwrap<ShipmentDocument[]>(api.get(`/v1/ops/shipments/${shipmentId}/documents?${qp(companyId)}`)),
events: (shipmentId: number, companyId: number) =>
unwrap<ShipmentEvent[]>(api.get(`/v1/ops/shipments/${shipmentId}/events?${qp(companyId)}`)),
seedEvents: (shipmentId: number, companyId: number) =>
unwrap<ShipmentEvent[]>(api.post(`/v1/ops/shipments/${shipmentId}/events/seed?${qp(companyId)}`, {}))
};
export const shipmentEventsAPI = {
create: (data: ShipmentEventInput, companyId: number) => unwrap<ShipmentEvent>(api.post(`/v1/ops/shipment-events?${qp(companyId)}`, data)),
update: (id: number, data: Partial<ShipmentEventInput>, companyId: number) => unwrap<ShipmentEvent>(api.patch(`/v1/ops/shipment-events/${id}?${qp(companyId)}`, data)),
complete: (id: number, companyId: number) => unwrap<ShipmentEvent>(api.patch(`/v1/ops/shipment-events/${id}/complete?${qp(companyId)}`, {})),
remove: (id: number, companyId: number) => unwrap(api.delete(`/v1/ops/shipment-events/${id}?${qp(companyId)}`))
};
export const shipmentDocumentsAPI = {