The Controlled Substance Inventory screen provides a transaction log for controlled substance activity at routeDocumentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
/cl/controlled-substances.
Overview
The page renders a list of inventory transactions from thecl_controlled_substance_inventory table, scoped to the current organization via organization_id. Transactions are ordered by created_at descending and soft-deleted records (deleted_at IS NOT NULL) are excluded. The InventoryList component accepts filter props (siteId, ndcCode, schedule, transactionType, dateFrom, dateTo) that are applied server-side in the query. Users with cl.inventory.create see a “Record Transaction” button that opens InventoryTransactionFormDialog. Users with cl.inventory.admin additionally see an ArcosExportButton. A running-balance reconciliation is available per NDC code and optional site via the useInventoryReconciliation hook (not surfaced on this list page itself).
Who it’s for
Requires permissioncl.inventory.view.
Before you start
You must hold thecl.inventory.view permission to access this page. Recording new transactions additionally requires cl.inventory.create. The ARCOS export action requires cl.inventory.admin.
Steps
Open Controlled Substance Inventory
Navigate to
/cl/controlled-substances. The page loads all non-deleted transactions for your organization, ordered by most recent first.Filter transactions (optional)
Use the filter controls in
InventoryList to narrow by site, NDC code, schedule, transaction type, or date range. Filters are applied server-side.Record a transaction (if permitted)
Click “Record Transaction” (requires
cl.inventory.create). The InventoryTransactionFormDialog opens. Fill in the required fields. If recording a Schedule II dispense, a witness must be provided — the system enforces this in the mutation and will return an error if witness_id is absent.Key concepts
Transaction types
Transaction types
The
transaction_type column accepts: receive, dispense, adjust, count, return, destroy. The reconciliation logic in code treats receive, return, and adjust as additive to the running balance, and dispense and destroy as subtractive. A count transaction records a physical count but does not change the computed running balance.Schedule II witness enforcement
Schedule II witness enforcement
The
useCreateInventoryTransaction mutation checks: if schedule === 'II' and transaction_type === 'dispense', it throws if witness_id is absent. This check runs client-side in the mutation function before the database insert.Soft delete
Soft delete
Transactions are never hard-deleted. The
useDeleteInventoryTransaction mutation sets deleted_at to the current timestamp. Deleted records are excluded from all list and reconciliation queries.Empty state
Empty state
When the query returns no transactions (or loading is in progress), the
InventoryList shows either skeleton placeholders or an empty state.Related
Clinical
Overview of the Clinical core.
Governance & parity
Documentation coverage and governance.
This page documents shipped product behavior. It is not medical, legal, or
billing advice. Verify against your organization’s policies and applicable
regulations before using it for clinical, compliance, or billing decisions.
Protected health information (PHI) shown in the product is governed by your
tenant’s access controls and is never exposed in this documentation.
Documentation sources
Documentation sources
- src/routes/cl.tsx
- src/cores/cl/pages/ControlledSubstanceInventoryPage.tsx
- src/cores/cl/hooks/useControlledSubstanceInventory.ts