# Lots and Quantities Language: `en` Mirror page: [lots-and-quantities.md](lots-and-quantities.md) Status: `partial migration` Last code verification: `2026-05-13` This page consolidates `BR-PT-LOT-001`, `BR-PT-LOT-002`, and `BR-PT-LOT-003`. Goal: drive quantity rules from a readable business definition, then secure them with Python guards and SQL diagnostics. ## Key Points
Operational SummaryA trade line has exactly one virtual lot. The virtual lot carries the global open balance, lot.qt carries the operational forecast, and physical lots consume that forecast.
Topic Short Rule
Entered quantity quantity_theorical is the business quantity.
Standard quantity quantity is a read-only technical counter.
Before physical lots quantity follows quantity_theorical.
After physical lots quantity reflects physical execution.
Open line Line amount uses quantity_theorical.
Finished line Line amount may switch back to physical execution.
Weight basis Purchase and sale may read two different states of the same lot.
Invoicing It chooses states from lot.qt.hist.
Controls Invariants are blocked in Python and auditable with SQL.
quantity_theorical
        |
        v
  virtual lot P1  --->  lot.qt forecast  --->  physical lot
        ^                    |
        |                    v
        +------ recalculation after consumption
## Consultant Rules ### BR-PT-LOT-001 - Virtual lot / forecast / physical life cycle
Moment Business Effect
Line creation One unique virtual lot is created.
Initialization The virtual lot takes quantity_theorical.
Forecast One open line is created in lot.qt.
Planning lot.qt may be split by sale, matching, transport, or shipment.
Physical add The physical lot consumes a precise lot.qt line.
After add lot.qt decreases and the virtual lot is recalculated.
Split of an open P1 balanceP1S1T1, P1S1T2, P1S2T3, P1S2T4
Key PointThese splits do not create several virtual lots. They only describe the forecast allocation of the open balance.
### BR-PT-LOT-002 - Contractual quantity, counter quantity, finished line
Situation Reference Quantity
User entry quantity_theorical
No physical lot quantity = quantity_theorical
Physical lots exist quantity = sum of physical lots
finished = False Amount based on quantity_theorical
finished = True Amount based on physical execution
Weight basis available Amount based on the contract wb.qt_type state
What finished Does Not Dofinished does not erase the contractual quantity, delete physical lots, or hide their PnL. It only means that the open balance may be ignored for execution calculations.
Reading of the Same Physical Lot Possible State
Purchase BL through purchase.purchase.wb.qt_type
Sale LR or Weight Report through sale.sale.wb.qt_type
Invoicing Independent choice in lot.qt.hist
### BR-PT-LOT-003 - Quantity Invariants
Invariant Formula
Conservation sum(physical lots) + virtual lot = quantity_theorical
Open forecast sum(non-zero lot.qt) = max(virtual lot, 0)
Case Rule
Purchase virtual lot Sum all lot.qt where lot_p = virtual lot, with or without lot_s.
Sale virtual lot Sum all lot.qt where lot_s = virtual lot, with or without lot_p.
lot.qt = 0 Ignored by checks; possible memory of a consumed forecast.
Negative virtual lot Allowed to compensate theoretical / executed gap; expected forecast = zero.
Non-zero orphan lot.qt Forbidden if neither lot_p nor lot_s is set.
### BR-PT-LOT-004 - Quantity history and weighing
Element Rule
lot.qt.hist Carries lot quantity states.
lot.lot form No direct state entry.
Update Only through Do weighing.
Virtual lot No manual packing.
Virtual packing fields lot_qt and lot_unit are not editable.
### Tolerances
Gap to ConfirmFull remaining-tolerance control in LotQt.add_physical_lots / LotQt.add_physical_lot still needs confirmation.
Point Target Rule
Level Global tolerance on line or contract.
Transport No independent tolerance per transport.
Over-execution Consumes remaining tolerance.
Under-execution Restores remaining tolerance.
## Developer Section ### Key Fields ### Line / Virtual Lot Creation ### Updating `quantity_theorical`
target_quantity = quantity_theorical - sum(converted physical lots)
free_quantity = target_quantity - sum(already matched or shipped lot.qt)
### Adding Physical Lots ### Removing Physical Lots ### Weighing / Quantity States ### Quantity Counter `quantity` ### Line Amount ### Python Guards ### SQL Diagnostic ## Nearby Tests