# Inventory counts

A React block (a whole screen) in [Beamline](https://beamline.io/)'s [Inventory](https://beamline.io/components/apps/inventory) app. Live demo: https://beamline.io/components/inventory-counts

Recurring stock counts from plan to shelf: a phone-first count of one occurrence where an untouched part reads not counted and a zero reads counted, none there, one mark per part to jump to its field, each part's count typed where it is and saved there (Enter, or leaving the field with a change; focus moves on to the next part still to count) against the revision it was read at, then said against the expected quantity (matches, 2 short, 3 over) with a failed save kept and retried, someone else's newer count offered as keep mine or take theirs, and offline said; a review of what's not counted and what differs from expected before completing; count plans whose schedule stays apart from each count they opened, which keeps the parts it opened with when the plan changes; and a bulk change of classification codes where keep, set and clear are different choices, every task's codes are shown now and after, and the reach (from now on, or past records too, with the records it rewrites counted) is decided before applying.

## Use it for

- Counting spare parts or stock on a schedule, on a phone.
- Changing a shared definition where rewriting history must be a choice.

## Not for

- Ordering stock up to a level ([purchase-orders](https://beamline.io/components/purchase-orders)).
- Running maintenance jobs ([work-orders](https://beamline.io/components/work-orders)).

## Anatomy

- header: the mark, the plan's name, the view (Count · Plans · Change codes)
- count: counted of total, one mark per part, offline, Find a part, each part (name, SKU, location; the count typed in with its unit; what it says: not counted, matches, short or over, with expected or blind under it), Try again after a failed save, someone else's count under it
- review: what's not counted (each jumps to its part), the differences (counted as a bar, expected as a rule), Complete the count
- plans: the plans with schedule in words and part count; the selected plan's Repeats, Show expected quantities, Save plan; the counts it opened with their progress and the parts each kept
- change codes: System, Assembly, Component (keep, clear or a value), Why, every task's codes now and after; Where it applies with what it rewrites; Apply

## States

- not counted; counted zero; draft; saving; saved; save failed (kept, retry); someone else's count; offline
- a search with no match
- nothing left to count; differences; completed (read only)
- no plans; nothing opened yet; a count keeping its old parts; plan save failed
- nothing changed; scope not chosen; impact counting; applied; partly applied

## Keyboard

- type the count straight into the field, or step it; Save returns focus to that part's field
- each mark in the strip and each not-counted name is a button that goes to the part
- the views and the reach are radio groups; Apply and Complete ask once more

## Motion

Marks fill with a colour fade as parts are counted; progress bars scale from their start. Nothing moves at rest.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `parts` | `Part[]` | — | Name, SKU, location and unit of each part. |
| `plans` | `CountPlan[]` | — | Recurring plans: repeats, day, parts, who counts, whether expected quantities show. |
| `occurrences` | `CountOccurrence[]` | — | Each count a plan opened, with the parts it was opened with and those counted. |
| `counts` | `PartCount[]` | — | The open occurrence's counts: expected, counted (null: not counted; 0: none there), revision. |
| `onSaveCount` | `(input) => Promise<SaveCountResult>` | — | Save one part's count against the revision it was read at; reject when it didn't save. |
| `onCompleteCount` | `(occurrenceId: string) => Promise<unknown>` | — | Complete the occurrence; counts not taken stay not counted. |
| `onSavePlan` | `(plan: CountPlan) => Promise<unknown>` | — | Save a plan's schedule; it applies from the next occurrence. |
| `tasks` | `ServiceTask[]` | — | The tasks a bulk code change applies to, with their codes and past records. |
| `onImpact` | `(taskIds: string[]) => Promise<number>` | — | How many past records a historical change would rewrite. |
| `onApplyCodes` | `(input) => Promise<{ failed: string[] }>` | — | Apply the changes with their reach; resolve with tasks that changed meanwhile. |
| `offline` | `boolean` | — | Say counts wait on the device; completing waits. |
| `defaultPlans` | `CountPlan[]` | — |  |
| `onPlansChange` | `((p: CountPlan[]) => void)` | — |  |
| `occurrenceId` | `string` | — | The occurrence being counted. |
| `defaultCounts` | `PartCount[]` | — |  |
| `onCountsChange` | `((c: PartCount[]) => void)` | — |  |
| `codeOptions` | `Record<CodeField, string[]>` | — |  |
| `timeZone` | `string` | — |  |
| `defaultView` | `"codes" \| "count" \| "plans"` | — |  |
| `product` | `string` | — |  |
| `className` | `string` | — | Classes on the documented visual root; no override by default. |
| `ref` | `Ref<HTMLDivElement>` | — | Receives the documented native target or imperative handle; omitted by default. |

## Built from

- [Avatar](https://beamline.io/components/avatar.md)
- [Button](https://beamline.io/components/button.md)
- [Confirm morph](https://beamline.io/components/confirm-morph.md)
- [Glow](https://beamline.io/components/glow.md)
- [Input](https://beamline.io/components/input.md)
- [Kbd](https://beamline.io/components/kbd.md)
- [Label](https://beamline.io/components/label.md)
- [Number field](https://beamline.io/components/number-field.md)
- [Radio cards](https://beamline.io/components/radio-cards.md)
- [Search field](https://beamline.io/components/search-field.md)
- [Segmented control](https://beamline.io/components/segmented-control.md)
- [Select](https://beamline.io/components/select.md)
- [Spinner](https://beamline.io/components/spinner.md)
- [Switch](https://beamline.io/components/switch.md)
- [Text morph](https://beamline.io/components/text-morph.md)
- [Tooltip](https://beamline.io/components/tooltip.md)

## Dependencies

`lucide-react`

## Import

```tsx
import { InventoryCounts } from "@beamline/inventory-counts";
```

## Get it

Inventory counts is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. [Get Beamline](https://beamline.io/checkout?pack=complete) · [Connect your agent](https://beamline.io/connect)

## More in Inventory

- [Stock count](https://beamline.io/components/stock-count): A shelf counted. Count: the products on it with counted units, not counted (an empty field that changes nothing) kept apart from a counted zero, expected…
- [Goods receiving](https://beamline.io/components/goods-receiving): Goods received against purchase orders and invoices. Cards grouped by purchase order or invoice, each line once whichever way (a line keeps both sources…
- [Purchase order desk](https://beamline.io/components/purchase-order-desk): Purchase orders for stock from draft to closed. The list of orders with status (ready for review on warning, approved, ordered and partly received on…
- [Restock desk](https://beamline.io/components/restock-desk): Restocking from suppliers' own shops. Items low on stock (below the minimum on danger, at it on warning, unknown said) beside the chosen item with how…
- [Stock alerts](https://beamline.io/components/stock-alerts): Alerts on stock counts and expiry dates. Counts of alerts gone off (danger) and close (warning) in the header. A table: item and type, the rule in words…
- [Inventory finder](https://beamline.io/components/inventory-finder): Find stock and act on what's found. A rail of filters: name or SKU; folders with or without their subfolders (folders the person can't see said as not…
- [Item setup](https://beamline.io/components/item-setup): Setting items up for scanning and records. Barcodes: scanned codes waiting to be linked, each with its symbology, when and who; Look it up brings a…
- [Bulk item edit](https://beamline.io/components/bulk-item-edit): Many items corrected at once. Pick a folder, with its subfolders or not (fixed once anything is edited), up to a limit said. The items in a grid: name…
- [Kit builder](https://beamline.io/components/kit-builder): A kit (bundle) made of standalone products, and how many its parts' stock can make. Sell as a kit; the parts in one kit with units per kit, removable…
- [Serial allocation](https://beamline.io/components/serial-allocation): A receipt line's serial numbers. Serials generated from a first serial and how many (its digits counted up, padding kept; a first serial without digits…
- [Stock moves](https://beamline.io/components/stock-moves): Where stock went, and moving it. The ledger lists movements newest first: moves on info, stock added on success, stock taken out on warning; each with…
- [Scan station](https://beamline.io/components/scan-station): A warehouse scanner, phone-first. Home: one scan field that also takes typing (and says so when the scanner isn't connected), each code named as what it…
- [Pack station](https://beamline.io/components/pack-station): A packing bench. Scanner, scale and printer each said, on the warning tone when away. Find the shipment by scanning or typing its number (none found…
- [Shipment split](https://beamline.io/components/shipment-split): An order's lines split across shipments. A table of lines with what was ordered and a column per shipment (new ones marked); a line already shipped can't…
- [Route plan](https://beamline.io/components/route-plan): A day's delivery routes in the service's zone. The day at a glance: routes, routes without a driver (warning), stops running late (danger), stops done…
- [Job materials](https://beamline.io/components/job-materials): Materials sent out to jobs and pick lists. Jobs: the list (draft, active on info, completed on success) beside the chosen job with its site, dates (the…
- [Service tasks](https://beamline.io/components/service-tasks): A fleet shop's maintenance setup. Tasks: active and archived, searchable, main tasks and their subtasks told apart in words, archiving refused while…
- [Owner records](https://beamline.io/components/owner-records): Who a customer is and what they own, at the front desk. New customer: name, phone and email checked as typed against existing customers; each likely…
- [Sample storage](https://beamline.io/components/sample-storage): Where physical items are kept (rooms, freezers, shelves, racks, boxes) and acting on several at once. The storage tree is browsed apart from moving: Move…
- [Sample ledger](https://beamline.io/components/sample-ledger): Materials used in a record and the containers they came from, plus pooling. Subtracting a used amount writes a stock movement with its unit and the…

Part of [Beamline UI: polished, editable React components and complete screens for custom applications](https://beamline.io/). [Build your own style from any look; tokens, fonts, radii, motion; not only colours](https://beamline.io/docs/customize).
