Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Janblack07/OxygenDispatch/llms.txt

Use this file to discover all available pages before exploring further.

OxygenDispatch maintains a complete, immutable audit trail of every position change and status transition a cylinder undergoes. Each event is written as an InventoryMovement record that captures what happened, who performed the action, when it occurred, and which warehouse areas were involved. This audit log is the backbone of inventory accountability — from the moment a tank enters the warehouse to the moment it leaves for a client.

Warehouse areas

Warehouse areas are catalog entries managed under Settings → Warehouse Areas (/catalog/warehouse-areas) and can be extended or renamed by administrators. However, three area names are hard-coded into the business logic of TankTechnicalReviewService and the dispatch eligibility check in TankUnit. These areas must exist in the database with exactly these names for the system to operate correctly.
Area nameRole in the system
RecepciónEntry point for all newly generated tanks. Every tank starts here after batch generation.
Productos aprobadosTanks cleared by technical review and ready for dispatch. A tank must be in this area to be dispatchable.
Rechazos, devoluciones y retiro del mercadoDestination for tanks that fail technical review, are returned from clients, or are withdrawn from the market.
Even though warehouse areas are stored as catalog records, the names Aprobado (technical status) and Productos aprobados (warehouse area) are resolved by exact string match — after case normalization — inside TankUnit::isAvailableForDispatch() and TankTechnicalReviewService. Renaming these catalog entries will break dispatch eligibility checks.

Movement types

Every InventoryMovement record carries a type field backed by the App\Enums\MovementType integer enum:
enum MovementType: int
{
    case ENTRADA              = 1;
    case TRASLADO             = 2;
    case SALIDA               = 3;
    case CAMBIO_ESTADO_TECNICO = 4;
}
TypeValueWhen recorded
ENTRADA1A new tank unit is generated from a batch — its first appearance in inventory
TRASLADO2A tank is manually transferred between warehouse areas via POST /tanks/{tank}/transfer
SALIDA3A tank is dispatched to a client and leaves the warehouse
CAMBIO_ESTADO_TECNICO4A tank’s technical status changes (approved, rejected, or decommissioned)

Inventory movement record fields

Each InventoryMovement row captures the following fields:
FieldDescription
typeMovementType enum value — one of ENTRADA, TRASLADO, SALIDA, or CAMBIO_ESTADO_TECNICO
occurred_atTimestamp of when the event took place
tank_unit_idUUID of the affected TankUnit
from_area_idForeign key to the WarehouseArea the tank moved from (null for ENTRADA)
to_area_idForeign key to the WarehouseArea the tank moved to (null for SALIDA and some CAMBIO_ESTADO_TECNICO events)
batch_idThe batch the tank belongs to — always populated
reference_documentExternal document number linked to the event (e.g. reception order number, dispatch document)
performed_by_user_emailEmail of the authenticated user who triggered the action
notesFree-text context automatically generated by each service

Common movement flows

When a batch is generated and tank units are created, an ENTRADA movement is written for each tank. The tank has just arrived — it has no previous area — so from_area_id is null.
type            = ENTRADA
from_area_id    = null
to_area_id      = <id of "Recepción">
batch_id        = <batch id>
reference_document = <batch document_number>
notes           = "Entrada de lote. Lote: <document_number>. Vence: <expires_at>."
performed_by_user_email = <operator email>
After this movement, the tank’s warehouse_area is Recepción and its technical_status is Pendiente.
When a reviewer approves a tank through the tank-review screen, TankTechnicalReviewService::approve() records a CAMBIO_ESTADO_TECNICO movement. The tank moves from its current area (typically Recepción) to Productos aprobados.
type            = CAMBIO_ESTADO_TECNICO
from_area_id    = <id of "Recepción">
to_area_id      = <id of "Productos aprobados">
batch_id        = <batch id>
reference_document = <technicalReception.document_number>
notes           = "Revisión técnica aprobada. Estado técnico: Pendiente → Aprobado."
performed_by_user_email = <reviewer email>
The TankTechnicalReview record is also written at the same time, inside the same database transaction, so both records are always consistent.
When a dispatch order is confirmed, a SALIDA movement is written for each dispatched tank. The tank leaves the warehouse entirely, so there is no to_area_id.
type            = SALIDA
from_area_id    = <id of "Productos aprobados">
to_area_id      = null
batch_id        = <batch id>
reference_document = <dispatch document_number>
performed_by_user_email = <dispatcher email>
Simultaneously, the TankUnit record is updated: status = DESPACHADO and dispatched_at = now().
The full, filterable movement history for every tank in the system is available at Inventory → Movements (/inventory/movements). You can filter by date range, movement type, warehouse area, or individual tank serial to reconstruct exactly where a cylinder has been at any point in time — useful for regulatory audits and discrepancy investigations.

Build docs developers (and LLMs) love