Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ElthonJohan/Sistema-MRP/llms.txt

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

The dispatch service converts a fulfilled or partially-reserved requirement into a physical stock movement. It follows a strict two-phase approach: all validations are performed first, and no database changes are applied until every check passes. A successful dispatch decrements Inventory.stock and Inventory.reserved across the principal warehouse’s budget records (FIFO), writes an OUT movement, and generates a GR-YYYYMMDD-{id:05d} guide number. Reversing a dispatch via delete_dispatch restores all affected stock and removes the linked receipt if one exists.

create_dispatch

create_dispatch(db, requirement_id, items, user_id=1) -> tuple[bool, str]
Creates a dispatch for a subset of items from an existing requirement. The function proceeds in two phases: phase 1 validates every item (quantity limits, reservation status, principal-warehouse stock), and phase 2 applies all changes atomically in a single commit. On success, a GR-YYYYMMDD-{dispatch_id:05d} guide number is generated and returned. The guide number is formatted as GR- followed by the UTC date of dispatch (YYYYMMDD) and the zero-padded dispatch ID (five digits). Example: GR-20250318-00042.
db
Session
required
Active SQLAlchemy session. Commits internally on success.
requirement_id
int
required
ID of the requirement being dispatched against.
items
object[]
required
Materials and quantities to dispatch. Each entry must correspond to a line item on the requirement.
[
  {"material_id": 1, "qty": 5},
  {"material_id": 2, "qty": 3}
]
user_id
int
default:"1"
ID of the user creating the dispatch. Recorded on the Dispatch record and the Movement log entries.
[0]
bool
True when the dispatch was created successfully.
[1]
str
On success: the guide number string (e.g. "GR-20250318-00042"). On failure: a descriptive error message.
Phase 1 — validation checks (no writes):
  • items list must not be empty.
  • Requirement and its associated warehouses must exist.
  • For each item: dispatched quantity must not exceed remaining unfulfilled quantity.
  • For each item: the requirement line item must have status reserved (not pending).
  • For each item: total principal-warehouse stock must be sufficient.
Phase 2 — atomic write:
  • Creates the Dispatch record and flushes to obtain an ID.
  • Assigns the guide number.
  • For each item: decrements stock and reserved across budget records in FIFO order.
  • Updates each RequirementItem.fulfilled_qty and status (fulfilled or partial).
  • Sets the parent Requirement.status to fulfilled or partial.
  • Writes Movement(type="OUT", reference_type="dispatch") entries.
from services.dispatch_service import create_dispatch

ok, result = create_dispatch(
    db,
    requirement_id=12,
    items=[
        {"material_id": 1, "qty": 5},
        {"material_id": 4, "qty": 8},
    ],
    user_id=3,
)

if ok:
    print(f"Dispatch created. Guide: {result}")
else:
    print(f"Dispatch failed: {result}")

get_dispatches

get_dispatches(db) -> list
Returns all Dispatch records from the database without filtering or pagination.
db
Session
required
Active SQLAlchemy session.
return
list
List of all Dispatch ORM objects.
from services.dispatch_service import get_dispatches

all_dispatches = get_dispatches(db)
print(f"{len(all_dispatches)} total dispatches")

get_dispatch_detail

get_dispatch_detail(db, dispatch_id) -> Dispatch
Retrieves a single Dispatch record by ID. Returns None when not found.
db
Session
required
Active SQLAlchemy session.
dispatch_id
int
required
ID of the dispatch to retrieve.
return
Dispatch
The Dispatch ORM object, including related items, requirement, and receipt via lazy loading. Returns None if no matching record exists.
from services.dispatch_service import get_dispatch_detail

dispatch = get_dispatch_detail(db, dispatch_id=42)
if dispatch:
    print(f"Guide: {dispatch.guia_number}, Items: {len(dispatch.items)}")

cancel_dispatch

cancel_dispatch(db, dispatch_id) -> bool
Marks a dispatch as cancelled and reverts stock at the obra warehouse. For each dispatch item, the quantity is added back to the obra inventory record linked to the requirement’s project.
This function contains a known bug in the RequirementItem status logic. When fulfilled_qty == 0 after the reversal, the status is incorrectly set to "fulfilled" instead of "pending". The correct guard at line 184 of dispatch_service.py reads:
if req_item.fulfilled_qty == 0:
    req_item.status = "fulfilled"   # BUG: should be "pending"
The condition is inverted. Until this is fixed, cancel_dispatch should be treated with caution for items that were dispatched in full.
db
Session
required
Active SQLAlchemy session. Commits internally.
dispatch_id
int
required
ID of the dispatch to cancel.
return
bool
True when the dispatch was found and cancelled; False otherwise.
from services.dispatch_service import cancel_dispatch

ok = cancel_dispatch(db, dispatch_id=42)
if not ok:
    print("Dispatch not found")

delete_dispatch

delete_dispatch(db, dispatch_id, owner_id) -> tuple[bool, str]
Permanently deletes a dispatch record and fully reverses its effects. The operation is scoped to owner_id so clients cannot delete dispatches belonging to other accounts. If the dispatch has an associated receipt, the receipt is deleted first. Reversal steps performed for each dispatch item:
  1. Restores stock and reserved on the principal-warehouse inventory record.
  2. If a receipt exists, decrements stock on the obra-warehouse inventory record (floored at zero).
  3. Decrements RequirementItem.fulfilled_qty and recalculates its status (fulfilled, partial, or reserved).
  4. Deletes all Movement records with reference_type="dispatch" and reference_id=dispatch_id.
  5. Deletes all DispatchItem records.
  6. Deletes the Dispatch record.
db
Session
required
Active SQLAlchemy session. Commits internally.
dispatch_id
int
required
ID of the dispatch to permanently delete.
owner_id
int
required
Client user ID. The dispatch is only returned for deletion when it belongs to a warehouse owned by this user.
[0]
bool
True when the dispatch was found and deleted; False when not found.
[1]
str
Empty string on success; "Despacho no encontrado." when not found.
from services.dispatch_service import delete_dispatch

ok, err = delete_dispatch(db, dispatch_id=42, owner_id=3)
if not ok:
    print("Error:", err)

Build docs developers (and LLMs) love