Cost sales first-in-first-out per branch instead of at an average
Cost of goods sold used each product's average buying price across the whole business. Ten jerrycans bought at 100 and ten at 140, with 15 sold, cost 1,800 instead of the 1,700 actually paid for those units; a branch that bought dearer was costed like one that bought cheaper; and units moved between branches lost their cost. src/lib/server/costing.ts replays the stock ledger in order with cost layers per branch and product: - purchases add stock at their unit cost; transfers carry the sending branch's layers to the receiving branch; opening stock and upward counts are valued at the product's purchase price at the time; - sales take the oldest layers first, and that is cost of goods sold; - stock written off by counts or adjustments is a separate "stock losses" figure, now deducted in net profit; - a sale recorded before its stock (stock gone negative) is costed by the next stock to arrive at that branch, even after the period ended; until then it is reported as units with no purchase cost on record. The report shows the method and a Stock losses card. Sales recorded before the stock ledger existed are counted as uncosted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+21
-4
@@ -98,7 +98,7 @@ seven findings and a retest plan. All of them are addressed on
|
||||
| F-04 No way back for deactivated products | Products page lists deactivated products under a toggle, with Reactivate. Deactivating warns about stock still on hand; that stock stays on the Stock page and can be transferred or counted out. |
|
||||
| F-05 Eggs shown as litres | Products carry a unit (L, ml, kg, g, pcs, tray, pack), chosen when the product is created and shown everywhere. |
|
||||
| F-06 No branch or staff removal | Staff: deactivate/reactivate (previous change). Branches: rename and deactivate/reactivate on the Branches page. A branch can only be deactivated once it has no stock and no active staff; its history stays in reports. |
|
||||
| F-07 Purchases shown as cost of goods | Cost of goods sold is now units sold x the product's average buying price. Purchases in the period are shown separately as "Stock purchased", with a "Cash surplus" line. |
|
||||
| F-07 Purchases shown as cost of goods | Cost of goods sold covers only units sold (now first-in-first-out per branch; see "Cost of goods sold" below). Purchases in the period are shown separately as "Stock purchased", with a "Cash surplus" line. |
|
||||
| STA-04 No invites | Staff and new branch managers can be invited: the owner or manager gets a one-time link (7 days) to send, and the person sets their own password. A new link can be made from Staff. |
|
||||
| CAT-12 Zero price, duplicates | Prices must be above zero; product names are unique per business, ignoring case. |
|
||||
| OFF-02 Local stock deduction | The till shows each product's stock and deducts every sale immediately, online or offline. |
|
||||
@@ -181,10 +181,27 @@ business's data.
|
||||
- Not guarded, by design: Business (the tenant itself, always looked up by
|
||||
the session's id), UserSession, MpesaCallbackLog and StockLock.
|
||||
|
||||
## Cost of goods sold
|
||||
|
||||
The profit report costs sales first-in-first-out, per branch
|
||||
(`src/lib/server/costing.ts`). It replays the stock ledger in order. Each
|
||||
branch keeps queues of stock at the price it was bought at, and a sale
|
||||
takes the oldest first.
|
||||
|
||||
- **Transfers carry their cost.** Stock moved between branches arrives at
|
||||
what the sending branch paid.
|
||||
- **Opening stock and upward counts** are valued at the product's purchase
|
||||
price at the time (or its first purchase price, if they came first).
|
||||
- **A sale recorded before its stock** (e.g. an offline sale before the
|
||||
purchase was entered) is costed by the next stock to arrive at that
|
||||
branch. Until then it counts as "units with no purchase cost on record".
|
||||
- **Stock written off** by counts or adjustments is shown as "Stock losses"
|
||||
and deducted in net profit. It is not part of cost of goods sold.
|
||||
- Each report replays the business's whole stock history. That is fast at
|
||||
pilot volumes; a business with years of history would want stored cost
|
||||
layers instead.
|
||||
|
||||
## Still open
|
||||
- **Cost of goods is an average.** It uses each product's average buying
|
||||
price across the business, not first-in-first-out per branch. Units sold
|
||||
with no purchase on record are counted and flagged, but have no cost.
|
||||
- **M-Pesa, if turned on.** Only one product per payment. A prompt that
|
||||
times out still needs a manual check before taking cash.
|
||||
- **Not modelled yet:** email verification at signup, sending invites by
|
||||
|
||||
Reference in New Issue
Block a user