Inventory

If your business buys things to resell, you need inventory accounting. Solid tracks quantity on hand, average or FIFO cost, and the cost-of-goods-sold journal entries that flow when items move out the door.

This page assumes General Ledger for terminology.

Items

Inventory is built on the items table, which has three flavors:

Item typeWhat it is
serviceTime, expertise — sold but not stocked. No quantity tracking.
inventoryPhysical goods you stock and resell. Tracks quantity on hand and cost.
non_inventoryPhysical goods you sell but don't stock — drop-ship, special order, custom builds. Tracks revenue and cost but not on-hand quantity.

Each item has:

  • Name + SKU + description
  • Income account — where revenue posts when the item sells
  • COGS account — where cost posts when the item leaves inventory (inventory items only)
  • Asset account — the inventory asset account (typically Inventory under Other Current Assets)
  • Sales price (default; per-line override on invoice)
  • Cost (default for non_inventory; computed from cost layers for inventory)
  • Cost method — FIFO or weighted-average (inventory items only — see below)

A single item flows through the books in three places: the sale (revenue + AR), the COGS posting (inventory asset down, COGS up), and reporting (units on hand, value on hand, sell-through rate).

Cost methods

Solid supports two cost methods per item. The choice matters for tax reporting and gross-margin accuracy:

FIFO — first in, first out

Each batch you buy has its own cost layer. When you sell, the system consumes the oldest cost layer first. Concrete example:

Buy 10 widgets at $5 each   → layer A: 10 × $5
Buy 10 widgets at $6 each   → layer B: 10 × $6
Sell 12 widgets:
  → consume all of layer A (10 × $5 = $50 COGS)
  → consume 2 of layer B (2 × $6 = $12 COGS)
  → total COGS for this sale: $62
  → remaining inventory: 8 × $6 = $48

FIFO is closer to reality for most businesses because old inventory is what physically gets sold first. It's also what GAAP and most tax authorities expect when prices are rising — it produces a higher reported income (and tax bill) than weighted-average in a rising-cost environment.

Weighted-average

Each purchase blends into a running average cost across all units on hand:

Buy 10 widgets at $5 each   → 10 × $5 = $50, avg cost $5.00
Buy 10 widgets at $6 each   → 20 widgets total, value $110, avg cost $5.50
Sell 12 widgets:
  → consume 12 × $5.50 = $66 COGS
  → remaining inventory: 8 × $5.50 = $44

Weighted-average is simpler in the books and produces smoother margin numbers across batches. Most small businesses pick weighted-average unless they have a specific reason for FIFO.

Switching methods

You can't mix methods on the same item. Switching from one to the other is a non-trivial operation — it requires recomputing every historical COGS posting under the new method and adjusting the inventory asset account. Solid supports the switch but the migration emits a journal entry for the cumulative difference, which you should review before posting.

The default for new items is average; change to fifo per item before any transactions hit it if FIFO is your preference.

Buying inventory

When you buy inventory, the journal entry credits the bank or AP (depending on whether you paid or owe), and debits the inventory asset:

Buy 100 widgets at $5 from Vendor X (paying with check)
DR  Inventory Asset            500
CR  Bank                       500

A new cost layer is created (or, for weighted-average items, the running average updates). Quantity on hand increases by 100.

The items table tracks this through journal_entry_lines.item_id, quantity, and unit_price_cents — these fields, added in migration 004, let any journal entry line be tagged as an item movement and quantity-tracked.

Selling inventory

When you sell inventory (via an invoice), Solid auto-generates two related entries:

  1. The invoice itself posts revenue and AR:
    DR  Accounts Receivable
    CR  Income (Sales)
    
  2. The COGS posting is automatic and links to the same source invoice:
    DR  Cost of Goods Sold
    CR  Inventory Asset
    

The COGS amount comes from the cost method — FIFO consumes oldest layers, weighted-average uses the current running average. You see both entries on the GL detail and they share a source-document link back to the invoice.

The same auto-COGS pattern applies to Sales Receipts (cash sales of inventory) and any other transaction type that moves an inventory item.

Purchase Orders

Purchase Orders capture intent to buy before the bill arrives. They don't post to the GL:

po_number              auto-generated
vendor_id              the supplier
date                   PO date
expected_date          when you expect delivery
status                 draft → approved → partially_received → received → billed → cancelled
memo                   notes
lines                  one or more (item, quantity, cost)

The status flow:

StatusWhat it means
draftStill being written
approvedIssued to the vendor
partially_receivedSome items have arrived; receipt entries link back to the PO
receivedAll items have arrived (no GL effect yet — receipt-only)
billedThe vendor's bill has been entered, matched against the PO
cancelledPO was cancelled before fulfillment

POs in Solid are an operational tool — they help you track what's on order, what's been received, and what's still expected. They're not journal entries. The actual financial posting happens when you receive items (DR Inventory / CR Accrued Liability or AP) and when you bill (DR Accrued / CR AP, or directly DR Inventory / CR AP if no accrual stage).

Inventory adjustments

When physical count doesn't match what Solid says — usually after a year-end count, sometimes after damage or theft — post an inventory adjustment of transaction_type = 'inventory_adjustment':

Quantity decrease (write-down):
DR  Inventory Loss / Shrinkage
CR  Inventory Asset

Quantity increase (write-up — found inventory):
DR  Inventory Asset
CR  Inventory Adjustment Income (or Inventory Loss reversed)

Adjustments specify item, quantity delta, and (for FIFO items) which layer to adjust against. The unit cost is computed from the layer or from the weighted average — you don't enter a unit cost on an adjustment, only the quantity and the offset account.

Reports

Inventory has two main reports:

  • Inventory Valuation — every inventory item with current quantity on hand and total value (FIFO: sum of remaining layers; weighted-average: quantity × average cost). One row per item.
  • Inventory Valuation Detail — every cost layer for FIFO items, or the running-average history for weighted-average items. Useful for auditing the COGS posting on a specific sale.

Both export to PDF and CSV.

Common gotchas

Quantity on hand is negative. Almost always a sale recorded before the receipt of the corresponding purchase (a sale on Tuesday from inventory bought on Wednesday). Backdate the purchase, or if the sale really did happen first (drop-ship), use a non_inventory item instead of inventory.

COGS is much higher (or lower) than expected after a price change. FIFO consumes oldest layers first; if you've been selling at a price set during low-cost layers and then a new high-cost batch arrives, COGS reflects the price you paid, not the new replacement cost. Check the Inventory Valuation Detail to see which layers are being consumed.

An inventory item's cost method change shows a big adjusting entry. Switching from weighted-average to FIFO (or vice versa) recomputes historical COGS under the new method and posts the cumulative difference as one entry. Review carefully before accepting; if you're unsure, post a tax-loss-question to your accountant first.

A purchase order is "received" but the GL doesn't show inventory. PO receipts are operational — they don't post to the GL. The GL update happens on the corresponding bill (or, in some workflows, a separate "Receive Goods" entry that accrues the liability). Check that you've entered the bill for the received items.

Year-end physical count is off by a few units. Normal — small shrinkage from breakage, miscounts, internal use. Post an inventory adjustment for the difference; in most cases the offset goes to a Cost of Goods Sold sub-account named Shrinkage so it shows on the P&L.

Cross-references