Cierre de remito
finances.sp_close_delivery_note_v2 es el dispatcher: recibe el remito y el JSON de líneas que
mandó el cliente, resuelve estados, y delega en el sub-SP que corresponda según el tipo de remito.
Firma
CALL finances.sp_close_delivery_note_v2(
pId, -- id del remito
userId, -- quién cierra
p_lines, -- JSON con las líneas entregadas / retiradas
p_source_entity_id, -- de dónde sale el stock (vehículo)
p_source_entity_code
);
Lo invoca src/services/v3/DeliveryNoteServiceV3.ts.
El JSON de líneas
Cada línea del array lleva, según el caso:
| Campo | Cuándo |
|---|---|
id | Id del DELIVERYNOTESDETAIL. Ausente en líneas extra que el mobile agrega en el momento |
amount, elementId | Siempre |
productId | Puede ser un array en líneas colapsadas por el mobile |
serialNumber / deliveredSerialNumber / retiredSerialNumber | Según entregue, retire o ambas |
deliveredProductId / retiredProductId | Ídem |
changeType | La causa de cambio de la línea |
needsDelivery / needsRetire | Banderas calculadas para la visita |
La bifurcación
Un tipo desconocido devuelve UNKNOWN_DELIVERY_NOTE_TYPE.
§3B — líneas colapsadas y sobre-entrega
Es la sección que más cuesta entender y la que más bugs concentró.
- Colapsado: BullStock puede mandar una sola línea con un array de
productIdcuando el operario entregó varias unidades de productos distintos contra la misma línea del remito. El SP la expande a una línea por producto. - Sobre-entrega: si se entregó más de lo aceptado, el SP crea
DELIVERYNOTESDETAILsintéticos para cubrir la diferencia, en vez de fallar.
productId hay que distribuirlo también al retirarUn bug real: §3B distribuía el array a deliveredProductId pero no a retiredProductId, y los
retiros colapsados fallaban con SUPPLY_NOT_FOUND_FOR_RETIRE. Ya está corregido, pero si tocás §3B
verificá que los dos caminos reciban la distribución.
Los tres sub-SPs
sp_close_delivery — entrega (dType = 0)
El más simple. Por cada línea:
- busca el supply en el vehículo (asignando serial si es trackeable y no lo tenía),
- lo transfiere al paciente con
sp_transfer_supply_to_entity, - cierra los
PATIENTSUPPLIESanteriores del mismo elemento, - crea los PS nuevos.
Errores: SUPPLY_NOT_FOUND_FOR_DELIVERY, TRANSFER_ERROR: <detalle>.
sp_close_retirement — retiro (dType = 2)
- Crea supplies on-the-fly para los inventariables que el paciente devuelve pero que nunca se
registraron, apareándolos 1:1 contra los PS huérfanos con
ROW_NUMBER. - Matchea contra los supplies del paciente (por serial cuando lo hay).
- Transfiere al vehículo en estado MTN (mantenimiento).
- Cierra los
PATIENTSUPPLIES. - Reclasifica genéricos seriados por prefijo de serie.
Errores: SUPPLY_NOT_FOUND_FOR_RETIRE, UNREGISTERED_SUPPLY_NO_PRODUCT,
RETIRE_TRANSFER_ERROR, DUPLICATE_ONFLY_RETIRE_SERIAL.
sp_close_visit — visita técnica (dType = 1)
El más complejo: combina lo de entrega y lo de retiro, y decide por línea según la causa de cambio.
- Computa
tmp_visit_flags(needsDelivery/needsRetire) a partir delchangeCause. - Crea inventariables on-the-fly para lo que se retira sin registrar.
- Hace las transferencias bidireccionales: vehículo → paciente (entrega) y paciente → vehículo en MTN (retiro).
- Cierra los PS por dos caminos: por
SUPPLYIDy porpatientSupplyId. - Reclasifica genéricos.
Errores: VISIT_SUPPLY_NOT_FOUND_FOR_DELIVERY, VISIT_SUPPLY_NOT_FOUND_FOR_RETIRE,
VISIT_DELIVERY_TRANSFER_ERROR, VISIT_RETIRE_TRANSFER_ERROR.
OTHER y NOACTION no tocan stockUna línea de visita con causa OTHER o NOACTION no debe cerrar el PATIENTSUPPLIES
referenciado: no se retiró nada. Faltaba el filtro por needsRetire en §12 y se cerraban PS que
seguían vigentes. Es el tipo de detalle que hay que tener presente al agregar una causa nueva.
Contrato de tablas temporales
Los tres sub-SPs comparten con el dispatcher un contrato de temps:
| Temp | Qué lleva |
|---|---|
tmp_result_details | El resultado por línea |
tmp_transfer_results | El resultado de cada transferencia |
tmp_affected_supply_ids | Los supplies tocados, para los pasos finales |
tmp_visit_flags | Solo en visita: needsDelivery / needsRetire por línea |
Si agregás una sección que necesite datos de otra, pasalos por acá — no por variables de sesión.
Documentación operativa detallada
Cada uno de estos SPs tiene una skill dedicada en oxitesa-backend/.claude/skills/, con la
sección por sección, todos los códigos de error, los bugs históricos y sus fixes:
sp-close-delivery-note-v2 · sp-close-delivery · sp-close-visit · sp-close-retirement ·
sp-accept-delivery-note · sp-transfer-supply-to-entity · sp-validate-stocks-v2 ·
tests-close-delivery-note
Esa es la referencia canónica para depurar. Esta página es el mapa conceptual.