PRD: Stock Transfer
| Module | Inventory | PRD ID | PRD-TRF-001 |
| Status | No item | FEAT | TRF |
| Epic | — | Plane | — |
| Date | 2026-07-14 | Version | v1.0 |
| Packages | @nx/inventory | URD | TRF |
| Surface | Client · Owner/Mgr | ||
| Owner | Phát Nguyễn | ||
What a stock transfer is
A merchant can hold several inventory locations: a main store, a bar counter, a kitchen. Several merchants sit inside one organizer.
A transfer ticket is the document recording one move of goods from one location to another: which location they leave, which location they arrive at, who issues them, who receives them, and how much goes missing on the way.
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 - ReservedWhy a transfer is not a simple addition and subtraction
Goods do not arrive instantly. They leave the source this morning and reach the destination tomorrow afternoon. In between, they are at neither location.
- Deduct the source and credit the destination at the same instant: the destination sells goods that are not on its shelf.
- Deduct the source and credit nothing: the goods disappear from the books for the whole time they are on the road.
A transfer is therefore a process in several legs, and each leg has its own document.
One shipment, end to end
Move 100 cans from location A to location B. Issue them in two trips. The second trip loses 2 cans.
| What happens | On-hand A | Reserved A | Incoming B | On-hand B |
|---|---|---|---|---|
| Raise the ticket, not yet approved | 100 | 0 | 0 | 0 |
| Approve | 100 | 100 | 0 | 0 |
| Issue trip 1: 60 cans | 40 | 40 | 60 | 0 |
| Location B receives all 60 | 40 | 40 | 0 | 60 |
| Issue trip 2: 40 cans | 0 | 0 | 40 | 60 |
| Location B counts only 38 | 0 | 0 | 0 | 98 |
- Reserved at the source is the approved quantity minus what has been issued. Issue everything and it is back to 0.
- Incoming at the destination is the total issued minus the total received. Receive everything and it is back to 0.
- The destination cannot sell what is incoming. Goods have to arrive and be counted for real before they become available.
The easiest thing to get wrong
Goods that left the source location cannot silently disappear
Issue 40, location B counts 38. Those 2 cans have left location A and cannot be pulled back.
The raiser has to close the ticket. Closing raises an adjustment ticket recording the 2 cans lost, with a reason. Goods that go missing need a document recording that they went missing.
The consequence: a completed ticket is never edited and never deleted. A wrong figure is corrected by raising a new ticket. The stock book is append-only.
1. Goals & Non-goals
Goals
- Let a transfer name a merchant-and-location pair at both ends, and require the receiving end.
- Support transfers between two different merchants, and run a same-merchant transfer on exactly the same model.
- Let one parent take many issue tickets and many receipt tickets, so issuing over several trips and receiving over several deliveries is normal.
- Derive the parent's status from its child tickets, and show it in the words of the transfer business.
- Keep what is reserved at the source and what is incoming at the destination always correct, because both are computed from the child tickets rather than from a column somebody has to remember to update.
- Let the real goods be recorded: issuing more than planned and receiving more than issued are never blocked.
- Draw a clean line between closing a ticket (goods were lost, an adjustment ticket is raised) and cancelling one (nothing was lost), and never let goods in transit vanish silently.
- Give each person their own job: the raiser sees a single row, the destination merchant's stock keeper sees a single receive task.
Non-goals
- The inventory ticket lifecycle, the parent-child shape and the append-only rule at the general level (owned by TKT); this PRD only covers what is specific to a transfer.
- Goods ordered from a vendor but not yet delivered: a different concept, owned by purchase orders, and never added to incoming.
- Logistics: shipping arrangements, shipping cost, drivers, vehicle plates.
- Recomputing cost per location: cost is a single figure per merchant, see inventory valuation.
2. Success metrics
| Metric | Target / signal |
|---|---|
| Overselling goods in transit | No case where the destination makes goods it has not received available, or the source sells goods already promised to a transfer |
| The four numbers add up | The two locations' on-hand plus the incoming figure always match the real goods at every step of the ticket |
| Lost goods always have a document | Every quantity issued that never arrived has an adjustment ticket recording the loss with a reason |
| Multi-trip transfers need no workaround | Merchants issue in batches on a single ticket instead of raising several unrelated slips |
| Adoption of the transfer ticket | Multi-location merchants move goods through a ticket instead of hand-editing stock on two screens |
3. Personas & scenarios
| Persona | Goal in this feature |
|---|---|
| Owner / Manager | Raise transfers, track goods in transit, close the ticket when the goods do not all arrive |
| Source merchant's stock keeper | Pick the goods against the ticket, write an issue ticket per trip, know exactly how much is still to go |
| Destination merchant's stock keeper | Get exactly one "receive the goods" task, count the real goods, write a receipt ticket per delivery |
| Cashier | Never sell goods already promised to a transfer, and never sell goods that have not arrived |
Core scenario: the manager raises a transfer of 100 cans from Merchant A - Default location to Merchant B - Default location → once approved, the ticket reads "To ship" and the source reserves 100 cans, so available drops by 100 → Merchant A's keeper issues a first trip of 60 cans, the ticket reads "In transit" and the destination sees 60 incoming → Merchant B's keeper receives all 60 → the second trip issues the last 40 but only 38 are counted on arrival → the manager hits Close, and the system raises an adjustment ticket recording 2 cans lost with a reason.
4. User stories
| # | As a | I want | So that |
|---|---|---|---|
| 01 | manager | to raise a transfer naming the merchant and the location at both ends | goods never leave without the system knowing where they are going |
| 02 | manager | to move goods to another merchant in the same organizer | I can pour stock between selling points without hand-editing stock in two places |
| 03 | source merchant's stock keeper | to issue goods over several trips on the same ticket | a full truck can leave rather than waiting for the whole load to be gathered |
| 04 | destination merchant's stock keeper | to see exactly one task of my own, "receive 20 cans from Merchant A" | I never have to read somebody else's document |
| 05 | cashier at the source | goods promised to a transfer to be locked away immediately, no longer sellable | I do not sell goods already promised to another location |
| 06 | destination merchant's stock keeper | to see incoming goods on the stock screen without being able to sell them | I know what is coming without selling it early |
| 07 | manager | to record the real quantity even when it goes past the plan | the books reflect what actually happened |
| 08 | manager | to close the ticket once I know the goods are not coming | the loss is recorded with a reason instead of hanging forever |
| 09 | manager | to cancel a ticket while the goods have not moved | the reserved stock goes straight back to available |
5. Functional requirements
| # | Requirement | Status | URD ref |
|---|---|---|---|
FR-001 | The person in charge of stock raises a transfer ticket on the Client app. • Each end names which merchant and which inventory location - the two locations may belong to two different merchants. • The receiving location is mandatory. With no receiving location, the ticket cannot be saved. • At least one item, with its unit and a quantity greater than 0. A reason and a note are optional. • Once saved, the ticket carries a code of its own, and either end can look it up. | 🚧 | URD-TRF-001 |
FR-002 | A transfer between two merchants and a transfer inside one merchant run exactly the same way. • Two different merchants: each side owns its own child tickets. • One merchant: both child tickets belong to that merchant. • The user never picks a transfer mode. Naming both ends is enough, and the system has no special case for it. | 🚧 | URD-TRF-002 |
FR-003 | The transfer walks all five steps of the inventory ticket lifecycle, with only the wording changed to fit the trade. • Draft and Submitted keep their own words. • Approved shows as To ship. In progress shows as In transit. Completed shows as Received. • Only the display wording changes; no extra state is created. | 🚧 | URD-TRF-003 · URD-TKT-004 |
FR-004 | The transfer's status is decided by its child tickets. The detail screen has no button that sets the status by hand. | 🚧 | URD-TRF-004 |
FR-005 | Goods are issued over several trips. Each trip is one issue ticket. • The source keeper hits Issue goods, enters this trip's quantity, and completes it. • The issue ticket belongs to the source merchant and has only two steps, Draft and Completed. • On completion the source location's on-hand drops right away, and the inventory ledger gets a row. | 🚧 | URD-TRF-005 |
FR-006 | Goods are received over several deliveries. Each delivery is one receipt ticket. • The destination keeper hits Receive goods, enters the quantity actually counted, and completes it. • The receipt ticket belongs to the destination merchant and has only two steps, Draft and Completed. • On completion the destination location's on-hand rises, and the inventory ledger gets a row. | 🚧 | URD-TRF-006 |
FR-007 | What is reserved at the source is the approved quantity minus what has been issued. The system computes it; nobody types it. • Approve 100 and the source reserves 100. On-hand does not move, and available drops by 100 immediately. • Issue 60 and on-hand drops by 60 while the reservation falls to 40. Available does not move again, because it already dropped at approval. • Issue the last 40 and the reservation is back to 0. | 🚧 | URD-TRF-007 · URD-RSV-009 |
FR-008 | Looking at what is reserved tells you who is holding it. • Open an item's detail and expand the reservation to see "transfer ticket X holds N", sitting next to the sale orders that also hold stock. • When stock is stuck, the merchant knows immediately which ticket to go and unstick. | 🚧 | URD-RSV-004 · URD-RSV-005 |
FR-009 | What is incoming at the destination is the total issued minus the total received. Visible, but not yet sellable. • The incoming column stands on its own, next to on-hand, reserved and available. • Incoming never adds to available. Goods that have not reached the destination are not sellable. • Issue 60 then receive 60 and incoming is back to 0. Issue another 40 and incoming is 40. | 🚧 | URD-TRF-008 |
FR-010 | A planned quantity above what the source still holds cannot be approved. • Approval is where the system checks against the source's available. A quantity above it is blocked, with a message naming which item is short and how much is left. • An item with the oversell flag on is approved anyway, exactly as that flag intends. | 🚧 | URD-RSV-002 · URD-RSV-003 |
FR-011 | Issuing more than the planned quantity is allowed. The issue ticket records exactly what really left the location, and the system does not block it for being larger than the quantity named on the transfer. | 🚧 | URD-TRF-009 |
FR-012 | Receiving more than the total issued is allowed. The receipt ticket records exactly what was counted at the destination, and the system does not block it for being larger than the total issued. | 🚧 | URD-TRF-010 |
FR-013 | When not everything arrives, the raiser hits Close. Closing raises an adjustment ticket recording the loss. • The Close button only shows while the total issued exceeds the total received. • The system confirms the quantity to be written off and requires a reason before it closes. • After closing: the destination's incoming drops to 0, the adjustment ticket sits on the source's ledger with the reason and the transfer's code, and the transfer reads Received. | 🚧 | URD-TRF-011 · URD-TKT-013 |
FR-014 | Cancelling is allowed, and cancelling only stops what was never issued. • The reservation at the source is released in full and available goes back up. Nothing was lost, so no adjustment ticket is raised. • Cancelling while goods are still incoming makes the system spell out that this quantity will be written off as a loss, and it only cancels once the user confirms. • The full rule table for every cancel and close case is in §7.1. | 🚧 | URD-TRF-012 · URD-TKT-014 |
FR-015 | Every correction is a new ticket. An old ticket is never edited. • A completed issue or receipt ticket has no Edit button and no Delete button - not even after the transfer is closed or cancelled. • A wrong figure is fixed with another issue trip, another receipt, or an adjustment ticket. The old ticket stays exactly as it was written. | 🚧 | URD-TRF-013 · URD-TKT-008 |
FR-016 | Goods on the road are the source's risk. And incoming is never mixed up with goods on order from a vendor. • Goods lost or damaged in transit are the source location's loss, until the destination confirms receipt. • Incoming only counts goods moving between two locations inside the system. Goods ordered from a vendor but not yet delivered never add to it. | 🚧 | URD-TRF-014 · URD-TRF-015 |
FR-017 | A transfer never changes the cost. Only the quantity shifts between two locations; the cost stays a single figure for the whole merchant. | 🚧 | URD-TRF-016 |
FR-018 | Each person only sees their own job. • The raiser sees a single row: "Transfer 20 cans, Merchant A - Default location to Merchant B - Default location, in transit". The issue and receipt tickets are detail inside it. • The destination keeper sees a single task: "receive 20 cans from Merchant A". They never see the sending side's document. | 🚧 | URD-TRF-017 |
FR-019 | The transfer list: look up by row, filter, open the detail. • Each row shows the ticket code, the merchant and location at both ends, the line count, the status and the creation date. • Filter by status, by merchant and location at either end, and by date range. • Open a ticket and every line shows all five numbers: planned, total issued, total received, reserved, incoming. | 🚧 | URD-TRF-018 |
FR-020 | Three groups of people can each approve and close a transfer that touches two merchants. • Anyone at the sending merchant. • Anyone at the receiving merchant. • Manager level or above at the headquarters merchant. • Whoever presses a button is recorded on the ticket. Leaving it open does not mean losing the trail. | 🚧 | URD-TRF-019 |
5.1 Acceptance criteria
- Raise a transfer of 100 cans from
Merchant A - Default locationtoMerchant B - Default locationwith one line → the ticket saves and shows its code. - Leave the destination merchant or the destination location blank and hit save → the form errors and refuses to save.
- Pick the same merchant-and-location pair at both ends → the form errors and refuses to save.
- Raise a transfer between two merchants, then one between two locations of a single merchant → both go through exactly the same screens, and no field asks for a "transfer mode".
- Approve the transfer → the ticket reads "To ship"; issue the first trip → it reads "In transit"; receive everything → it reads "Received".
- Open the transfer detail → there is no field that lets you set the transfer's status by hand.
- The source has 300 on-hand and 300 available; approve a transfer of 100 → on-hand is still 300, reserved is 100, available is 200.
- Open the reservation breakdown for that item at the source → a row shows "transfer ticket X holds 100 units".
- Issue a first trip of 60 cans → the source has on-hand 240, reserved 40, available still 200; the destination shows 60 incoming.
- Open the destination's stock screen → the incoming column shows 60 and available is unchanged; try to sell past what the destination really holds → it is blocked.
- The destination merchant's keeper receives all 60 cans → the destination's on-hand goes up by 60 and incoming drops to 0; the source is unchanged.
- Issue the second trip of 40 cans → the source has on-hand 200 and reserved 0; the destination shows 40 incoming.
- The receiver counts only 38 cans and records 38 → the destination's on-hand goes up by 38 and incoming is 2.
- An item has 10 available at the source; raise a transfer of 15 and hit approve → the system blocks it, naming the item that is short and the 10 that are left.
- Turn the oversell flag on for that item and approve the transfer of 15 again → it approves normally.
- A transfer planned at 100, the keeper issues 110 cans → the system accepts it, the issue ticket completes at 110, with no block.
- The total issued is 110, the receiver counts 115 and records 115 → the system accepts it and the receipt ticket completes at 115.
- A transfer has issued 100 and received only 98; hit Close → the system confirms a loss of 2 and requires a reason; on confirmation an adjustment ticket for 2 cans is raised with that reason and the transfer's code, the destination's incoming drops to 0, and the transfer reads "Received".
- Open the source's inventory ledger after that → the 2-can loss adjustment row is there, pointing back at the transfer's code.
- A transfer has just been approved with nothing issued; hit Cancel → all 100 cans reserved at the source are released, available is back to 300, neither location's on-hand moves, and no adjustment ticket is raised.
- A transfer has issued 60 and the destination has received 38; hit Cancel → the system spells out that 22 cans in transit will be written off and requires confirmation; on confirmation the unissued 40 are released and an adjustment ticket for 22 cans is raised.
- A transfer has issued 60 and the destination has received all 60; hit Cancel → the unissued 40 are released and no adjustment ticket is raised, because nothing was lost.
- Open a completed issue ticket → every field is locked, with no Edit button and no Delete button.
- A completed receipt ticket has the wrong figure → the only way to bring the figure back to the truth is a new adjustment ticket; the old receipt ticket stays as it was.
- Everything is lost in transit and the destination receives nothing → the destination's on-hand does not move and the source adds nothing back; the raiser closes the ticket and the whole issued quantity becomes a loss on an adjustment ticket.
- Raise a purchase order for 30 cans from a vendor with nothing delivered → the receiving location's incoming column still shows 0.
- Check an item's cost before and after a completed transfer → the cost is unchanged.
- The raiser opens the transfer list → exactly one row shows: "Transfer 20 cans, Merchant A - Default location to Merchant B - Default location, in transit".
- The destination merchant's keeper opens their own task list → exactly one task shows, "receive 20 cans from Merchant A", and the source merchant's issue ticket is nowhere in sight.
- In the transfer list, filter by status "In transit" and source merchant "Merchant A" → only the tickets matching both conditions show.
- Open a transfer that is mid-flight → every line shows the planned quantity, the total issued, the total received, what is reserved and what is incoming.
- The receiving merchant's stock keeper opens a transfer raised by the sending merchant → they can approve it, and their name shows on the ticket.
- A manager at the headquarters merchant opens that same transfer → they can close it, even though they belong to neither the sending nor the receiving merchant.
6. Non-functional requirements
| Aspect | Requirement |
|---|---|
| Stock integrity | Completing an issue or a receipt ticket is one all-or-nothing write: stock and the inventory ledger are both written, or nothing is |
| Derived numbers | Reserved at the source and incoming at the destination are always recomputable from the set of child tickets, so they can never drift from the documents |
| Duplicate protection | Completing a child ticket twice still writes the ledger once; quantities are never moved twice |
| Append-only | No business path edits or deletes a completed issue or receipt ticket |
| Parallel with selling | Selling at the source runs alongside a live transfer without breaking the four numbers; the invariant available = on-hand minus reserved holds at every instant |
| Cross-merchant scoping | An issue ticket is readable and writable only by the source merchant, a receipt ticket only by the destination merchant; the parent is readable from both ends, but each side only sees its own part |
| Traceability | Every movement a transfer creates is written to the inventory ledger with the ticket code and a reason, so any ledger row traces back to its transfer |
| i18n | Transfer status labels and the reason list are displayed bilingually |
7. UX & flows
The path of a transfer, from raising it to settling it:
Two ends, two people, two sets of documents:
7.1 The cancel and close rule table
A transfer planned at 100 cans. "Reserved" is the approved quantity minus what has been issued. "Incoming" is the total issued minus the total received. Cancelling stops what was never issued; closing settles what was issued and never arrived. In every case below, completed issue and receipt tickets stay exactly as they are, never edited and never deleted.
| Case | Reserved at source | On-hand at source | Incoming at destination | On-hand at destination | Adjustment ticket for the loss |
|---|---|---|---|---|---|
| Cancel while still Draft | Nothing reserved, unchanged | Unchanged | 0 | Unchanged | No |
| Cancel while Submitted, nobody has approved | Nothing reserved, unchanged | Unchanged | 0 | Unchanged | No |
| Cancel while Approved (To ship), nothing issued yet | Release all 100, back to 0 | Unchanged | 0 | Unchanged | No - no goods ever left |
| Cancel after issuing 60, destination received all 60 | Release the remaining 40, back to 0 | Already down 60 at issue, drops no further | 0 | Already up 60 at receipt, changes no further | No - everything issued arrived |
| Cancel after issuing 60, destination received only 38 | Release the remaining 40, back to 0 | Already down 60, drops no further | 22 is settled, back to 0 | Already up 38, changes no further | Yes - an adjustment ticket for 22 cans lost |
| Cancel after issuing all 100, destination received only 90 | Already back to 0 once everything was issued | Already down 100 | 10 is settled, back to 0 | Already up 90 | Yes - an adjustment ticket for 10 cans lost |
| Cancel after issuing 60, destination has received nothing | Release the remaining 40, back to 0 | Already down 60, drops no further | 60 is settled, back to 0 | Unchanged | Yes - an adjustment ticket for 60 cans lost |
| Close after issuing 100 and receiving only 98, waiting no longer | 0 | Already down 100 | 2 is settled, back to 0 | Already up 98 | Yes - an adjustment ticket for 2 cans lost |
| The ticket already Completed (all 100 received) | 0 | Already down 100 | 0 | Already up 100 | No - and there is no cancel button left; a correction means a new ticket |
Raising the ticket, issuing and receiving all live in the Inventory area of the Client app. The raiser sees one row for one move; the destination merchant's keeper sees exactly one "receive the goods" task in their own list. Incoming shows as its own column on the stock screen, next to on-hand, reserved and available.
8. Data & domain
| Concept | Role |
|---|---|
| Transfer ticket (parent) | The document carrying the intent: it fixes the merchant and location at both ends, the list of goods and the planned quantities |
| Issue ticket (child) | The document for one trip of goods leaving the source location, owned by the source merchant |
| Receipt ticket (child) | The document for one delivery of goods arriving at the destination location, owned by the destination merchant |
| Ticket line | One item: planned quantity, total issued, total received, what is reserved, what is incoming |
| Reserved at the source | The approved quantity minus what has been issued, naming which transfer holds how much |
| Incoming at the destination | The total issued minus the total received; visible but never sellable |
| 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 issued, releases the reservation, and raises no adjustment ticket |
| Loss adjustment ticket | The inventory ticket raised on closing, carrying the lost quantity, a reason and the transfer's code |
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 | TKT Inventory tickets | the shared lifecycle, the parent-child shape, the append-only rule and the closing rule. |
| 02 | LOC Inventory locations | both ends of the ticket are active locations, each belonging to a merchant. |
| 03 | STK Stock items & levels | the four numbers on-hand, reserved, available and incoming are the foundation of the whole transfer flow. |
| 04 | RSV Reservation | a transfer's reservation uses the same named-holder mechanism as a sale order's. |
| 05 | LDG Inventory ledger | where every movement the child tickets create is written. |
| 06 | VAL Inventory valuation | cost is a per-merchant figure, which is why a transfer never touches money. |
Assumptions
| # | Assumption | What breaks if it is wrong |
|---|---|---|
| 01 | 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 model in this version does not provide. |
| 02 | The receiver at the destination counts the real goods before writing a receipt ticket, rather than rubber-stamping it. | Rubber-stamping the planned quantity buries the loss, and a later stock count carries the whole variance with no way to trace where it came from. |
| 03 | The raiser is the person best placed to decide when the goods are no longer coming. | If nobody settles them, the ticket hangs forever, the destination's incoming figure swells and nobody clears it. |
| 04 | Goods issued that never arrive are really gone, not merely late. | Close too early when the goods are merely late and the loss is recorded wrongly; the goods that turn up later become surplus with no origin. |
10. Release plan & criteria
| Aspect | Plan |
|---|---|
| Phase | P2 (Inventory) - see the URD feature catalog |
| Rollout | Every merchant with two or more locations, and every organizer with two or more merchants; no feature flag |
| Migration | There is no legacy transfer data to convert; the first transfer starts from current stock |
| Release criteria | A merchant-and-location pair can be picked at both ends; one parent runs many issue and many receipt tickets; the four numbers match the acceptance scenario at both ends; every case in the §7.1 rule table behaves as written; a completed child ticket cannot be edited |
| Monitoring | Transfers by status, tickets closed and total quantity written off per month, tickets hanging with goods in transit too long, count of over-issues and over-receipts |
References
- URD: Stock transfer
- Related: Inventory tickets · Stock items & levels · Reservation & oversell prevention · Inventory ledger · Stock count · Inventory valuation
- Module: Inventory - URD
- Developer: @nx/inventory · domain model
Risks & open questions
| # | Risk / question | Mitigation / status |
|---|---|---|
| 01 | Who may approve and who may close a transfer that touches two merchants | Settled: 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. |
| 02 | The destination rubber-stamps a receipt without counting, burying the loss in its own stock | The receiver has to enter the counted quantity on every delivery (FR-006); any gap always leaves a trace through the adjustment ticket raised on close (FR-013) |
| 03 | A ticket is forgotten with goods hanging in "incoming" forever | Open: a warning is needed for tickets with goods in transit beyond a configurable number of days |
| 04 | A user confuses Cancel with Close and loses track of the shrinkage | Cancelling with goods still incoming forces the user to confirm what will be written off (FR-014); the full rule table is in §7.1 |
| 05 | Receiving more than was issued inflates the destination's stock with no explanation | Recording the real count is allowed (FR-012); the excess shows plainly on the ticket detail and is reconciled through a stock count |
| 06 | An item with the oversell flag gets transferred past its stock, taking the source's on-hand negative | Accepted, exactly as that flag intends (FR-010); the negative figure shows plainly on the stock screen and is settled through a stock count |
FAQ
| # | Question | Answer |
|---|---|---|
| 01 | Can I move goods between two merchants? | Yes, and it is a normal operation. Raising a transfer means picking all four things: which merchant and which location issues, and which merchant and which location receives. Moving goods between two locations of one merchant works identically, the only difference being that both ends belong to the same merchant. |
| 02 | Why does the destination not get the goods in stock the moment the source issues them? | Because they are on the truck, not on the destination's shelf. Credit them immediately and the destination's cashier can sell goods that have not arrived. The incoming figure solves exactly that: visible for planning, but never added to available. |
| 03 | Why does the source's on-hand not drop while the ticket is To ship? | Because the goods are still on the source's shelf and a counter walking the aisle would find them. What drops is available, because those goods are promised to the transfer. That is the general rule: the seller looks at available, the counter looks at on-hand. |
| 04 | Does a transfer have to go out in one load? | No. Issue as many trips as you like and receive as many deliveries as you like. Each trip is an issue ticket owned by the source merchant, each delivery a receipt ticket owned by the destination merchant. What has not been issued stays reserved at the source, and you always see how much is left to go. |
| 05 | What if I issue more than the ticket says? | That is fine. Record what really went on the truck. Receiving more than what was issued is fine too. The number on the ticket is the plan, and the goods are the goods - the books have to reflect what actually happened. |
| 06 | Two cans are missing - where are they? | In the destination's incoming figure, until you decide. If they are still on the way, wait. If you know they are gone, hit Close: the system raises an adjustment ticket recording 2 cans lost with a reason, and incoming drops to 0. The source bears the risk in transit, so goods lost on the road are the source's loss. |
| 07 | How is closing different from cancelling? | Cancelling stops what was never issued: the goods are still on the source's shelf, so the reservation is simply released and nothing is lost. Closing settles what was issued and never arrived: the goods left and are not coming back, so they are a loss and always raise an adjustment ticket. And if you cancel while goods are still in transit, the system tells you plainly that the in-transit quantity still has to be written off - goods are never allowed to vanish silently. |
| 08 | I wrote the wrong figure on an issue ticket - how do I fix it? | You do not. A completed child ticket is final, with no edit and no delete. To bring the figure back to the truth, raise another ticket: another issue trip, another receipt, or an adjustment. Fixing a mistake means writing another slip, not tearing up the old one. |
| 09 | Does a transfer change an item's cost? | No. Cost is a single figure per merchant, not per location. A transfer only shifts quantity and never touches money. Cost only changes when goods are received at a new price. |