Skip to main content

The inventory ledger

Route: /org/inventory/ledger · Module: org_inv_ledger — 3 permissions Permission to view: View Inventory Ledger


1. What the ledger is​

Every stock movement recorded by Inventory, in one append-only list. The module's real name is Inventory Audit View, and that is what it is: a journal, not a stock report.

Figure 1 — The ledger. 1 Export Data · 2 Detailed Filters.
Export Data does nothing

The button has no click handler. Nothing happens when you press it — no file, no error, no spinner.

The Export inventory ledger permission that appears to gate it is enforced nowhere either. The export feature does not exist in any form; there is no API endpoint behind it.

To get this data out, use the external API with the inventory:stock:read scope.


2. The six transaction types​

TypeSignWritten by
PURCHASE+Goods receipts
PRODUCTION_IN+Completing a production run
CONSUMPTION_OUT−The same completion, one per ingredient
SALE−Direct sales
ADJUSTMENT±Stock adjustments
WASTAGE−Wastage
Storefront orders are not in this list

A customer buying on the storefront produces no ledger row at all. Only the direct-sales screen writes SALE.

So the ledger is a complete record of what Inventory did, and an incomplete record of what happened to your stock. See How stock is counted.


3. Reading the table​

Figure 2 — Ledger rows. Note the blank Item Details on raw-material rows and the raw tags in Remarks.
ColumnNotes
Date & timeWhen the row was written
Item detailsProduct name, SKU and variation — blank on raw-material rows
Transaction typeColour-coded pill
MovementSigned quantity with unit; @ ₹price on sale rows
Audit infoAlways N/A / Ref: Manual
RemarksRaw, undecoded

Three things wrong with this table​

Raw-material rows show no item name

Every PURCHASE, CONSUMPTION_OUT, ADJUSTMENT and WASTAGE row against a raw material has an empty Item Details cell. The name is returned by the API — the page only ever renders the product name, never the raw-material name.

Roughly half the audit view is therefore anonymous: you can see that 3.5 KG of something was wasted, but not what.

The encoding tags are printed raw

Sales and maintenance pack their metadata into the remarks field and decode it on their own screens. The ledger does not decode it, so rows read:

[CUST:Ritwika Basu] [PH:9836500415] [PAY:card] [DISC:5] [TAX:5] [REASON:Expired stock] Past shelf life at morning check

On a tenant with real customers this column displays customer names and phone numbers in plain text to anyone holding ledger.view. Treat that as a privacy consideration when granting the permission.

Audit Info is always N/A

Every row shows N/A and Ref: Manual, including rows posted by an authenticated user through the UI. The created_by value is stored but never resolved to a name, so the audit view cannot tell you who did anything.


4. Finding a movement​

ToolMatches
SearchSKU, product or reference
Detailed FiltersType, date range and item scope
Figure 3 — Detailed Filters.
Production rows have no reference number to search

Receipts and sales carry a reference_no you chose. Production writes none — only a generated remark containing the order's first 8 characters, such as Production Order #fb75ec9f completion.

Searching for a production run means searching for that fragment.


5. Ordering and pagination​

Rows are returned newest first, 50 per page by default. The count in the footer is the total for the organisation, and the project filter is applied on top.


6. Permissions​

ActionPermissionEnforced?
Viewledger.view✅
Menuledger.menu✅
Exportledger.export❌ — and there is nothing to enforce it on

7. Troubleshooting​

SymptomCause
Empty ledgerNo project selected, or no operations have been recorded
Export does nothingCorrect — the button has no handler
Half the rows have no item nameRaw-material rows do not render their name
Remarks full of square bracketsThe ledger does not decode the encoding tags
A storefront order is missingStorefront orders never write here
Audit Info always N/Acreated_by is never resolved to a user
Balance disagrees with the Stock columnThey are different systems — see How stock is counted