Employee Portal Manual

A note on permissions. employee-web does not show or hide screens based on role — every signed-in employee can open every screen; the backend API enforces permission and two-factor rules when a button is actually clicked. Several privileged write actions in this manual were attempted live and rejected by the API with the exact on-screen message quoted, which is expected, correct behavior for this demo account’s session — not a bug.

Signing In & Always-Available Utilities

The login gate every employee passes through, plus the Search and My Work utilities available from the top bar regardless of workspace, plus the shared Home landing screen.

Employee Login

no route — replaces the whole screenworkspace: none
Employee Login screen
Employee Login — signed in as manual-demo@blukaal.test.

Purpose

Lets you sign in to the system with your work email and password.

What you see

  • A “PLMP Employee Web” title/logo.
  • An “Employee Login” form with Email and Password fields.
  • An inline error message if sign-in fails (e.g. “Invalid email or password.”).

What you can do

  • Enter your email and password and press Sign in. This calls POST /login. Two outcomes are possible:
  • If the account does not have two-factor authentication turned on, a successful password check signs you in immediately.
  • If the account has two-factor authentication confirmed, the server returns two_factor: true and you are shown the Two-Factor Authentication screen instead — you are not yet signed in at this point.

Related screens

Leads to the Two-Factor Authentication screen (if 2FA is on) and then into whichever workspace/screen the app defaults to (Operations → Home).

Constraints to know

A wrong email/password shows a generic “Invalid email or password.” message; it does not tell you which field was wrong (standard security practice, not a bug).

Two-Factor Authentication

shown only mid-loginworkspace: none
Two-Factor Authentication screen, recovery code mode
Two-Factor Authentication, switched to recovery-code mode (this account's authenticator app isn't available in this environment, so the recovery-code path was used to sign in).

Purpose

Completes sign-in for accounts protected by two-factor authentication, by asking for a one-time code.

What you see

  • A prompt asking for the code from your authenticator app (or, if switched, a recovery code).
  • A single code input field.
  • An inline error if the code is rejected.

What you can do

  • Enter your 6-digit authenticator code and press Verify — calls POST /two-factor-challenge with { code }.
  • Click Use a recovery code instead to switch the form to accept a one-time recovery code ({ recovery_code }). You can toggle back with Use an authenticator code instead.

Related screens

On success, proceeds into the app exactly like a normal sign-in.

Constraints to know

Until this step succeeds, the session is not authenticated — refreshing or navigating away leaves you back at the login form. Full enrollment/management of two-factor authentication is not part of this app — only the login-time challenge exists here.

Global Search

/searchworkspace: none — top bar
Global Search with a real result
Global Search, matching a real Customer record by internal ID.

Purpose

Lets you quickly find a specific Customer, Product, Asset, Quote, Order, Purchase Order, Service Ticket, or Return Request by typing an ID, without needing to know which workspace it lives in.

What you see

  • A single search box (“Search by id…”).
  • After searching, results grouped into cards by record type, each a two-column table: ID and Details (every other field, shown generically as key: value pairs).
  • An empty-state message (“No results for '...'.”) if nothing matches.

What you can do

Type a value and press Search (or Enter) — calls GET /search, a single read-only endpoint that fans out across the Customer, Product, Asset, Quote, Order, Purchase Order, Service Ticket, and Return Request lookups.

Related screens

None directly clickable — results are raw data in-page; you take the ID you find here and look the record up in its own workspace screen.

Constraints to know

This screen deliberately has no domain-specific knowledge of what a record “looks like” — it renders every field generically. It matches by internal ID, not a human-facing order/invoice number.

My Work

/my-workworkspace: none — top bar
Genuinely empty for this account — expected behavior, not a bug
My Work screen, empty
My Work — no tickets assigned to this account, and Approvals is correctly empty platform-wide.

Purpose

Gives you a single place to see the Service Tickets assigned to you and any approval requests waiting on your decision, instead of checking each module separately.

What you see

  • My Service Tickets card: Ticket, Description, Priority (badge), Status (badge).
  • My Approvals card: Type, Action, Requested by, Requested (timestamp).

What you can do

Filter your own ticket list with the Filter my tickets… search box. Both tables load via a single call to GET /my-work; there are no action buttons on this screen.

Related screens

None directly linked — you'd go to the Dispatch workspace's Service Dispatch screen to act on a ticket.

Constraints to know

The My Approvals table is genuinely, correctly empty for everyone today — no domain has yet wired a real approval workflow through the underlying approval mechanism.

Home

/ default routeshared across all 7 workspaces that list it
Home / platform status screen
Home — live platform status. Readiness is shown red/unreachable here, reflecting the real, live state of the local API at capture time.

Purpose

A simple landing/boot-verification screen confirming the system is up, rather than a business dashboard.

What you see

A “Welcome back” heading and a “Platform status” card with four badge rows: Liveness, Readiness, Database, and Redis.

What you can do

Nothing beyond viewing — it calls GET /health/live and GET /health/ready on load. No buttons or filters.

Related screens

None — from here you switch workspaces using the nav dropdown.

Constraints to know

This screen carries no business functionality — it is infrastructure health-check content only.

Operations Workspace

General staff day-to-day master-data and lookup screens: Customers, Products, Assets, Orders.

Customers List

/customersworkspace: Operations
Customers list, showing card-style records
Customers list — now rendered as a list of cards rather than a table.

Purpose

Lets you find a customer account by number, name, or organisation, and register a brand-new customer.

What you see

  • A “Search customers” card with a text box and Search button.
  • A list of customer cards: customer number as the bold heading, the customer's name/organisation as the subtitle, Status as a colored badge, and Type as a small fact. Each card is one click target — there's no separate row/button layout anymore.
  • A “Register customer” card below.

What you can do

  • Search — submits to GET /customers?q=....
  • Click a card — opens the Customer 360 detail view (replaces the old per-row “View 360” button; clicking anywhere on the card does the same thing).
  • Register customer form — Given name, Family name, Account type, and (if Organisation) Organisation legal name/registration number; submits to POST /customers.

Related screens

Clicking a card opens Customer 360; its Related section links conceptually to Assets, viewed fully on the Assets screen. The Assets screen's own “Register asset” form can now search for this customer by name/number instead of requiring you to already know its raw id.

Constraints to know

Registering a customer is privileged — requires domains.customer.register and confirmed two-factor authentication. Live-tested here: this demo account's recovery-code-based session was rejected with “You do not have permission to register customers, or two-factor authentication has not been confirmed for your account.” — a real, expected constraint, not a bug.

Customer 360

no separate route — opened in place on Customersworkspace: Operations
Customer 360 detail panel
Customer 360, opened from the Customers list above.

Purpose

Shows everything currently known about one customer account in one place, including the assets they own.

What you see

  • A detail panel titled with the Customer number, subtitled “Customer account — individual/organisation”, with a status badge.
  • Overview table: ID, Customer number, Account type, Status.
  • Related section: a table of the customer's owned Assets, loaded from GET /assets?owner_customer_account_id=..., or “No owned assets.” if none.

What you can do

View only — no edit or status-change buttons in the current build.

Related screens

Reached from the Customers list; its Related-assets table doesn't link onward — look the same asset numbers up on the Assets screen for full detail.

Constraints to know

This is read-only — there is no way to edit a customer's details or change their status from this screen.

Products List

/productsworkspace: Operations
Products list, showing card-style SKU records
Products list — now rendered as a list of cards rather than a table, showing real demo SKUs.

Purpose

Lets you find a product SKU by code/name, model, or brand, and register a new SKU.

What you see

  • A “Search products” card with a text box and Search button.
  • A list of product cards: SKU code as the heading, SKU name as the subtitle, Model and Brand as small facts. Click anywhere on a card to open its 360 view.
  • A “Register product” card below.

What you can do

  • Search — calls GET /products?q=....
  • Click a card — opens the Product 360 detail view (replaces the old per-row “View 360” button).
  • Register product form — Brand name, Model code, Model name, SKU code, SKU name, Serialization policy; submits to POST /products.

Related screens

Clicking a card opens the Product 360, whose Related section shows Assets of this SKU. Several other screens (Assets, Sales Quotes, Inventory) can now search for a specific SKU by this same code/name instead of requiring a raw id.

Constraints to know

Registering a product is privileged — requires domains.product.register and confirmed two-factor authentication. Live-tested here: attempting to register “Manual Demo Brand” with this demo account's recovery-code session was rejected with “You do not have permission to register products, or two-factor authentication has not been confirmed for your account.” This is the real, on-screen error text for this permission-gated action.

Product 360

no separate route — opened in place on Productsworkspace: Operations
Product 360 detail view for Ceiling Fan Premium
Product 360 for “Ceiling Fan Premium” (Aeroflow) — captured live after the demo/UAT seed added real products.

Purpose

Shows the full definition of one SKU and every physical Asset that has been created against it.

What you see

  • Detail panel titled with the SKU name, subtitled “Brand — Model (SKU code)”, with the Serialization policy shown as a badge.
  • Overview table: ID, Brand, Model code, Model name, SKU code, SKU name, Serialization policy.
  • Related section: a table of Assets of this SKU, loaded from GET /assets?sku_id=..., or “No assets of this SKU yet.”

What you can do

View only — no edit or action buttons.

Related screens

Reached from the Products list; conceptually related to the Assets screen.

Constraints to know

Read-only — no way to change a SKU's fields, retire it, or otherwise act on it from this screen.

Assets List

/assetsworkspace: Operations
Assets list, showing card-style records
Assets list — now rendered as a list of cards rather than a table.

Purpose

Lets you look up a specific physical Asset by its asset number, and register a newly-created Asset against a product model/SKU and owner.

What you see

  • A “Search assets” card with a text box and Search button.
  • A list of asset cards: asset number as the heading, the owner's name as the subtitle, Lifecycle status as a badge. Click anywhere on a card to open its 360 view.
  • A “Register asset” card below, now with two search-and-select fields instead of raw id boxes (see “What you can do”).
Register asset form, Product / SKU search field open with results
Register asset form — the combined “Product / SKU” search field, showing matching results as you type.
Register asset form, Owner customer account search field open with results
Register asset form — the “Owner customer account id” field is now the same kind of search-and-select box.

What you can do

  • Search — calls GET /assets?q=....
  • Click a card — opens the Asset 360 detail view.
  • Register asset form — a single “Product / SKU” search field (type a SKU code, SKU name, or model name; picking a result fills both the product model id and the SKU id together — there is no way to submit a model with no specific SKU through this field), and an “Owner customer account id” search field (type a customer number or name); submits to POST /assets.

Related screens

Click a card to open the Asset 360. Assets also appear as “Related” data inside the Customer 360 and Product 360 screens.

Constraints to know

Registering an asset is privileged (domains.asset.register + confirmed two-factor). The Product / SKU and Owner customer account fields are searchable pickers, not free-typed text — you can no longer submit an unverified raw id here. If the product/SKU or customer you need doesn't show up in the search, it needs to be registered on the Products or Customers screen first.

Asset 360

no separate route — opened in place on Assetsworkspace: Operations
Asset 360 detail panel
Asset 360, opened from the Assets list above — Overview tab shown.

Purpose

Gives the full identity and history picture for one physical asset — what it is, who owns it, its serial/identifier numbers, and where it has been located over time.

What you see

  • Detail panel titled with the Asset number, subtitled “Product model {id}”, with the Lifecycle status shown as a badge.
  • Overview table: ID, Asset number, Product model id, SKU id, Lifecycle status, Owner customer account id.
  • Related — Identifiers table: Type, Value, Primary flag (supports multi-identifier/componentized assets).
  • Related — Location assignments table: Service location, Effective from, Effective to (“Current” if still open-ended).

What you can do

View only — no buttons to edit the asset, change ownership, or add identifiers/locations from this screen.

Related screens

Reached from the Assets list, and reachable indirectly via Customer 360 / Product 360 “Related” tables (which don't link directly — re-search by asset number here).

Constraints to know

This view is read-only history — it correctly shows multiple identifiers and a location history rather than a single current location, consistent with Asset identity/ownership/location all being effective-dated and never overwritten in place.

Orders List

/ordersworkspace: Operations
Orders list, showing card-style records
Orders list — now rendered as a list of cards rather than a table.

Purpose

Lets you see every Sales Order and its current status, and filter down to orders in a particular state.

What you see

  • A “Sales orders” card with a Filter by status dropdown (All / Draft / Pending validation / Confirmed / On hold / Cancelled).
  • A list of order cards: order number as the heading, customer name as the subtitle, Status as a badge. Click anywhere on a card to open its detail view.

What you can do

  • Change the status filter — reloads from GET /orders?status_code=....
  • Click a card — opens the order's detail view (replaces the old per-row “View” button).

Related screens

Clicking a card opens Order Detail. Orders originate from an accepted Quote in the Sales workspace's Quotes screen.

Constraints to know

This list only reads existing orders — it has no “create order” button; new orders are created from an accepted Quote, not from here.

Order Detail & Lifecycle Actions

no separate route — opened in place on Ordersworkspace: Operations
Order Detail with lifecycle action buttons
Order Detail for a real Confirmed order — note the Place on hold / Record amendment / Cancel order action buttons, which vary by status.

Purpose

Lets you see one order's full status and history, and carry out controlled lifecycle actions — confirm, hold/release, cancel, or record a formal amendment — without ever freely typing a new status.

What you see

  • Detail panel titled with the Order number, subtitled with the Customer account ID, with a status badge.
  • Overview table: ID, Order number, Customer account id, Quote id, Status, Version (concurrency control), Held reason, Held by, Cancelled reason, Cancelled by, Replacement order id.
  • History table (amendment history): Field, Original → revised value, Reason, Requested by, Approved by, When.
  • Action buttons that vary with the order's current status.

What you can do

  • Confirm (Draft/Pending validation) — POST /orders/{id}/confirm.
  • Place on hold (Confirmed) — opens a form requiring a Hold reason, then POST /orders/{id}/hold.
  • Release hold (On hold) — POST /orders/{id}/release-hold directly.
  • Record amendment (Confirmed/On hold) — pick a material field, Original/Revised value, and a required reason; POST /orders/{id}/amendments.
  • Cancel order (Confirmed/On hold) — requires a Cancellation reason and optional Replacement order id; POST /orders/{id}/cancel.

Related screens

Reached from the Orders list. A cancellation can reference a Replacement order id, implying a link to another Order (looked up separately, e.g. via Global Search).

Constraints to know

The server enforces the real transition rules regardless of which button the UI shows — an illegal transition is rejected (HTTP 422) even if a button were somehow clicked. Concurrent edits fail with a conflict message (optimistic concurrency via Version) rather than silently overwriting. There is no generic status dropdown — each action is a separate, explicit business Command.

Sales Workspace

Quote lifecycle: create, list, review, accept, and convert to Sales Order.

Quotes

/quotesworkspace: Sales
Create quote form, Customer account search field open with results
Create quote form — the “Customer account id” field is now a search-and-select box.
Create quote form, Product / SKU search field open with results
Create quote form — each line's “Product model id”/“SKU id” pair is now one combined “Product / SKU” search field.
Quotes list with real accepted quotes, card style
Quotes list — now rendered as a list of cards, showing the real, already-Accepted seeded quotes.

Purpose

Lets sales staff create a Quote for a customer, search/browse existing Quotes, and move a Quote through its lifecycle — Draft → Customer Acceptance → converting to a real Sales Order.

What you see

  • A Create quote card: a Customer account search field, Originating opportunity id (optional — still a raw text field; no opportunity picker exists yet), and repeatable line rows, each with one combined Product / SKU search field and a Quantity.
  • A Quotes list card with filters (a Customer account search field, and Status) and a list of quote cards: quote number as the heading, customer name as the subtitle, Status as a badge, Opportunity as a small fact.
  • A detail panel when a quote is selected: overview table plus a line items table.

What you can do

  • Create quote — POST /quotes, then opens the new quote's detail. Picking a customer and a product/SKU from the search fields fills the underlying ids automatically; there is no way to submit the form with a typed-but-unselected id.
  • Filter/search the list, then Search — GET /quotes.
  • Click a card — GET /quotes/{id} (replaces the old per-row “View” button).
  • On a Draft quote: Accept quote — POST /quotes/{id}/accept (Customer Acceptance, not an internal approval).
  • On an Accepted quote: Convert to order — creates a new Sales Order and shows its ID.

Related screens

Converting creates a record you'd next look up on the Operations workspace's Orders screen (no direct link — only the new order's ID as text).

Constraints to know

  • Accept quote only appears in Draft; Convert to order only once Accepted.
  • “Accept” means Customer Acceptance, not an internal sales-manager approval — PLMP's separate “Quotation Approval” concept has no backend action wired up yet (PDQ-009).
  • There is no “Revise Quote” action — lines cannot be edited once created.
  • The Customer account and Product / SKU fields require picking a real search result — if you type but don't select before submitting, that field's id stays empty and the server rejects the request (422), same as leaving it blank.

Reports Workspace

Operational reporting and export surfaces.

Time to Final Resolution

/reports/time-to-final-resolutionworkspace: Reports
Time to Final Resolution report screen, with Recent runs list and chart
Time to Final Resolution — generate/look-up forms, a “Recent runs” card list, a bar chart, and the results table.

Purpose

Shows managers/operations staff how long it typically takes, by product brand, from a technician's first visit on a service ticket to that ticket's final resolution.

What you see

  • A Generate a report run card with optional Period from/to pickers and a Generate report button.
  • A Look up a previously generated run card (Report run id + Look up).
  • A “Recent runs” list of cards — each showing the run's timestamp as the heading, a status badge (e.g. COMPLETED), and Period/Brands as small facts. Click a card to load that run instead of typing its id.
  • Once a run is loaded: a status line, a bar chart (average hours to resolution by brand), and a table (Product Brand, Resolutions, Avg/Min/Max time to resolution).

What you can do

  • Generate report — POST /reports/time-to-final-resolution/generate, then auto-loads via GET /reports/runs/{id}.
  • Look up an existing run id directly, or click a card in Recent runs — both call GET /reports/runs/{id}.
  • Export CSV once a run is loaded (built entirely in-browser; disabled if no rows).

Related screens

None — a standalone reporting screen.

Constraints to know

Generating a report requires a specific reporting permission and confirmed two-factor authentication; looking up an existing run by ID (or clicking a Recent runs card) has no such restriction. If no qualifying resolutions exist, the table explains why rather than showing an empty grid with no context.

Field Service Workspace

The technician-facing side of PLMP — currently just a link-out, no in-app functionality.

Technician App (external link)

opens customer-portal in a new tabworkspace: Field Service
Technician app download page in customer-portal
The public “Get the Blukaal Technician app” download page (hosted in apps/customer-portal), opened by the “Technician App” nav item.

Purpose

Gives office/dispatch staff a quick way to grab the link (or hand it to a technician) for downloading the technician mobile app — a convenience shortcut, not a business screen.

What you see / can do

Nothing renders inside employee-web itself; clicking the nav item opens this public, no-login download page (QR code, app store links, and a “continue to the PLMP web portal” fallback) in a new tab.

Related screens

None inside employee-web — the Field Service workspace has no other screens beyond the shared Home screen and this external link.

Constraints to know

This is explicitly a link-out, not a page. An earlier authenticated in-app “Technician App” page was retired in favor of this public download page, so don't expect technician data or history inside employee-web.

Inventory Workspace

Stock balances, reservations, transfers, counts, and conditions.

Stock Balances

/inventory/stock-balancesworkspace: Inventory
Shown here with no data yet — no warehouses configured in this environment
Stock Balances, empty
Stock Balances — “No warehouses are configured yet.”

Purpose

Lets you check how much of a product is on hand, reserved, and actually available to promise, in a specific warehouse.

What you see

  • A warehouse picker at the top.
  • A Balances table: Product model, SKU, On hand, Reserved, Available (green badge if >0).
  • A “Filter by product model…” search box.

What you can do

Pick a warehouse to load its balances — GET /stock-balances?warehouse_id=. No write actions — read-only by design.

Related screens

To change a balance, go to Stock Reservations, Warehouse Transfers, Stock Counts, or Stock Conditions — none of those edit this table directly.

Constraints to know

This screen only displays a maintained projection of stock, derived from posted Stock Movements recorded elsewhere; there is no “edit quantity” control anywhere on it.

Stock Reservations

/inventory/reservationsworkspace: Inventory
Reserve stock form, Product / SKU search field open with results
Stock Reservations — the Reserve stock form's “Product / SKU” search field, showing matching results as you type.

Purpose

Lets you set aside available stock for a specific Sales Order (or other source) without physically moving it, and release a reservation once it's no longer needed.

What you see

  • Warehouse picker.
  • A Reserve stock form: a combined Product / SKU search field (replacing the old separate Product model id/SKU id text fields), Quantity, Source reference type/id, Priority.
  • A Reservations table (unchanged): Product model, Qty, Source, Priority, Status (badge), Reserved at, Actions.

What you can do

  • Submit the form — POST /stock-reservations (ReserveStock). Picking a result from the Product / SKU search fills both the product model id and SKU id together.
  • Release an active reservation — POST /stock-reservations/{id}/release.

Related screens

Works against the balances shown on Stock Balances; source references typically point back to a Sales Order.

Constraints to know

Releasing an already-released reservation is rejected (422) rather than silently succeeding — a legitimate concurrency case. Reserving stock is always a dedicated business action, never a direct quantity edit. The Product / SKU field always resolves to a specific SKU — there is no way to reserve “just a model” with no SKU through this field, even though the raw field was previously optional.

Warehouse Transfers

/inventory/transfersworkspace: Inventory
Transfer stock form, Product / SKU search field open with results
Warehouse Transfers — the Transfer stock form's “Product / SKU” search field, showing matching results as you type.

Purpose

Lets you move stock from the warehouse you're viewing to another warehouse, recording it as a proper transfer rather than manually adjusting two separate balances.

What you see

  • Source/viewing warehouse picker.
  • A Transfer stock form: Destination warehouse (excludes the source), a combined Product / SKU search field (replacing the old separate Product model id/SKU id text fields), Quantity.
  • A Transfer history table (unchanged): Transfer #, Direction (Outbound/Inbound badge), Product model, Qty, Status.

What you can do

Submit the form — POST /warehouse-transfers (TransferStock), posting two linked Stock Movement entries. Picking a result from the Product / SKU search fills both the product model id and SKU id together.

Related screens

Complements Stock Balances — a completed transfer changes both warehouses' on-hand quantity there.

Constraints to know

You cannot select the same warehouse as both source and destination. There is no direct “edit balance” step — a transfer always posts two linked ledger movements. The Product / SKU field always resolves to a specific SKU.

Stock Counts

/inventory/stock-countsworkspace: Inventory
Starting a new count is permission-gated for this demo session — shown here with only the one existing (already-reconciled) count
Stock Counts list, card style
Stock Counts — the counts list is now rendered as a list of cards rather than a table. “Start count” did not create a new count for this demo session (no error banner shown either — likely a silent permission rejection), so the “Record count line” form's new combined “Product / SKU” search field couldn't be captured live here; it works the same way as the identical field shown on Stock Conditions/Reservations/Warehouse Transfers below.

Purpose

Lets you run a cycle or physical stock count in a warehouse — start a count, record what you counted, then reconcile so any variance gets corrected.

What you see

  • Warehouse picker with a Start count button.
  • A list of count cards: the count's started-at timestamp as the heading, Status as a badge. Click a card to open its detail.
  • Selecting a count opens a detail panel: overview table, a “Record count line” form (while open) — now with one combined Product / SKU search field instead of two separate text fields — and a lines table with Variance badges.

What you can do

  • Start count — POST /stock-counts (StartStockCount).
  • Click a card — opens that count's detail (replaces the old “View”/“Selected” button; there's no separate visual highlight for the currently-open count in the list anymore, only the detail panel below tells you which one you're looking at).
  • Submit “Record count line” — POST /stock-counts/{id}/lines (re-entering the same product/SKU replaces the prior line). Picking a result from the Product / SKU search fills both ids together.
  • Reconcile (only while open) — POST /stock-counts/{id}/reconcile, posting one corrective Stock Movement per non-zero-variance line.

Related screens

Reconciling here is what ultimately corrects the numbers on Stock Balances for this warehouse.

Constraints to know

A count's system quantity is never overwritten directly — a real corrective Stock Movement is posted per line, only on explicit Reconcile. Recording lines is only possible while the count is “open.”

Stock Conditions

/inventory/stock-conditionsworkspace: Inventory
Record a condition transition form, Product / SKU search field open with results
Stock Conditions — the form's combined “Product / SKU” search field, showing matching results as you type.

Purpose

Lets you record that a quantity of stock has moved into a particular physical/quality condition — e.g. damaged, QC hold, returned quarantine — and see the full history for a warehouse.

What you see

  • Warehouse picker.
  • A form: a combined Product / SKU search field (replacing the old separate Product model id/SKU id text fields), Quantity, Condition (dropdown: Available New, QC Hold, Damaged, Returned Quarantine, Serviceable Used, Repaired, Standby), Reason.
  • A Condition history table (unchanged) with color-coded condition badges.

What you can do

Submit the form — POST /stock-conditions (SetStockCondition). Picking a result from the Product / SKU search fills both the product model id and SKU id together.

Related screens

A separate concept from Stock Balances' on-hand/reserved/available numbers — this is quality/handling state, not location or reservation.

Constraints to know

Strictly append-only history — there is no edit or delete of a previously recorded condition entry; the fix for a mistake is a new correcting transition.

Dispatch Workspace

Service ticket dispatch and installation/commissioning management.

Service Dispatch

/dispatch/service-ticketsworkspace: Dispatch
Service Dispatch queue
Service Dispatch — the ticket queue is now rendered as a list of cards rather than a table.

Purpose

Lets a dispatcher see every open Service Ticket across the whole company, assign a technician, and record what happened — a visit's restoration, formal resolution, and SLA breach status.

What you see

  • Ticket queue card: Status filter, Unassigned only checkbox, Refresh.
  • A list of ticket cards: ticket number as the heading, description as the subtitle, Priority as the badge, Status and Assigned technician as small facts.
  • Selecting a ticket opens a detail panel: Assign technician form, Evaluate SLA form, Record restoration form, Record resolution form, SLA exceptions list, and Visits/Restorations/Resolutions history.

What you can do

  • Filter/refresh — GET /service-tickets/dispatch-queue.
  • Click a card — opens that ticket's detail (replaces the old per-row “View” button).
  • Assign technician — POST /service-tickets/{id}/assign.
  • Evaluate SLA — POST /service-tickets/{id}/sla-evaluations.
  • Record restoration — POST /service-tickets/{id}/restorations.
  • Record resolution — POST /service-tickets/{id}/resolutions.

Related screens

Tickets assigned to the signed-in user also show up (read-only) on My Work. No cross-link into Asset/Customer 360.

Constraints to know

A Visit, Restoration, Resolution, and Closure are four separate facts — recording a restoration never resolves or closes the ticket, and this screen has no “close ticket” action at all. The Ticket queue deliberately shows every ticket company-wide, unlike the self-scoped My Work view.

Installation Jobs

/dispatch/installation-jobsworkspace: Dispatch
Installation Jobs queue
Installation Jobs — the job queue is now rendered as a list of cards rather than a table.

Purpose

Lets a dispatcher run a checklist-driven installation for a delivered Asset — open the job, tick checklist items, record commissioning tests, mark complete, and record customer acceptance.

What you see

  • Open an installation job form: Delivery line id, Checklist item code/description, Mandatory checkbox.
  • Installation job queue: Status filter, Refresh, and a list of job cards: job id as the heading, delivery line id/asset id as the subtitle, Status as a badge.
  • Selecting a job: Accepted at field, Checklist list, Record commissioning form, Commissioning attempts history, and Complete job / Accept installation buttons.

What you can do

  • Open an installation job — POST /installation-jobs (one job per Delivery Line with an allocated Asset).
  • Click a card — opens that job's detail (replaces the old per-row “View” button).
  • Complete a checklist item — POST /installation-jobs/{id}/checklist-items/{itemId}/complete.
  • Record commissioning — POST /installation-jobs/{id}/commissioning.
  • Complete job / Accept installation — each disabled once already done.

Related screens

Works against an existing Delivery Line and Asset — looked up via Assets or Global Search; no direct link back.

Constraints to know

Exactly five explicit business actions, no generic “change status” control. No “replace the Asset” workflow surfaces here — permanent Asset replacement, if needed, happens elsewhere.

Procurement Workspace

Purchase orders, goods receipt, and supplier performance.

Purchase Orders

/purchase-ordersworkspace: Procurement
Purchase Orders list
Purchase Orders — the list is now rendered as a list of cards rather than a table.

Purpose

Lets purchasing/warehouse staff create a purchase order to a supplier, record what was actually received, see discrepancies, and check a supplier's performance score.

What you see

  • Create purchase order form: Supplier name, Expected delivery date, repeatable Lines (Product model id, SKU id, Quantity — these two id fields are still plain text on this screen; they were not converted to search fields in this pass).
  • A list of PO cards: PO number as the heading, supplier name as the subtitle, Status as a badge, Expected delivery and Received as small facts.
  • Selecting a PO: overview + Lines table, Receive goods form (while open), Related panel (Supplier + Performance Score), History panel (discrepancies).

What you can do

  • Create purchase order — then auto-selects the new PO's detail.
  • Click a card — opens that PO's detail (replaces the old per-row “View” button).
  • Receive goods (while status is “open”) — records the receipt, flips status to “received”, and generates Discrepancy records if quantities don't match.
  • Compute score — recalculates the supplier's performance score.

Related screens

None directly linked — cross-reference received stock on Inventory workspace screens separately.

Constraints to know

Receive goods disappears once the PO's status flips to “received” — no re-receiving or reopening from this screen. The Supplier Performance Score only updates on explicit Compute score.

Spares & Returns Workspace

Spare compatibility, reservation/issue, Core Returns, Repair Orders, and customer Returns.

Spare Compatibility

/spares/compatibilityworkspace: Spares & Returns
Spare Compatibility, SKU id search field open with results
Spare Compatibility — the “SKU id” field is now a search-and-select box; the neighboring “Compatible product model id” field stays plain text.

Purpose

Lets you record which spare parts fit which product models (and vice versa), and look that mapping up before reserving or issuing a part for a repair.

What you see

  • Declare compatibility card — a SKU search field (picking a result sets only the SKU id; the compatible model is a separate, different id, not derived from the SKU pick) and a “Compatible product model id” text field.
  • Retire compatibility card (Compatibility id).
  • Compatible spares for a product model lookup (still a raw “Product model id” text field — no search endpoint exists for a bare model), and Compatible product models for a spare lookup (its “SKU id” field is also now a search-and-select box).

What you can do

  • Declare compatibility — POST /spares/compatibility.
  • Retire compatibility — POST /spares/compatibility/{id}/retire.
  • Two read-only lookups by product model id / SKU id.

Related screens

Feeds into Spare Reservations & Issues — check compatibility here before reserving a SKU against a Service Ticket there, where the SKU id field is now the same kind of search box.

Constraints to know

Both mutating actions are permission- and MFA-gated on the backend — a 403 here is expected for a non-authorized session, not a bug. Retiring is the only way to remove a mapping — there is no plain delete/update. The “Compatible product model id” fields on this screen deliberately remain raw text — there is no backend search for a bare product model yet.

Spare Reservations & Issues

/spares/service-ticketsworkspace: Spares & Returns
Spare Reservations and Issues, load form
Spare Reservations & Issues — the “Load a service ticket” gate before any reserve/issue form appears (still true today — this demo account has no real seeded ticket id to load, so the new SKU search fields inside the Reserve/Issue forms aren't shown here).

Purpose

Lets you reserve a spare part against a specific Service Ticket, cancel a reservation, and record that a spare was actually handed out (issued) for the repair.

What you see

  • Load a service ticket card (Service ticket id).
  • Once loaded: Reserve a spare (now with a SKU search field instead of a raw text box), Cancel a reservation, and Issue a spare (also now a SKU search field) cards, plus Reservations and Issues tables.

What you can do

  • Load — GET /service-tickets/{ticketId}/spares.
  • Reserve spare — POST /service-tickets/{ticketId}/spare-reservations. Picking a search result sets the SKU id; the field ignores the product-model half of the match, since this action only ever needed the SKU.
  • Cancel reservation — POST .../spare-reservations/{reservationId}/cancel.
  • Issue spare — POST /service-tickets/{ticketId}/spare-issues, optionally linked to a reservation and/or warehouse. Its SKU field is the same kind of search box.

Related screens

Works with Spare Compatibility (check fit first — its own SKU id fields are now search boxes too), Service Dispatch (where the ticket is managed), and Inventory (warehouse side of an issued spare).

Constraints to know

Issuing a spare with a warehouse id posts a real Stock Movement (IssueStock) — a genuine ledger deduction. All three mutating actions are permission- and MFA-gated. You must load a ticket before any reserve/cancel/issue form will submit.

Return Requests

/returns/requestsworkspace: Spares & Returns
Return Requests, Customer account search field open with results
Return Requests — the “Customer account id” field in the create form is now a search-and-select box.

Purpose

Lets you record a customer's request to return a product, approve or reject it, and then walk the returned item through inspection and a final disposition decision.

What you see

  • Create a return request card — a Customer account search field, plus Sales order id, Asset id, and Reason code as raw text fields (unconverted).
  • Look up a return request card — shows Approve/Reject buttons while “pending”.
  • Look up a return item card — shows an inspection form or a disposition form depending on state.

What you can do

  • Create return request — POST /return-requests. Picking a customer from the search field fills the underlying customer account id.
  • Approve / Reject — POST /return-requests/{id}/approve or /reject.
  • Record inspection — POST /return-items/{id}/inspection.
  • Record disposition — POST /return-items/{id}/disposition.

Related screens

Core Returns and Repair Orders are a related but distinct workflow (supplier core exchanges / depot repairs), reached independently.

Constraints to know

You cannot approve/reject outside “pending” status, nor record a disposition before an inspection. Sales order id and Asset id still require manual entry — there is no lookup/autocomplete for either yet, only for the customer.

Core Returns

/spares/core-returnsworkspace: Spares & Returns
Core Returns, load form
Core Returns — the “Load a spare issue” entry gate.

Purpose

Lets warehouse/service staff track a defective part (“core”) that a technician owes back after a spare part was issued, walking it from declared owed through received, inspected, and disposed.

What you see

A Load a spare issue form, then a Core card showing status, and (once a Core Return is started) received condition, inspection outcome, and disposition.

What you can do

  • Declare core owed back — POST /spare-issues/{id}/core.
  • Record core return received — POST /spares/cores/{coreId}/returns.
  • Record inspection — POST /spares/core-returns/{id}/inspection.
  • Record disposition — POST /spares/core-returns/{id}/disposition.

Related screens

The Core Return Dashboard shows the same data across every Spare Issue at once. Getting a Spare Issue id typically comes from Spare Reservations & Issues.

Constraints to know

Strict one-way sequence: received → inspected → disposed. Known limitation (PDQ-046-01): no monetary credit amount, credit mechanism, or approval workflow anywhere — only the physical facts are tracked.

Core Return Dashboard

/spares/core-return-dashboardworkspace: Spares & Returns
Shown here with no data yet — all four pipeline counts are genuinely 0
Core Return Dashboard, empty
Core Return Dashboard — four honest pipeline-stage counts, all zero, and “No cores have been declared yet.”

Purpose

Gives a manager or purchasing/service lead a single view of every core owed back across all Spare Issues, grouped by pipeline stage.

What you see

Four summary count cards (Awaiting technician return, Received, Inspected, Disposed) and a filterable Cores table.

What you can do

Read-only — loads via GET /spares/cores on page load. Go to Core Returns to act on any individual core.

Related screens

Takes you conceptually to Core Returns by SKU id / Spare Issue id / Core id shown here.

Constraints to know

Deliberately does not show “overdue for credit” or total financial exposure, even though mentioned in the underlying business requirement — no due-date or monetary-amount field exists to compute them from (PDQ-046-01). The screen refuses to fabricate numbers it can't back up.

Repair Orders

/spares/repair-ordersworkspace: Spares & Returns
Shown here with no data yet
Repair Orders screen
Repair Orders — Register a repair vendor form plus the (empty) vendor list and ticket-load gate.

Purpose

Lets you register outside repair vendors and track a broken unit's repair job for a Service Ticket, from creation through vendor dispatch, acceptance, in-progress repair, outcome, and closing.

What you see

  • Register a repair vendor card and Active repair vendors table.
  • Load a service ticket's repair orders card.
  • Once loaded: Create a repair order card, Record a repair outcome card, and a Repair orders table with per-row, status-specific action buttons.

What you can do

  • Register vendor — POST /repair-vendors.
  • Create repair order — POST /service-tickets/{id}/repair-orders.
  • Row actions: Send to vendor, Record vendor acceptance, Record in progress, Close — each visible only in the matching status.
  • Record outcome — moves an order from in_repair to outcome_recorded.

Related screens

The Repair Dashboard shows this data aggregated across every ticket. A Repair Order is typically created against a ticket found via Service Dispatch.

Constraints to know

Strict six-stage lifecycle: created → sent_to_vendor → vendor_accepted → in_repair → outcome_recorded → closed. Known limitations (PDQ-047-01/02/03): no cost/SLA field, and no maker-checker gate on any transition.

Repair Dashboard

/spares/repair-dashboardworkspace: Spares & Returns
Shown here with no data yet — all six stage counts are genuinely 0
Repair Dashboard, empty
Repair Dashboard — six lifecycle-stage counts, all zero, and “No repair orders have been created yet.”

Purpose

Gives a manager a portfolio view of every Repair Order across every Service Ticket, showing how many sit at each lifecycle stage.

What you see

Six summary count cards and a filterable Repair orders table (Service ticket id, Repair vendor id, Status, Outcome, Created, Repair order id).

What you can do

Read-only — loads via GET /repair-orders. Go to Repair Orders (with the Service Ticket id shown) to actually progress a job.

Related screens

Feeds into the Repair Orders screen for taking action on any individual repair job.

Constraints to know

Deliberately omits “vendor turnaround,” “cost saving vs new,” and “repeat failure rate” metrics called for by the business requirement — no turnaround/SLA, cost, or repeat-failure field exists to compute them from (PDQ-047-01/02).

Finance Workspace

Chart of Accounts, Fiscal Periods, Vouchers, Trial Balance, Receivables, Payables, MIS Dashboards, Period Close, Tally Integration, Dimensions, Intercompany, Inventory Accounting, Tax, Banking, and Fixed Assets — the largest workspace in the app.

Chart of Accounts

/finance/chart-of-accountsworkspace: Finance
Shown here with no chart yet — the seeded “Default Legal Entity” has none configured
Chart of Accounts, no chart yet
Chart of Accounts — real legal entity loaded (“Default Legal Entity (pilot bootstrap)”), no chart of accounts created for it yet.

Purpose

Lets accounting staff set up and browse the official Chart of Accounts a legal entity books its transactions against, including account groups and which ledgers allow manual entries.

What you see

  • A Legal entity picker (shared across Finance screens).
  • A Chart of accounts table for the selected entity (one active chart per entity).
  • If none exists: a Create chart of accounts form (Code, Name, Accounting basis, Currency).
  • Once a chart exists: Account groups and Ledgers tables, each with its own create form.

What you can do

  • Pick a Legal entity to load its chart, groups, and ledgers.
  • Create chart of accounts, Create account group, Create ledger.

Related screens

Ledgers created here are exactly what you pick from when posting a Voucher, and what appear as rows on the Trial Balance report.

Constraints to know

Exactly one active Chart of Accounts per legal entity. You cannot create an Account Group before a Chart exists, nor a Ledger before at least one Account Group exists.

Fiscal Periods

/finance/fiscal-periodsworkspace: Finance
Shown here with no fiscal years yet for this legal entity
Fiscal Periods, no fiscal years yet
Fiscal Periods — Create fiscal year form; this legal entity has none yet.

Purpose

Lets accounting staff define a legal entity's fiscal years and accounting periods, and control which periods are open for posting.

What you see

  • Legal entity picker, Fiscal year picker, Create fiscal year form.
  • Accounting periods table: Period, Name, Start, End, Status (badge), Actions.
  • Create accounting period form; an inline Reopen form when reopening.

What you can do

  • Soft-close (while OPEN), Hard-close (while SOFT_CLOSED), Reopen (any non-OPEN period, requires a typed reason).
  • Create fiscal year and Create accounting period.

Related screens

The periods managed here gate which Accounting date is valid when posting a Voucher, and feed the Period Close screen.

Constraints to know

Explicit lifecycle only: OPEN → SOFT_CLOSED → HARD_CLOSED, never a free-form status jump. Reopening requires a reason or the form won't submit.

Vouchers

/finance/vouchersworkspace: Finance
Shown here with no vouchers posted yet
Vouchers screen, none posted yet
Vouchers — Post a voucher form; no vouchers posted yet for this entity.

Purpose

Lets accounting staff record and review accounting vouchers — the debit/credit postings that make up the general ledger — and reverse a voucher posted in error.

What you see

  • Legal entity picker, Recent vouchers table (Number, Type, Voucher date, Currency, Status, View).
  • A Voucher detail panel with a Lines table after clicking View.
  • A Post a voucher form: type, dates, currency, narration, reference, repeatable Lines (Ledger id, Entry side, Amount).

What you can do

  • View a voucher to load its full line-item detail.
  • Reverse voucher (only while POSTED) — posts an offsetting reversal and marks the original REVERSED.
  • Post voucher — submits header + all lines as one voucher.

Related screens

Posted vouchers feed Trial Balance and Receivables/Payables reports; Ledgers are set up on Chart of Accounts; periods are managed on Fiscal Periods.

Constraints to know

Lines must balance (debits = credits) before posting. Amounts are exact-decimal text, never floating point. A voucher is never edited in place — only Reverse voucher corrects a posted one.

Trial Balance

/finance/trial-balanceworkspace: Finance
Trial Balance report parameters
Trial Balance — report parameters, ready to produce (no chart/vouchers exist yet for this entity, so nothing to display below).

Purpose

Lets accounting staff produce a live trial balance — total debits and credits by ledger — as of any date, to check the books are in balance.

What you see

Legal entity picker, Currency and As-of-date report parameters, and (once produced) a Balanced/Not balanced card with a ledger table and totals.

What you can do

Produce trial balance — the only action; then filter the rows with the search box.

Related screens

Figures are derived entirely from Vouchers posted against Ledgers on Chart of Accounts — there's nothing to edit here.

Constraints to know

A read-only, always-recomputed report. If a total looks wrong, the fix is a correcting Voucher, not anything on this page.

Receivables

/finance/receivablesworkspace: Finance
Receivables, Customer account search field open with results
Receivables — the “Open a customer financial account” form's “Customer account id” field is now a search-and-select box; the separate “Load” card's “Customer financial account id” field (a different id) stays plain text.

Purpose

Lets AR staff manage a single customer's Accounts Receivable subledger — open the account, see what they owe, review the running-balance ledger, record a payment, and apply it against open receivables.

What you see

  • Open a customer financial account card — now with a Customer account search field instead of a raw id box — and Load an existing one card — still a raw “Customer financial account id” lookup box, a different id, unaffected.
  • Once loaded: account summary, Receivables table, Ledger table, Recognise a receivable form, Record a payment form, Allocate a payment form with a running allocations list.

What you can do

  • Open account — picking a customer from the search field fills the underlying customer account id. / Load.
  • Recognise receivable — ties a new amount owed to a source document.
  • Record payment — captures the resulting Customer Payment id.
  • Allocate payment and Unallocate.

Related screens

The Customer account search field on this screen searches the same Customers list shown on the Operations workspace's Customers screen. Chart of Accounts and Trial Balance reflect the postings this screen produces.

Constraints to know

Recording a payment never auto-settles an invoice — allocation is a deliberate, separate step, and can be partially or entirely unallocated later. A 403 here can mean missing 2FA confirmation, not just role.

Payables

/finance/payablesworkspace: Finance
Shown here with no account loaded yet
Payables, open/load account forms
Payables — the supplier-side mirror of Receivables.

Purpose

The supplier-side mirror of Receivables — open a supplier's financial account, see what's owed, review the ledger, record a payment made, and apply it against outstanding bills.

What you see

Open / Load a supplier financial account cards, then account summary, Payables table, Ledger table, Recognise a payable form, Record a payment form, Allocate a payment form.

What you can do

  • Open account / Load.
  • Recognise payable, Record payment, Allocate payment, Unallocate.

Related screens

Supplier ids and source Purchase Order numbers come from Procurement; postings show up in Chart of Accounts / Trial Balance.

Constraints to know

Same recording-vs-allocation separation as Receivables. The Payable dropdown only shows payables not already SETTLED. This is a single-account-at-a-time tool — no “all overdue suppliers” list.

MIS Dashboards

/finance/dashboardsworkspace: Finance
Finance MIS Dashboards, DATA_INCOMPLETE badges
Finance MIS Dashboards, loaded for the real legal entity — every KPI card honestly shows a DATA_INCOMPLETE badge rather than a fabricated number, since no KPI/ledger mapping is configured yet.

Purpose

Gives finance leadership a one-screen snapshot of cash, receivables, payables, inventory value, profitability, period-close progress, and outstanding exceptions for a chosen company and date.

What you see

  • Dashboard parameters form (Legal entity id, Currency, optional As of date).
  • Six KPI cards: Cash & Bank, Accounts Receivable, Accounts Payable, Inventory Value, Close Status, Critical Exceptions.
  • Profitability (MTD), Tax (GST) Reconciliation, and Fixed Asset Reconciliation cards.

What you can do

Load dashboards — fires nine parallel read-only calls; each card loads and fails independently.

Related screens

None of the cards link onward — visit Receivables, Payables, Period Close, Tax, or Fixed Assets separately to act.

Constraints to know

Performs no calculations of its own. Every card can independently show DATA_INCOMPLETE rather than a fabricated number when configuration is missing — exactly what's captured in the screenshot above.

Period Close

/finance/period-closeworkspace: Finance
Shown here with no period close runs yet
Period Close, empty list
Period Close — browse list and manual lookup, no runs yet for this entity.

Purpose

Lets you look up a Period Close Run — the record tracking an accounting period moving through checks, soft close, hard close, and certification — to see its current state.

What you see

A Legal entity picker, a browse list of Period Close Runs (Id, Status badge, Started at), and a manual Period close run id lookup.

What you can do

Pick a legal entity to load its runs, then View a row or type an id directly — both display the full record.

Related screens

None — a standalone lookup.

Constraints to know

Read-only — the actual close actions (start, run checks, soft-close, hard-close, certify) exist as backend commands but have no buttons here. Treat this as a status-lookup tool, not the close workflow itself.

Tally Integration

/finance/tally-integrationworkspace: Finance
Shown here with no Tally company mappings yet
Tally Integration lookups
Tally Integration — Company Mapping browse list plus the three id-only lookup panels.

Purpose

Lets finance/IT staff look up how a company is mapped to Tally (the external accounting package) and check export batches and reconciliation runs.

What you see

A Legal entity picker, a browsable Tally Company Mapping list, and three id-only lookup panels: Mapping Version, Export Batch, Reconciliation Run.

What you can do

Browse/View a Company Mapping, or type any Mapping Version / Export Batch / Reconciliation Run id and press Look up.

Related screens

None — a standalone set of lookups.

Constraints to know

Read-only inspection only — no new export, reconciliation run, or mapping can be created here. Only Company Mapping supports browsing; the other three need an id you already have.

Dimensions

/finance/dimensionsworkspace: Finance
Shown here with no governed dimension values yet
Accounting Dimensions screen
Accounting Dimensions — dimension-value browse/lookup, and the voucher-line tag lookup.

Purpose

Lets you look up the governed cost-center/department-style Accounting Dimension tags used to classify transactions, and see which tags apply to a specific voucher line.

What you see

An Accounting Dimension Value panel (browsable list + id lookup) and a Voucher Line Dimension Tags panel (lookup by voucher line id).

What you can do

Browse/View a dimension value, or look up the tags recorded against a specific voucher line.

Related screens

None directly — get a voucher line id from Vouchers and bring it here.

Constraints to know

Read-only — no way to create a dimension value or tag a voucher line from this screen. No separate “Dimension Type” lookup exists.

Intercompany

/finance/intercompanyworkspace: Finance
Shown here with no intercompany transactions yet
Intercompany screen
Intercompany — Transaction browse/lookup and Reconciliation Run lookup.

Purpose

Lets you look up cross-legal-entity (“intercompany”) transactions and their reconciliation runs, to check how a transaction was split across companies and whether it has settled.

What you see

An Intercompany Transaction panel (browsable + id lookup) and an Intercompany Reconciliation Run panel (id lookup only).

What you can do

Browse/View a transaction (including its per-company legs), or look up a reconciliation run by id.

Related screens

None directly linked.

Constraints to know

Read-only lookups only — no create/settle/reconcile action exists here, and no summary dashboard was built for this area. Reconciliation Run has no browsable list.

Inventory Accounting

/finance/inventory-accountingworkspace: Finance
Shown here with no valuation layers matched yet
Inventory Accounting screen
Inventory Accounting — Find valuation layers, plus the Request/Approve adjustment maker-checker forms.

Purpose

Lets accounting staff look up how the value of stock on hand is tracked (FIFO-style valuation layers), and lets one person request — and a different person approve — a correction when it's wrong.

What you see

A Find valuation layers search form and results table, a Valuation layer detail card, a Request inventory value adjustment form, and an Approve inventory value adjustment form.

What you can do

  • Find layers — GET /finance/inventory-valuation-layers.
  • Request adjustment — POST /finance/inventory-value-adjustments.
  • Approve adjustment — POST /finance/inventory-value-adjustments/{id}/approve.

Related screens

Works alongside Trial Balance and Chart of Accounts; layers originate from goods-receipt/stock-movement activity in Inventory and Procurement.

Constraints to know

Maker-checker control — the requester cannot also approve; the server rejects a same-identity approval. There is no way to directly edit a valuation layer's value in place.

Tax

/finance/taxworkspace: Finance
Tax screen, request tax rule form
Tax — Request tax rule form (Approve tax rule and GST reconciliation cards continue below the fold).

Purpose

Lets tax/compliance staff define tax rules (rates and treatments), get a second person to approve each rule before it takes effect, and check that GST collected/paid matches the general ledger.

What you see

A Request tax rule form, a Tax rule detail card, an Approve tax rule form, and a GST reconciliation form/results table.

What you can do

  • Request tax rule — POST /finance/tax-rules.
  • Approve tax rule — POST /finance/tax-rules/{id}/approve.
  • Reconcile — GET /finance/gst-reconciliation.

Related screens

Ties into Chart of Accounts / Trial Balance and whichever sales/purchase screens generate taxable transactions.

Constraints to know

Maker-checker — the approver must differ from the requester. Transaction type and Tax treatment are restricted to a fixed, pre-approved list.

Banking

/finance/bankingworkspace: Finance
Banking screen
Banking — Open bank account form and Bank reconciliation form.

Purpose

Lets finance staff open a bank account record linked to the ledger, and reconcile the company's book balance for that account against the bank statement balance.

What you see

An Open bank account form, a Bank account detail card, and a Bank reconciliation form/results table.

What you can do

  • Open bank account — POST /finance/bank-accounts, wrapping an existing ledger of type BANK.
  • Reconcile — GET /finance/bank-reconciliation.

Related screens

The Bank ledger id comes from Chart of Accounts; reconciled totals would be cross-checked against Vouchers/Trial Balance.

Constraints to know

A bank account must link to a pre-existing BANK-type ledger. Reconciliation is a read-only computed comparison, not an editable worksheet.

Fixed Assets

/finance/fixed-assetsworkspace: Finance
Fixed Assets screen
Fixed Assets — Register fixed asset class and Register fixed asset forms.

Purpose

Lets finance staff set up fixed-asset categories, register a specific fixed asset against one, formally capitalise it once ready for use, and record moves to a new location or custodian.

What you see

Register fixed asset class card, Register fixed asset card, a Fixed asset detail card, a Capitalise fixed asset form, and a Transfer fixed asset form.

What you can do

  • Register class — POST /finance/fixed-asset-classes.
  • Register asset — creates it in DRAFT status.
  • Capitalise — moves DRAFT to capitalised with cost/dates.
  • Transfer — updates location/custodian within the same legal entity.

Related screens

No cross-link to the operational Assets screen — a PLMP “Asset” a customer owns is a separate concept from a Finance “Fixed Asset” the company capitalises on its own books.

Constraints to know

Registration and capitalisation are deliberately two separate steps. Transfer only works within the same legal entity. Nothing here lets you delete or directly overwrite an asset's cost or status.