Introducción a la facturación 3PL
La cadena de facturación: partidas → tarifas → reglas por merchant → extractos, y las brechas actuales (cantidades manuales, sin UI de extractos aún).
La cadena de facturación#
Cadena: partidas de cargo → tarifas → reglas de facturación por merchant → generación de extractos/facturas (wms_merchant_invoices + líneas). Todo es de escritorio; no hay facturación en el móvil.
Partidas de cargo#
WMS → Billing → Partidas. Crear: code (único por organización) / nombre / categoría (8: storage, inbound, outbound, pick, pack, value_added, freight, other) / pricing_method (6: per_pallet_day, per_unit, per_order, per_weight, per_cubic_ft, flat) / unit_price / currency (por defecto USD) / uom / is_active.
Tarifas#
- WMS → Billing → Tarifas: nombre + merchant_id (NULL = global, aplica a todos) + versión + effective_date/expiry_date + is_active. Admite varias versiones.
- Cada línea ata una partida; unit_price_override vacío = usa el precio original. Una línea puede tener su propio effective/expiry (vacío = sigue la tarifa).
Reglas de facturación por merchant#
WMS → Billing → Reglas: una regla por merchant (única por organización×merchant), apuntando a un rate_sheet_id. Cambiar de versión = cambiar el rate_sheet_id.
Generar un extracto#
Llame a POST /api/wms/billing/invoices/generate; actualmente no hay página de generación en escritorio, los extractos se generan por API.
- Body: merchant_id, period_from, period_to (YYYY-MM-DD), rate_sheet_id opcional, quantities (uso, manual), notes.
- Resolución de tarifa: la pasada explícitamente gana; si no, se usa la regla activa del merchant. Sin regla → 400.
- Protección contra duplicados: un extracto del mismo período ya existente se rechaza (único por organización×merchant×período).
- Cálculo línea por línea (recalculable): unit_price = override ?? precio del ítem; qty de quantities (flat sin qty = 1 por defecto; líneas con qty 0 no se guardan); amount = round(qty × unit_price, 2). Cada línea lleva su fórmula para verificar a mano.
- Numeración: MINV-000001 en adelante (numeración atómica); el encabezado se guarda con status=draft más una instantánea de la tarifa, luego las líneas.
- Brechas conocidas: el extracto generado queda en draft; la transición sent/paid no está implementada; no hay páginas de escritorio de lista/detalle/generación (las APIs GET existen); sin vínculo con AR contable (acc_invoices); la moneda se transporta, no se convierte (Fase 1).