@spree/docs 0.1.224 → 0.1.226

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,6 +28,8 @@ erDiagram
28
28
  StockLevel {
29
29
  integer count_on_hand
30
30
  integer allocated_count
31
+ integer reserved_count
32
+ integer incoming_count
31
33
  boolean backorderable
32
34
  }
33
35
  StockLocation {
@@ -37,15 +39,21 @@ erDiagram
37
39
  }
38
40
  ```
39
41
 
40
- ## The three numbers
42
+ ## The five numbers
41
43
 
42
- A stock level carries two counts, and a third is derived from them. Keeping them apart is what stops a warehouse from disagreeing with a website.
44
+ A stock level carries four counts, and a fifth is derived from them. Keeping them apart is what stops a warehouse from disagreeing with a website.
43
45
 
44
46
  | | What it means |
45
47
  |---|---|
46
48
  | `count_on_hand` | What is physically on the shelf, right now |
47
49
  | `allocated_count` | How much of that is already spoken for by orders not yet shipped |
48
- | **`available_count`** | `count_on_hand − allocated_count` — what's actually sellable |
50
+ | `reserved_count` | How much is held by checkouts still in progress |
51
+ | `incoming_count` | How much is on its way here — on a purchase order placed with a supplier, or a transfer already in transit |
52
+ | **`available_count`** | `count_on_hand − allocated_count` — what's actually sellable, before checkout holds |
53
+
54
+ Reserved and incoming are kept as counters rather than worked out on every read, because the Inventory page in the dashboard reads them for every row, many times a day, and only a handful of things change them: entering or leaving checkout moves reserved; marking a purchase order ordered or a transfer in transit adds to incoming, and receiving, closing, cancelling or reopening the document takes the remainder back off. Nothing else writes them. If a figure ever looks wrong, `rake spree:stock:recount_levels` recomputes both from their sources and reports every row it corrected — the same task the 6.0 upgrade runs to fill them in for existing stock.
55
+
56
+ A transfer counts as incoming from the moment it is marked in transit, not when it is drafted: until the van leaves, nothing is moving. Units a delivery rejects at the dock leave incoming too — they are recorded on the receipt, but they are not coming.
49
57
 
50
58
  > **NOTE:** **Selling an item does not reduce `count_on_hand`.** Placing an order raises `allocated_count`; the physical count only drops when the parcel actually ships.
51
59
  >
@@ -162,7 +170,7 @@ A reservation is a short, time-limited hold placed when a customer enters checko
162
170
  | They complete the order | The hold becomes a real allocation |
163
171
  | They abandon it | The hold expires and stock returns |
164
172
 
165
- Reservations never touch `count_on_hand` — they're a separate layer consulted when availability is read. A backorderable item is skipped entirely, since unlimited supply needs no holding.
173
+ Reservations never touch `count_on_hand` — they're a separate layer consulted when availability is read, and their total per stock level is what `reserved_count` shows. A backorderable item is skipped entirely, since unlimited supply needs no holding.
166
174
 
167
175
  How long the hold lasts is a **store setting**, because it's a decision about the checkout experience rather than a property of a warehouse. Reservations can also be switched off entirely.
168
176
 
@@ -272,6 +280,12 @@ await adminClient.purchaseOrders.close(order.id, { reason: 'Supplier out of stoc
272
280
  await adminClient.stockTransfers.close(transfer.id, { reason: 'Two fell off the van' })
273
281
  ```
274
282
 
283
+ ## The Inventory page
284
+
285
+ The dashboard's Inventory section opens on a list with one row per variant per location: on hand, allocated, reserved, available and incoming — the page uses the column names, with the location as a filter and SKU or product name as the search. Every figure on it is a column read off the stock level.
286
+
287
+ The on-hand figure is corrected in place — set it to a count, or adjust it by a delta, and say why — and the change lands in the stock history like any other adjustment. The incoming figure links to the two ways of making it grow: a transfer from another warehouse, or a purchase order from a supplier.
288
+
275
289
  ## Turning tracking off
276
290
 
277
291
  Some things don't need counting — a service, a made-to-order item, a digital download. Tracking can be switched off, and those variants are always purchasable.
@@ -130,6 +130,14 @@ bundle exec rake spree:backfill_order_markets
130
130
 
131
131
  Orders missing a market get the store default — `market` is required on carts and orders in 6.0.
132
132
 
133
+ ### Fill in the stock level counters
134
+
135
+ ```bash
136
+ bundle exec rake spree:stock:recount_levels
137
+ ```
138
+
139
+ `spree_stock_levels` gains `reserved_count` (units held by checkouts in progress) and `incoming_count` (units on their way on a purchase order placed with a supplier or a transfer in transit). Both are kept by the workflows that change them and start at zero on an existing install; this recomputes them from active reservations and open documents and prints every level it corrected. Until it runs, the dashboard's Inventory page shows zero reserved and incoming for stock that predates the upgrade. Safe to re-run at any time.
140
+
133
141
  ## The Cart/Order split
134
142
 
135
143
  The single biggest change. What used to be one `Spree::Order` living through checkout and beyond is now two models:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spree/docs",
3
- "version": "0.1.224",
3
+ "version": "0.1.226",
4
4
  "description": "Spree Commerce developer documentation for AI agents and local reference",
5
5
  "type": "module",
6
6
  "license": "CC-BY-4.0",