← All manuals Operator Guide for this screen IM2

Inventory ABC Analysis

Inventory ABC Analysis
Technical Spec Ver 1 Updated 2026-09-06 Matches the live screen

Inventory ABC Analysis — Technical Spec

Screen + job registry: app/im2.py (ABC_JOBS, _abc_worker, routes below). Report engine: app/abc_report.py. Template: app/templates/abc.html. QuickBooks access: app/qb.py (QBO, the droplet's own Intuit app).

A port of skills/qb_inventory_activity/scripts/{inv_pull,build_costed_report}.py — same methodology, same layout, same cost-basis priority.

Routes

MethodPathNotes
GET/reports/abcScreen. Passes can_write_abc = can(user, "abc_write").
POST/reports/abc/runJSON body {a_pct, b_pct, include_on_hand, window_days, update_im2}{"job": <hex>}.
GET/reports/abc/status/{job_id}`{"state": running\done\error, "message": ...}`.
GET/reports/abc/file/{job_id}xlsx stream; 404 unless state == 'done'.

All four depend on current_user — any signed-in role can run the report. Only abc_write (admin) may set update_im2; the run route 403s otherwise, and the select is not rendered for non-admins.

Validation on /run

Job registry

ABC_JOBS is a plain in-process dict, one entry per run: {state, message, user, started, filename, blob}. Entries older than 7200 s are dropped on the next /run. The xlsx lives in memory in job["blob"] — nothing is written to disk and every job is lost on app restart. _abc_worker runs on a daemon threading.Thread and writes progress strings into job["message"]; the page polls status every 2 s.

Pull (abc_report.pull)

_page() pages 100 at a time via qbo.query:

CreditMemo is pulled but never consumed in build() — see limits.

Math (abc_report.build)

Workbook

Two sheets, Summary moved to the front. Item Detail columns A–O as listed in the operator page; header style _head(); freeze D2; autofilter A1:O{max}; columns F,G,H,I,J,K hidden. Summary carries the A/B/C band table, a Cost Source rollup (counts + on-hand value) and a Notes block (totals, uncosted count, no-cost-expected count, negative-qoh count, and the standing cautions). Filename Inventory_ABC_Analysis_<ISO date>_{inclOnHand|issuedOnly}.xlsx.

build() returns (fname, bytes, stats, codes); the docstring says it returns three values — cosmetic only.

Known limits

  1. CreditMemo is queried every run and never used — returns/credits do not reduce issued quantity, and the pull is slower than it needs to be.
  2. Jobs and their spreadsheets are in-process only: an app restart or a second app worker means a running job or a completed download disappears (404).
  3. stats/codes come from the same run that produced the file, but a write-back happens after the file is built — the spreadsheet is the record of what was written, and nothing records the ABC run itself except the per-item audit rows.
  4. The similar-item cost estimate and the AF30- 0.75 factor are heuristics baked into the code, not configuration.
  5. Inventory Adjustments are not a movement type; Qty On Hand is current, not period-start (both stated in the workbook Notes).