Skip to main content

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:

CampoCuándo
idId del DELIVERYNOTESDETAIL. Ausente en líneas extra que el mobile agrega en el momento
amount, elementIdSiempre
productIdPuede ser un array en líneas colapsadas por el mobile
serialNumber / deliveredSerialNumber / retiredSerialNumberSegún entregue, retire o ambas
deliveredProductId / retiredProductIdÍdem
changeTypeLa causa de cambio de la línea
needsDelivery / needsRetireBanderas 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 productId cuando 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 DELIVERYNOTESDETAIL sintéticos para cubrir la diferencia, en vez de fallar.
El array de productId hay que distribuirlo también al retirar

Un 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:

  1. busca el supply en el vehículo (asignando serial si es trackeable y no lo tenía),
  2. lo transfiere al paciente con sp_transfer_supply_to_entity,
  3. cierra los PATIENTSUPPLIES anteriores del mismo elemento,
  4. crea los PS nuevos.

Errores: SUPPLY_NOT_FOUND_FOR_DELIVERY, TRANSFER_ERROR: <detalle>.

sp_close_retirement — retiro (dType = 2)

  1. 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.
  2. Matchea contra los supplies del paciente (por serial cuando lo hay).
  3. Transfiere al vehículo en estado MTN (mantenimiento).
  4. Cierra los PATIENTSUPPLIES.
  5. 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.

  1. Computa tmp_visit_flags (needsDelivery / needsRetire) a partir del changeCause.
  2. Crea inventariables on-the-fly para lo que se retira sin registrar.
  3. Hace las transferencias bidireccionales: vehículo → paciente (entrega) y paciente → vehículo en MTN (retiro).
  4. Cierra los PS por dos caminos: por SUPPLYID y por patientSupplyId.
  5. 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 stock

Una 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:

TempQué lleva
tmp_result_detailsEl resultado por línea
tmp_transfer_resultsEl resultado de cada transferencia
tmp_affected_supply_idsLos supplies tocados, para los pasos finales
tmp_visit_flagsSolo 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.