PRD: Inventory Tickets
| Module | Inventory | PRD ID | PRD-TKT-001 |
| Status | Superseded | FEAT | TKT |
| Epic | — | Plane | — |
| Date | 2026-07-14 | Version | v1.0 |
| Packages | @nx/inventory | URD | TKT |
| Surface | Client · Owner/Mgr | ||
| Owner | Phát Nguyễn | ||
What an inventory ticket is
An inventory ticket is the document behind every stock change outside the sale flow: goods in, goods out, or a stock figure that needs correcting. The raiser picks exactly one of nine types - purchase request, goods receipt, stock transfer, internal issue, adjustment, cycle count, vendor return, customer return, write-off/disposal.
A merchant raises the ticket on the Client app, for one or two inventory locations depending on the type. One transfer can touch two merchants sitting inside the same organizer.
This is the shared frame. Stock transfer and stock count are two ticket types inside this frame, not two separate mechanisms.
The four numbers in stock
Lifted from Stock locations & levels so there is no need to open another PRD. Every item at every location carries four numbers:
| Number | What the system calls it | Meaning |
|---|---|---|
| On-hand | on-hand | Goods physically sitting in the location |
| Reserved | reserved | Already promised to another document, no longer sellable to anyone else |
| Available | available | The part still sellable |
| Incoming | incoming | Left the source location, not yet arrived at the destination |
The invariant, true at every moment:
Available = On-hand - ReservedOnce a ticket is approved, the promised goods sit in reserved. Only when a child ticket completes does on-hand change.
Why every stock change needs a document behind it
Stock figures are not allowed to move on their own. Every time a number changes there has to be a document behind it, with someone who raised it and someone who approved it. That is how a merchant explains why there are 60 cases on the shelf today and not 100.
Without a document, every stock change outside the sale flow has to be typed straight into the stock table: open the Stock screen, overwrite the quantity, and no trace is left of who changed it or why. Receiving a shipment, writing off a spoiled case of milk, returning a faulty batch to the vendor: all of it looks identical in the system, just a number that got overwritten.
One goods receipt, end to end
The location holds 500 cases. Receive 100 more. This is where the most important rule of the ticket frame shows itself: stock does not budge until the final step.
| What happens | Ticket status | On-hand |
|---|---|---|
| Draft a receipt for 100 cases | Draft | 500 |
| Submit for approval | Submitted | 500 |
| The owner approves | Approved | 500 |
| The stock keeper starts receiving | In progress | 500 |
| Record 100 received, hit complete | Completed | 600 |
- Approving means agreeing the work can be done, not that it has been done. If the goods are not on the shelf yet but stock has already gone up, the figure on the Stock screen is no longer the real one.
- Only at completion does stock change and does the inventory ledger get a row carrying the reason and the ticket code.
- The wording changes with the ticket type. A stock transfer calls Approved To ship, In progress In transit, Completed Received. Underneath it is still one single set of states.
- A large move keeps the intent on the parent ticket, while the child tickets record each trip out and each delivery in. The parent's status is derived from its children.
The easiest thing to get wrong
A completed ticket is final: no edit, no delete
Hit complete by mistake, type 50 where it should have said 60, pick the wrong reason - there is no Edit button and no Delete button, not even when the parent is later closed or cancelled.
The only way to bring the figure back to the truth is to raise a new compensating ticket: another issue trip, another receipt, or an adjustment. Fixing a mistake means writing another slip, not tearing up the old one.
Because of this rule, stock history is never rewritten behind anyone's back. And goods that left a location and never arrived do not silently disappear either: the raiser hits Close, and closing raises an adjustment ticket recording exactly that loss, with a reason.
1. Goals & Non-goals
Goals
- Give the merchant an inventory ticket book on the Client app: raise a ticket, browse the list, open the detail, submit, approve, execute, complete, close, cancel.
- Define one lifecycle for all nine ticket types, and spell out which type walks which part of it.
- Let each type relabel its statuses in the words of its own business without spawning a second set of states.
- Enforce the rule "stock only moves when a ticket completes" as real system behaviour, not as a convention.
- Build the one-parent, many-issues, many-receipts shape, so executing in batches and having two merchants involved is normal.
- Draw a clean line between closing a ticket (goods were lost, an adjustment ticket is raised) and cancelling one (nothing was lost).
- Guarantee the frame is append-only: a completed child ticket is never edited and never deleted.
Non-goals
- The rules specific to stock transfer: the four numbers at both ends, goods in transit, the detailed cancel-and-close rule table (owned by TRF).
- The rules specific to stock count: capturing the baseline, counting while sales run, applying the variance (owned by CNT).
- The structure and rules of purchase orders: price, minimum order quantity, reconciliation with the vendor (owned by PO).
- How inventory valuation is computed on receipt (owned by VAL) and how lots are picked on issue (owned by LSE).
- Stock deduction on the sale flow: selling reserves first and deducts later, and does not go through an inventory ticket.
2. Success metrics
| Metric | Target / signal |
|---|---|
| Stock changes are traceable to a source | Every stock movement outside of selling points back to an inventory ticket with a raiser |
| The overwrite habit disappears | The number of times a merchant edits a quantity directly on the Stock screen trends toward zero once the ticket book is live |
| Right numbers, no double counting | Total quantity written to the inventory ledger matches the total actually issued and received on completed tickets |
| Lost goods always have a document | Every quantity that was issued and never arrived has an adjustment ticket recording the loss; nothing vanishes silently |
| No stuck tickets | The share of tickets sitting too long in Submitted or In progress trends down |
3. Personas & scenarios
| Persona | Goal in this feature |
|---|---|
| Owner | Approve tickets, close a ticket when goods do not all arrive, see who received what, who wrote off what, and why stock changed |
| Manager / Stock keeper | Raise tickets, record what was actually issued and received on each batch, hit complete once the goods are on the shelf |
| System | Derive the parent status from its child tickets, write the inventory ledger exactly once when a child completes, raise the adjustment ticket when the parent is closed |
Core scenario: the stock keeper raises a transfer of 100 cases from Merchant A - Default location to Merchant B - Default location → submits it → the owner approves, the ticket reads "To ship" and the source location reserves 100 cases → the truck runs twice and the source-side keeper writes two issue tickets, 60 then 40 → the destination receives twice, recording 60 then 38 → 2 cases never turn up, the raiser hits Close, and the system raises an adjustment ticket recording 2 cases lost with a reason.
4. User stories
| # | As a | I want | So that |
|---|---|---|---|
| 01 | stock keeper | to raise a ticket naming the kind of job, both ends and the list of goods | every stock change comes with a document instead of an overwritten number |
| 02 | merchant owner | to approve a ticket before it is executed | nobody can change my stock behind my back |
| 03 | merchant owner | to be sure a ticket that was just drafted or just approved does not touch stock | the figure on the Stock screen is always the real figure on the shelf |
| 04 | stock keeper | to record what was really issued and really received even when it differs from the plan | the books reflect what actually happened |
| 05 | stock keeper | to issue goods in several trips on the same ticket | one job does not turn into three unrelated slips |
| 06 | merchant owner | to close a ticket once I know the goods are not coming | the missing quantity is recorded as a loss with a reason instead of hanging forever |
| 07 | merchant owner | to cancel a ticket I raised by mistake while the goods have not moved | the reserved stock goes straight back to selling |
| 08 | merchant owner | to know for certain that nobody can edit a completed ticket | my stock history is never rewritten behind my back |
5. Functional requirements
| # | Requirement | Status | URD ref |
|---|---|---|---|
FR-001 | An inventory ticket is the document for one instance of goods in, goods out or a stock correction, and the raiser picks exactly one of nine types at creation. • Purchase request - a request to buy more, which does not touch stock. • Goods receipt - goods arriving into a location from outside. • Stock transfer - goods moving from one location to another. • Internal issue - goods leaving a location for internal use, not for sale. • Adjustment - correcting the stock figure to match reality, with a reason. • Cycle count - counting real goods and applying the variance. • Vendor return - goods travelling back to the vendor. • Customer return - goods a customer brings back, taken into a location. • Write-off/disposal - damaged, expired or discarded goods. • The type is fixed at creation and cannot be changed afterwards. | 🔶 | URD-TKT-001 |
FR-002 | All nine ticket types share exactly one lifecycle, and the user can only press the button for the next step. • Draft - the ticket is being written, everything is editable. • Submitted - the ticket has gone out for approval, its content is locked. • Approved - whoever holds the right has signed off, the ticket is ready to execute. • In progress - goods are actually being received, issued or counted. • Completed - the work is done. • A ticket can be cancelled from any step before completion. No step can be skipped. | 🚧 | URD-TKT-002 |
FR-003 | Each ticket type only walks the part of the lifecycle it needs, and no type invents an extra step. • Adjustment: Draft → Completed. The screen shows no Submit and no Approve button. • Cycle count: Draft → In progress → Completed, with no separate approval step. • Stock transfer: walks all five steps. | 🚧 | URD-TKT-003 |
FR-004 | The status labels on screen are per ticket type, even though there is a single set of states underneath. • A stock transfer shows Approved as To ship, In progress as In transit, Completed as Received. • A cycle count shows In progress as Counting, Completed as Applied. • The status filter in the ticket book uses the wording of the type being filtered. | 🚧 | URD-TKT-004 |
FR-005 | Stock only changes when the ticket reaches Completed. • Drafting, submitting, approving and starting execution never add or subtract a single unit. • Opening the Stock screen while the ticket is Approved still shows the old figure. | 🚧 | URD-TKT-005 |
FR-006 | The parent ticket carries the intent, and its status is derived from its child tickets. • The parent records both ends of the move - which merchant, which location - along with the list of goods and the planned quantities. • One parent takes many issue tickets and many receipt tickets; it is never boxed into exactly one pair. • The parent's detail screen has no button or field that sets its status by hand. | 🚧 | URD-TKT-006 |
FR-007 | A child ticket is the execution document and belongs to the merchant at the end where it sits. • An issue ticket belongs to the source merchant; a receipt ticket belongs to the destination merchant. • A child ticket has only two steps, Draft and Completed, because approval already happened on the parent. • Completing one child writes only its own share of stock and leaves untouched what the other children have not done yet. | 🚧 | URD-TKT-007 |
FR-008 | The inventory ticket frame is append-only, never overwrite. • A completed child ticket has no Edit button and no Delete button, not even when the parent is later closed or cancelled. • A correction is a new compensating ticket: another issue trip, another receipt, or an adjustment. The old ticket stays exactly as it was written. | 🚧 | URD-TKT-008 |
FR-009 | A ticket carries a header, filled at creation and editable while the ticket is still a Draft. • Ticket code - system-generated, unique, used to look the ticket up and to refer to it elsewhere. • The issuing end and the receiving end - each end picks a merchant and a location. Every type shows only the ends it needs: a goods receipt has a receiving end only, a write-off has an issuing end only. • Counterparty - a vendor or a customer, shown only for the types that have one. • Reason - picked from a predefined list, mandatory on adjustment and write-off/disposal tickets. • Free-text note - optional. | 🔶 | URD-TKT-009 |
FR-010 | Every line on the ticket names an item, a unit and a quantity, and carries its own line status. • Item - a product variant or a material. • Unit - picked from that item's own units. The system converts to the base unit, and the user never enters a factor. • The planned quantity is entered when the ticket is raised; the actual quantity is recorded during execution. • Lot and expiry show for items under lot control. Unit price shows on goods receipt and vendor return tickets. • Line status - pending, processing, completed, cancelled - so one ticket can hold finished and unfinished lines at the same time. | 🔶 | URD-TKT-010 |
FR-011 | When a ticket reaches Completed, every line writes exactly one inventory ledger row. • The ledger row records the figure before, the change, the figure after, the reason and the source ticket code. • Processing the ticket again does not produce a second row for the same line, and stock is not moved twice. | 🚧 | URD-TKT-011 |
FR-012 | An actual quantity that differs from the planned quantity never blocks completion. • Issuing less than planned, issuing more than planned, receiving less than what was issued, receiving more than what was issued: all four are allowed. • The ticket completes at the real quantity and stock moves by the real quantity, never forced back to the planned one. | 🚧 | URD-TKT-012 |
FR-013 | The raiser hits Close when goods went out and did not all arrive, and closing raises an adjustment ticket recording the loss. • The Close button only shows on the parent, and only while the total issued exceeds the total received. • The system confirms the quantity that will be written off and requires a reason before it closes. • The adjustment ticket carries the exact lost quantity, the chosen reason and the parent's code. A closed ticket cannot be reopened. | 🚧 | URD-TKT-013 |
FR-014 | Cancelling and closing are two different things, and the interface says so plainly. • Cancelling only stops the planned quantity that was never executed: it releases the reservation, nothing is lost, and no adjustment ticket is raised. • Closing settles goods that left a location and never arrived: that quantity is a loss and always raises an adjustment ticket. • Cancelling a parent while goods are still in transit makes the system spell out the quantity that will be written off as a loss, and it only cancels once the user confirms. | 🚧 | URD-TKT-014 |
FR-015 | The inventory ticket book on the Client app lists the merchant's tickets, newest first. • Each row shows the ticket code, the ticket type, the location involved, the status, the raiser and the creation date. • Filter by ticket type, by status, by location and by date range. • Search by ticket code. | 🚧 | URD-TKT-015 |
FR-016 | The ticket detail records the trail of every status change. • Each step stores the timestamp and who pressed the button: on submit, on approve, on start of execution, on completion, on close, on cancellation. • That trail shows up right on the ticket detail screen, with nothing to hunt for elsewhere. | 🚧 | URD-TKT-016 |
FR-017 | Inventory tickets are per-merchant data. • A user only sees and acts on tickets belonging to the merchant they are currently working in. • When a move touches two merchants, each side only sees its own child ticket and never the other side's document. | 🔶 | URD-TKT-017 |
FR-018 | Whoever raised the ticket sees a single row in the list and never has to learn another concept. • That row says the whole job: how much is moving, from where to where, and which step it is at. • The child tickets live inside the detail screen as a timeline of what has been done: which trip went out on which day and how much, and how much came in on each delivery. | 🚧 | URD-TKT-018 |
5.1 Acceptance criteria
- Open the inventory ticket book on the Client app and hit create → the list offers exactly nine ticket types, no more and no less.
- Create a ticket, save it, then reopen it → the type field is locked and cannot be switched to another type.
- Open any Draft ticket → only the button for the next step is offered, never a Complete button.
- Raise a goods receipt ticket, submit and approve it, then look for a way back to Draft → no button steps the ticket backwards.
- Raise an adjustment ticket → the screen offers a Complete button only, with no Submit and no Approve.
- Raise a cycle count ticket → the screen offers Start counting and then Apply result, with no separate approval step.
- Raise a stock transfer ticket → the screen offers all five steps plus Cancel.
- Approve a stock transfer ticket and open the ticket book → the ticket reads "To ship"; issue the goods and reopen → it reads "In transit".
- Filter the ticket book by type Stock transfer → the status filter offers exactly To ship, In transit, Received.
- Raise a goods receipt ticket for 100 cases, submit and approve → open the Stock screen for that location → the on-hand figure is unchanged.
- On that same ticket, start execution, record 100 received and hit complete → on-hand at that location goes up by exactly 100 cases.
- Open any parent ticket detail → there is no field or button that sets the parent's status by hand.
- Raise a transfer of 100 cases and issue a first trip of 60 → the parent moves to "In transit" on its own, with nobody pressing a status button on the parent.
- On the same ticket, issue a second trip of 40 and receive three times → the parent takes both issue tickets and all three receipt tickets, with no block saying it already has a pair.
- Sign in as the source merchant and open the issue ticket → it can be edited and completed; open the destination merchant's receipt ticket → it is not in this merchant's list at all.
- Complete the first issue trip of 60 cases → the source location's on-hand drops by exactly 60, and the 40 cases of the later trip are not in the ledger yet.
- Open a completed child ticket → every field is locked, with no Edit button and no Delete button.
- An issue ticket completed at 60 when it should have said 50 → the only way to fix the figure is a new adjustment ticket; the old issue ticket stays exactly as it was written.
- Create a ticket → the ticket code is generated and shows on the header immediately; create a second → its code differs from the first.
- Create a goods receipt ticket → the form asks for a receiving end only; switch to a write-off/disposal → the form asks for an issuing end only.
- Create a stock transfer ticket → the form asks for all four things: source merchant, source location, destination merchant, destination location.
- Create an adjustment ticket, leave the reason empty and hit complete → the system blocks it and asks for a reason.
- Add a line and pick the unit "case" for an item stocked in "cans" → no field asks for a conversion factor; complete the ticket → on-hand goes up by the matching number of cans.
- Add a line for an item under lot control → the form shows the lot and expiry fields; pick an item with no lot control → those two fields disappear.
- Raise a ticket with two lines, complete one and cancel the other → each line shows its own status.
- Open the inventory ledger for the item just received → there is exactly one receipt row, showing the figure before, the change of 100, the figure after, the reason and the ticket code.
- Hit complete again on a completed ticket → no further ledger row is written and stock does not go up by 100 a second time.
- Raise a transfer of 100 cases and issue 110 → the system accepts it, the issue ticket completes at 110, with no block.
- The destination counts 115 cases while the total issued is 110 → the system accepts it and the receipt ticket completes at 115.
- A transfer of 100 cases has issued 60 and received 38; the raiser hits Close → the system confirms a loss of 22 and requires a reason; on confirmation, an adjustment ticket for 22 cases is raised with that reason and the parent's code.
- Reopen the ticket that was just closed → there is no reopen button.
- A transfer of 100 cases has just been approved with nothing issued; hit Cancel → all 100 cases reserved at the source are released, and no adjustment ticket is raised.
- A transfer has issued 60 and received 38; hit Cancel → the system spells out that 22 cases in transit will be written off as a loss and requires confirmation before cancelling.
- In the ticket book, filter by type "Write-off/disposal" and status "Completed" → the list only holds completed write-off tickets.
- Type a ticket code into the search box → that exact ticket comes up.
- Open a ticket that has walked the whole lifecycle → the timestamp and the person's name show for each of submit, approve, execute and complete.
- The person who raised a transfer opens the ticket book → exactly one row shows for that job, for example "Transfer 20 cans, Merchant A - Default location to Merchant B - Default location, in transit".
- Open that row's detail → the issue and receipt tickets show as a timeline inside: which trip went out on which day and how much, and how much came in on each delivery.
- Switch to a different merchant and open the ticket book → none of the previous merchant's tickets are visible.
6. Non-functional requirements
| Aspect | Requirement |
|---|---|
| Stock integrity | Completing a child ticket is one all-or-nothing write: either the whole ticket writes stock and the ledger successfully, or nothing is written; there is no half-done state |
| Duplicate protection | Every line has a unique business key on its inventory ledger row, enforced at the database layer; two simultaneous presses of complete still write only one row |
| Append-only | No business path edits or deletes a completed child ticket; every correction is a new record |
| No status skipping | A status change has to match the ticket's current status; if two people press at once only one succeeds, and the other is told the ticket has already moved on |
| Derived parent status | The parent's status is recomputed from its set of children at read time, so it can never drift from what the children actually say |
| Merchant scoping | Every child ticket is confined to the merchant that owns it; on a parent that touches two merchants, each side can only read and write its own part |
| Traceability | Every status change stores the timestamp and the operator, and cannot be edited afterwards |
| i18n | Ticket type labels, per-type status labels and the reason list are displayed bilingually |
7. UX & flows
The shared lifecycle of an inventory ticket, and where stock actually moves:
One parent, many children, and a parent status derived from them:
The inventory ticket book lives in the Client app, in the Inventory menu group, next to the Stock screen and the Locations screen. Whoever raised a ticket sees a single row for a single job. The child tickets show inside the detail screen as a timeline, and nobody has to learn another concept to read it.
8. Data & domain
| Concept | Role |
|---|---|
| Inventory ticket (parent) | The order slip carrying the intent of one instance of goods in, goods out or a correction; its status is derived from its children |
| Issue ticket (child) | The document for one time goods left a location, owned by the source merchant; on completion the source's on-hand drops |
| Receipt ticket (child) | The document for one time goods arrived at a location, owned by the destination merchant; on completion the destination's on-hand rises |
| Ticket type | One of nine: purchase request, goods receipt, stock transfer, internal issue, adjustment, cycle count, vendor return, customer return, write-off/disposal |
| Ticket status | Draft, Submitted, Approved, In progress, Completed, Cancelled, Closed - displayed in the wording of each ticket type |
| Ticket line | One item on the ticket, with its unit, planned quantity, actual quantity, lot, expiry and its own status |
| Closing | The raiser's action that settles goods issued but never arrived, and raises an adjustment ticket recording the loss |
| Cancelling | The action that stops the planned quantity never executed, releases the reservation, and raises no adjustment ticket |
| Reason | The label explaining why stock changed, carried from the ticket down onto the inventory ledger row |
| Counterparty | The vendor or the customer attached to the ticket, depending on the type |
Conceptual level only - the full schema and invariants live in the inventory domain model.
9. Dependencies & assumptions
Depends on
| # | Feature | What it depends on |
|---|---|---|
| 01 | LOC Inventory locations | each end of a ticket points at one active location. |
| 02 | STK Stock items & levels | where the on-hand figure is actually moved when a child ticket completes. |
| 03 | RSV Reservation | goods approved but not yet issued are held at the source through the shared reservation mechanism. |
| 04 | LDG Inventory ledger | where every completed line leaves a row behind. |
| 05 | UOM Units of measure & conversion | lines are entered in a buying or selling unit and the system converts to the base unit. |
| 06 | LSE Lots & expiry | lines for items under lot control also carry a lot and an expiry date. |
| 07 | VEN Vendors and customers | the counterparty on goods receipt, vendor return and customer return tickets. |
Assumptions
| # | Assumption | What breaks if it is wrong |
|---|---|---|
| 01 | Merchants accept one approval step before stock moves. In a small merchant the raiser and the approver can be the same person. | If merchants find the approval step fussy they go back to overwriting the figure on the Stock screen, and the whole traceability value of the ticket frame is lost. |
| 02 | An actual quantity differing from the plan is a normal part of the trade, not an error to block. | Block the variance and the stock keeper types the planned number to get past the form, so the books reflect what was supposed to happen rather than what did. |
| 03 | Goods issued that never arrive are really gone, and the raiser is the person best placed to decide when to settle them. | If nobody settles them the ticket hangs forever with goods in transit; settle too early when the goods are merely late and the loss is recorded wrongly, and the goods that turn up later become surplus with no origin. |
| 04 | Two merchants moving goods to each other sit inside the same organizer, so the two sides trust each other at the business level. | Moving goods outside the organizer needs approval at both ends and much tighter control, which the parent-child model in this version does not provide. |
10. Release plan & criteria
| Aspect | Plan |
|---|---|
| Phase | P2 (Inventory - document frame) - see the URD feature catalog |
| Rollout | All merchants; the inventory ticket book opens alongside the existing Stock screen |
| Migration | There is no legacy ticket data to move; current stock stands as the opening figure, and every change from here on goes through a ticket |
| Release criteria | All nine types can be raised from the Client app; each type walks its own part of the lifecycle with its own wording; stock only moves at completion; one parent runs many issue and many receipt tickets; closing raises exactly one adjustment ticket; a completed child ticket cannot be edited |
| Monitoring | Tickets raised per type, tickets cancelled, tickets closed and the total quantity written off, average time from submit to approve, number of direct stock edits on the Stock screen |
References
- URD: Inventory tickets
- Related: Stock transfer · Stock count · Inventory ledger · Stock items & levels · Reservation & oversell prevention · Purchase orders
- Module: Inventory - URD
- Developer: @nx/inventory · domain model
Risks & open questions
| # | Risk / question | Mitigation / status |
|---|---|---|
| 01 | Two people hit complete on the same ticket and stock moves twice | A unique business key on the inventory ledger row, enforced at the database layer, plus a status change that has to match the current status (FR-011, §6) |
| 02 | The raiser never closes the ticket and lost goods hang in "incoming" forever | Open: a warning is needed for tickets with goods in transit beyond a configurable number of days |
| 03 | A user confuses Cancel with Close and loses track of the shrinkage | Both buttons spell out their consequence before acting; cancelling with goods in transit forces the user to confirm the quantity that will be written off (FR-014) |
| 04 | Who may approve and who may close a ticket that touches two merchants | Ratified: anyone at the sending merchant, anyone at the receiving merchant, and manager level or above at the headquarters merchant can all do it. Deliberately left open, not locked down in this release. |
| 05 | A small merchant finds the five-step lifecycle fussy and goes back to overwriting the figure | The simple types already skip steps: an adjustment has only Draft and Completed (FR-003) |
| 06 | A user picks the wrong ticket type and cannot change it | The type is fixed at creation; the fix is to cancel the draft and raise it again (FR-001, FR-014) |
FAQ
| # | Question | Answer |
|---|---|---|
| 01 | Why does stock not move the moment I approve a ticket? | Because approving means agreeing that the work can be done, not that it has been done. If the goods are not on the shelf yet but stock has already gone up, the figure on the Stock screen is no longer the real one. Only when complete is pressed, meaning the goods have really come in or gone out, does stock move. |
| 02 | Nine types but only one lifecycle, is that not fussy? | No, because each type only walks the part it needs. An adjustment has two steps: write it, complete it. A cycle count skips approval. Only a stock transfer walks all five, because that is the job that genuinely needs someone to sign off before goods leave a location. |
| 03 | Why does a stock transfer read "To ship" instead of "Approved"? | Because talking to a stock keeper in the words of the trade is easier to follow. Underneath it is still the Approved step of the shared lifecycle: one state, relabelled for its context. There is no second set of states. |
| 04 | What are parent and child tickets, and do I need to care? | No. You see one row for one job, for example "Transfer 20 cans, Location A to Location B, in transit". Open it and inside is a timeline: which trip went out and how much, which delivery came in and how much. You do not have to learn another word to read it. |
| 05 | Will the system block me if I issue more than the ticket says? | No. Record what really left the location and the system accepts it. Receiving more than what was issued is the same. The number on the ticket is the plan, and the goods are the goods. The books have to reflect what happened, not what was supposed to happen. |
| 06 | Goods went out and never arrived, what do I do? | Hit Close. The system confirms how much is missing, asks you for a reason, then raises an adjustment ticket recording exactly that loss. Missing goods get recorded as missing, with a document, instead of hanging in limbo. |
| 07 | How is closing different from cancelling? | Cancelling stops what was never done: the goods are still on the shelf, so the reservation is simply released, nothing is lost, and no adjustment ticket is raised. Closing settles what was done and never arrived: the goods left the location and are not coming back, so they are a loss and need an adjustment ticket recording it. |
| 08 | What if I hit complete by mistake? | A completed ticket cannot be edited and cannot be deleted. To bring the figure back to the truth, raise a new adjustment ticket with a clear reason. Fixing a mistake means writing another slip, not tearing up the old one, which is how stock history stays impossible to rewrite. |