Skip to content

Historical Stock Balance

historical-stock-balance is the query behind the Stock Report applet’s balance-as-at-a-date screen — one row per item per location, computed as of a date_to you supply (“Date As” on the applet).

Path: POST /core2/tnt/dm/erp/reports/stock/historical-stock-balance/etl-ep Request body: StockReportInputDto as JSON Response envelope: StreamingPagingResponse — see the family page

See Applet Reports API for authentication and the shared envelope shapes.


Request fields

FieldTypeDefaultApplied by this query?
location_guidsSet<UUID>emptyYes — also determines the companies searched, see below
date_fromZonedDateTimenowNo — send it if you like, it’s ignored. The applet itself hardcodes 2022-01-01T00:00:00.000Z and never varies it; there’s no lower bound in the query the value could affect anyway.
date_toZonedDateTimenowYes — this is “Date As”. The query includes everything up to and including the full calendar day of date_to (internally: < date_to + 1 day), so a timestamp with a time-of-day component doesn’t trim same-day transactions.
keywordOptional<String>emptyYes
item_from, item_toOptional<String> eachemptyYes — set both together for an item-code range
item_typeSet<String>emptyYes
item_statusSet<String>emptyYes
item_category1_guids … item_category20_guidsSet<String> eachemptyYes
pre_order_item, require_delivery, require_production, consignment, free_shipping, basic_warrantyOptional<Boolean> eachempty (no filter)Yes
show_serialOptional<Boolean>emptyYes — adds a serials array per row; slower, only request it if you’re using it
company_guidsSet<UUID>emptyNo — read nowhere in this call path. The companies searched are derived from location_guids (LocationUow.grabCompanyGuidsBasedOnLocationGuids), not from this field.
txn_typeSet<String>emptyNo — hardcoded. This method always filters to PNS, ETL_SYNC_STOCK_BALANCE_CALIBRATION and ETL_SYNC_STOCK_DELTA_REPLICATION for the balance figure and PNS/RESET_MA for the cost figure. Whatever you send here is never read.
date_columnString"txn_date"No — not referenced by this query at all.
hide_voided_documents, include_sn_adjustment, inv_item_guids, option_balancevariousemptyNo — not referenced by this query. Present on the DTO for other StockReportController endpoints.
date_from is not optional to get right — it’s fixed, and you should fix it the same way. Always send "2022-01-01T00:00:00.000Z", matching what the applet itself sends on every search, so a future reader of your integration’s code isn’t misled into thinking it does something. It is accepted and parsed, just never placed in a WHERE clause anywhere in this query.

Server-side transforms already applied

Two things the applet does client-side are done for you before the response leaves the server:

  1. Zero-balance rows are dropped. The applet’s own default (showZeroBalance = false) is applied unconditionally — there is no request field to turn this off and get zero-balance rows back. If your integration specifically needs them, you cannot get them from this endpoint; query bl_inv_current_company_stock_balance directly instead.
  2. hist_ma_amount and hist_ma_price are added, computed as cost_ma_amount and cost_ma_amount / bal_qty respectively.

Cost basis: this is the one thing the endpoint does NOT replicate — you still have to

The applet’s “Calculate Base On” dropdown is never sent to the backend — same as on Sales Report By Document, it’s a purely client-side relabelling. But unlike that page, what it relabels here isn’t just a display fallback — it changes which raw field the applet’s hist_ma_amount/hist_ma_price columns actually show:

// what the applet does, client-side, for every row:
hist_ma_amount = row[selectedCostBasis + '_amount']   // e.g. row['cost_fifo_amount'] if FIFO is selected
hist_ma_price  = hist_ma_amount / row.bal_qty

where selectedCostBasis is cost_ma by default and one of cost_ma, cost_fifo, cost_wa, cost_lifo, cost_replacement, cost_manual depending on what the user picked.

This endpoint’s own hist_ma_amount/hist_ma_price are always MA-based (see above) — they match the applet’s output only when the applet’s “Calculate Base On” is left on its default, MA. If your integration needs to reproduce the applet under a different cost basis, ignore this endpoint’s hist_ma_* fields and compute your own from the raw cost_fifo_amount / cost_wa_amount / cost_lifo_amount fields, the same way the applet does. cost_replacement_amount and cost_manual_amount are not in this endpoint’s response at all — the underlying query never computes them — so “Replacement” and “Manual” cost bases cannot be reproduced from this endpoint under any circumstance; if a customer needs those, they need the raw bl_inv_current_company_stock_balance figures instead.

Response fields

FieldNotes
guid, guid_fi_mst_itemItem identity.
code, name, uomItem code, name, unit of measure.
category1_code … category10_code, category1_name … category10_nameItem category tree — 10 levels on this endpoint (the sales report joins 20).
bal_qtyBalance quantity as of date_to. Always non-zero (see zero-balance filtering above).
cost_ma_priceCurrent, live moving-average unit cost. Despite the report being “historical,” this specific field is not point-in-time — it reads today’s MA price, not the MA price as of date_to.
cost_ma_amount, cost_fifo_amount, cost_wa_amount, cost_lifo_amountCost-basis amounts, each computed as bal_qty × the corresponding per-unit cost as of date_to in the query (unlike cost_ma_price, these ARE point-in-time). cost_replacement_amount and cost_manual_amount do not exist on this endpoint.
hist_ma_amount, hist_ma_priceAdded by this endpoint — see Server-side transforms and the cost-basis warning above for exactly what these are and aren’t.
serialsPresent only when show_serial: true. Array of {serial_no, quantity, location_guid}.

Known data issue: some items have two conflicting balance rows

Some items can have two rows in bl_inv_current_company_stock_balance for the same item and company, under two different inv_item_guid values, with no deterministic ordering between them. This is a pre-existing condition in the source data — not something introduced by this endpoint, and not something this endpoint (or the applet itself) corrects, because the query this endpoint calls has no ROW_NUMBER()/dedup on that particular join, unlike every bl_inv_txn_line-based CTE earlier in the same method, which does. See this page’s sources: map for exactly where.

Practical effect: for an affected item, cost_ma_price (and anything derived from it) can come back as either of the two conflicting values on different calls, non-deterministically. This showed up during verification as the applet itself disagreeing with its own export across two pulls of the same item — so it is not specific to etl-ep; a frontend built on this endpoint has the same exposure the applet already has. There is nothing to work around on the client side; this needs a backend fix (add the missing ROW_NUMBER() partition) to resolve for good.


Filter dropdowns

POST /core2/tnt/dm/erp/drop-down/company/etl-ep       (narrows the Location dropdown)
POST /core2/tnt/dm/erp/drop-down/location/etl-ep
POST /core2/tnt/dm/erp/drop-down/label/etl-ep
POST /core2/tnt/dm/erp/drop-down/label-list/etl-ep

Body and response shape: see Applet Reports API → dropdowns.


Example

curl -X POST "https://api-etl.akaun.com/core2/tnt/dm/erp/reports/stock/historical-stock-balance/etl-ep" \
  -H "AccessId: YOUR_ACCESS_ID" \
  -H "AccessKey: YOUR_ACCESS_KEY" \
  -H "tenantCode: YOUR_TENANT_CODE" \
  -H "Content-Type: application/json" \
  -d '{
    "location_guids": ["6b8d1f42-7e35-4c09-ad81-1d4e8b2c5a70"],
    "date_from": "2022-01-01T00:00:00.000Z",
    "date_to": "2026-09-01T00:00:00.000Z"
  }'

Related

Last updated on