EBM HubDeveloper documentationMenu

CIS workflows — EBM Hub 0.2.2

This guide describes implemented CIS workflows under certification evaluation. Applicant documents, assigned RRA test execution and physical printer qualification are separate release gates.

Prepare a branch

  1. Choose Development or Production. Every request, device, inventory balance and receipt belongs to that environment.
  2. Create the assigned branch and initialize its VSDC connection.
  3. Under Branches, save the trading name, two or more address lines, telephone and assigned 11-character MRC. Never invent the MRC.
  4. Fetch reference classifications and codes. Add catalogue items with appropriate country, type, units and tax category. Leaving item code empty generates country + type + packaging unit + quantity unit + seven-digit serial. Existing item codes are skipped.
  5. Register each item with VSDC. Editing a catalogue item requires re-registration. Register it for the branch used on the invoice. Goods need available inventory; services do not.

Issue receipts

Enter a unique positive invoice number, customer name, customer TIN or mobile number, payment method, items, quantities (two decimal places) and optional discounts. Review and issue. The server calculates tax and signs through the deployment's VSDC. The browser prepares a print snapshot automatically after a confirmed response.

A saved response is recovered using the same request identifier and unchanged request. Keep an uncertain request; do not create a replacement invoice. An uncertain branch transaction blocks new issuance and keeps reserved stock until reconciled. A failed stock delivery does not erase an already issued fiscal receipt.

  • NS: normal sale; reserves goods before signing, then deducts stock once.
  • NR: from Receipts → View → Refund this sale. Cancels the full original exactly once, preserves original quantities/prices/taxes and restores tracked stock. Record reason code and explanation. Partial refunds are not supported by this workflow.
  • CS / CR: from Receipts → View → Create COPY. Creates a new signed copy of the stored normal sale/refund. Does not change stock.
  • TS / TR: select training and explicitly activate training mode. Does not change inventory or normal-sale totals.
  • PS: proforma; does not change inventory or normal-sale totals.

Copies, training and proforma carry their designation and “THIS IS NOT AN OFFICIAL RECEIPT”. Refund monetary values print with negative signs. Legacy receipts lacking a reconciled CIS history cannot be refunded or printed as new originals through this workflow.

Printing and recovery

The intended paper formats are 58 mm POS rolls and A4. Select the corresponding paper size in the printer driver/browser, use 100% scale, and disable browser headers and footers. The 58 mm layout stacks item details; local qualification used 5 mm side margins (48 mm content width). Confirm the actual printable width with the chosen POS printer. A4 keeps the tabular layout. Long receipts may span driver-defined pages; cutter behavior is printer-specific.

Normal and refund PDFs for both formats retained required fields and decoded QR symbols at 203 dpi in the local layout check. This does not establish physical printing, paper-out recovery or power-loss behavior. The POS printer model is still to be confirmed.

The browser retains the preparation request identifier across refreshes and lost responses. Once printing is requested, that browser requires a COPY for another print. Each receipt can authorize one original print snapshot. The first successful preparation is journaled and retains the issuance profile/version. The same request identifier can recover the same snapshot after an interrupted response; a different request cannot authorize another original. Use a signed COPY for another print.

The browser cannot verify that a physical printer actually delivered paper. A print-dialog cancellation, empty paper roll or power failure therefore requires operator reconciliation and the documented copy process. Saving and printing from browser/OS facilities cannot be prevented by application controls alone. Qualify the intended printer and operational procedure before submission.

Receipt content includes identity/address/TIN, customer contact, quantities/prices/discounts, payment, group tax values, item counter, source reference, MRC, software version and VSDC data. QR payload is ddmmyyyy#hhmmss#SDC_ID#receipt_number#internal_data#signature. Signature and internal-data display groups use four characters.

Stock and inbound records

Stock & receiving shows on-hand, reserved and available balances and delivery status. Identical adjustment retries return the original operation without changing stock; changed input under the same identifier is rejected. Positive adjustments receive goods; negative adjustments remove available goods, with a reason and unique request identifier. A service cannot have stock. Each movement queues the prescribed stock movement and resulting StockMaster balance in order.

Import/purchase fetch dates must advance beyond the last successful request. Map incoming lines to active registered items in the same branch/environment with matching units and, for purchases, tax category. Imports require verified tax-inclusive unit costs in RWF; sale prices are not used as import costs. Record the approval/rejection reason. A confirmed approval applies stock once and queues movement/master updates. Rejected items do not add inventory. Import package counts retain the declaration value independently of quantity.

Multiple incoming lines may map to the same catalogue item. Each line retains its own price, tax and stock movement identity; the balance accumulates every line once. Supplier purchase content is retained; approved catalogue identifiers are mapped explicitly. Unknown responses are held for reconciliation, never blindly retried.

Use Load saved inbox in Stock & receiving to review imports and purchases already stored for the selected branch. It needs no request date and does not fetch upstream updates or advance the reference cursor. Completed records show their outcome; failed, unknown and submitting records show reconciliation guidance. Source details remain available for review.

The receiving form keeps the result beside the submitted decision. “Approval completed” or “Rejection completed” requires a nested fiscal result of 000; approval still requires checking stock delivery separately. A fiscal refusal displays its code and message. Uncertain codes (894, 896, 899), missing fiscal outcomes and lost responses direct you to inspect the inbound record and use reconciliation. Do not submit a replacement decision. The form prevents duplicate submissions while waiting, retains the original request after a lost response, and only re-enables submission for a definitive request rejection. After a refresh, Stock & receiving shows “Recover interrupted receiving decisions” with the original decision details. Use “Check and recover original decision” to inspect its server state and replay the exact saved body/key when pending or completed. Unknown, submitting and failed records require operator reconciliation and are not resubmitted by this control. Saved requests are isolated by company and environment; malformed browser records are preserved for operator review. Uncertain or incomplete HTTP 200 responses also retain the original request.

Pending delivery resumes in order on startup. SUBMITTING, UNKNOWN and FAILED entries block later delivery for that branch and require reconciliation with the configured VSDC. There is no automatic proof of an uncertain remote outcome; use the owner/operator reconciliation panel described below.

Reports and cash

Record cash deposits/withdrawals with amount, reason and a persistent request identifier. Generate X, Z, PLU, sales, stock, purchase, import or item report snapshots for the selected period. X/Z summarize activity since the last CIS Z close; PLU and detailed reports use the chosen date range. Amounts in the audit JSON's *_cents fields are integer cents; quantities named *_hundredths use hundredths.

Reports include current catalogue details, PLU remaining stock, per-mode payments/taxes, first period deposit, and opening/closing cash balances. Cash balances count payment code 01 plus deposits minus withdrawals; mixed cash/credit has no split in the VSDC request and is explicitly excluded. ITEMS is a snapshot of the current catalogue, not a reconstructed historical catalogue.

A CIS Z close refuses unresolved transactions, uncertain inbound decisions or pending stock delivery, stores its snapshot and prevents further invoices and cash movements for the closed day. A local CIS report is not an RRA submission acknowledgement. The supplied _9 WAR's separate /reports/saveZReports date defect remains unresolved; its rejected response must not be represented as successful upstream delivery.

API

Use the authenticated /api/portal prefix and existing environment header. Maintain X-Idempotency-Key across retries for invoices, print preparation, stock adjustments, inbound decisions and cash. Direct fiscal write routes are blocked for companies with CIS profiles so they cannot bypass stock/refund controls. Standalone VSDC deployments keep their own compatibility contract.

Key routes:

Route Method Purpose
/cis/profile GET / PUT Branch receipt identity
/cis/taxes GET / PUT Supported tax configuration and audit
/cis/items/register/{id} POST Register catalogue item
/fiscal/invoices POST Issue/recover a CIS invoice
/cis/receipts/{id}/print POST Authorize/recover original print snapshot
/cis/stock GET / POST Balances and adjustments
/cis/delivery GET Inspect deliveries (read-only)
/cis/recovery GET / POST Inspect and reconcile uncertain stock/inbound operations
/cis/references/{kind} POST Fetch imports, purchases, customers or notices
/cis/inbound GET Imported/purchased source records
/cis/inbound/{id} POST Approve or reject
/cis/cash POST Cash movement
/cis/reports POST Generate local report snapshot

Normal invoice example:

{
  "branch": "00",
  "invoice_number": "101",
  "mode": "NS",
  "customer_name": "Customer",
  "customer_phone": "0781234567",
  "payment_code": "01",
  "lines": [{"item_id": "YOUR_REGISTERED_ITEM_UUID", "quantity": 2, "discount_percent": 5}]
}

The response retains the VSDC envelope and adds cisReceiptId. A refund/copy supplies source_receipt (the stored receipt UUID) and an empty lines array. Use the original receipt rather than resubmitting editable source data.

Operator reconciliation

Use Stock & receiving → Reconcile uncertain deliveries. Only a signed-in company owner or platform operator can reconcile or program the receipt profile. API keys cannot perform this management action.

  1. Load the branch's unresolved operations and review the stored payload.
  2. Verify its actual outcome from the configured VSDC's records. For accepted, obtain the successful response for that exact operation. For not applied, obtain positive evidence that the operation did not take effect. A missing response alone is insufficient.
  3. Select the verified outcome, record the evidence reference and details, and attach the successful response when accepted.
  4. The server checks the payload SHA-256 fingerprint and unresolved state, saves the previous record and decision in cis_reconciliations, and updates state atomically. Accepted inbound decisions apply the durable stock snapshot once; confirmed unapplied operations become eligible for processing again. The recovery endpoint itself sends no upstream request. Background delivery may resume eligible stock operations afterwards.

This is an operator-attested reconciliation, not automatic verification or proof that the supplied response came from RRA. If the actual outcome cannot be verified, leave the operation held. Existing decisions from older releases without a durable payload/stock snapshot need a separately reviewed migration.

POST/cis/recovery accepts branch, kind (delivery or inbound), id (string), payload_sha256 from GET, outcome (accepted or not_applied), evidence (10–4000 characters), and response (successful VSDC envelope or null). Preserve X-Idempotency-Key across retries. Invoice recovery continues through /fiscal/invoices using its original request; this endpoint cannot invent a fiscal receipt.

Known configuration limits

Branches → Tax configuration lets an owner/operator load and save A/B/C/D rates with an audit reason. The supported WAR contract validates A/C/D=0 and B=18. Unsupported values are rejected without changing configuration. Each new invoice snapshots its branch rates; existing invoices keep their original values. This is configuration within the selected contract, not permission to introduce rates that the VSDC rejects. Physical paper recovery remains subject to printer qualification.

Repeated lines and unit conversion

Map every incoming line, including repeated items, to the appropriate registered item. The selector shows the target quantity and package codes and restricts items to the selected branch. Prices and tax totals remain separate for each line. Stock movement identity now includes its line position; retrying an approval does not add those lines again.

If source and target units differ, select Convert this line and enter target/source ratios separately for quantity and packages. For one box containing ten units, enter quantity numerator 10 and denominator 1. A package code that stays the same must use an identity ratio, such as 1/1. Record the evidence/reason for the conversion. Ratios must be positive integers no greater than 1,000,000.

Conversion preserves the incoming line's monetary totals and tax. Quantity is multiplied by the ratio; unit price is divided by it. Both must be exactly representable to two decimal places. A conversion that would silently round stock or price is rejected before any approval is submitted. Choose an exact unit instead of changing the declared total. Import unit cost is entered per source quantity unit in RWF, including tax; conversion calculates the target unit cost.

For rejection, no catalogue mapping, conversion or import cost is required. Purchase rejection still needs its purchase invoice number because it is part of the VSDC request.

The inbound decision's optional conversions array aligns with source lines. Use null for an unchanged line. For example:

[
  {"quantity_numerator":10,"quantity_denominator":1,"package_numerator":1,"package_denominator":1,"reason":"Supplier packaging: ten units per box"},
  null
]

PUT/cis/taxes accepts branch, rates (exactly A/B/C/D) and a nonempty reason. Read /cis/taxes?branch=00 to inspect current/supported values. Migration 022 adds the tax configuration/audit tables and stock movement line identity. Back up and qualify upgrades using the installation/restore guide.

Supplier purchase returns

An incoming supplier sale (S) is saved to the VSDC as a purchase (P). An incoming supplier refund (R) is handled as a full return of one original approved purchase, rather than as incoming stock.

For approval, enter the original CIS purchase invoice number, map the incoming lines, and supply any exact unit conversions. Supplier identity, line quantities, unit prices, discounts, taxes and totals must match the original. Line order may differ. The CIS preserves the original line/stock snapshots, reserves the goods before submission, and removes them only after acceptance using outgoing-return stock type 12. A second full return is blocked. Uncertain returns keep their stock reservation until reconciled; a verified unapplied outcome releases it, and verified acceptance deducts it once.

Purchase invoice numbers are unique within the branch/environment. Rejection does not affect stock and does not require an original reference. Partial supplier returns are not supported by this full-original workflow. Legacy ambiguous originals or return records without direction/reservation metadata require reviewed reconciliation.

The optional inbound field original_invoice_number is required when approving an incoming purchase refund. Ordinary purchases must omit it. Stock data is validated before the upstream approval call so malformed receiving data cannot leave an accepted decision without a valid local stock entry.

Recover and reopen reports

Report generation stores a persistent browser request identifier before submission. If the response is lost, return to Reports: the original fields are restored. Generate again to recover the same snapshot, including a Z report that already closed its period. Do not change the restored request to close a different period.

Use Saved reports to browse branch history and open an original snapshot for viewing or printing. Later profile/catalogue changes do not alter that snapshot. This retrieves a local CIS report; it does not establish RRA report submission.

Dashboard delivery counts

The overview separates locally issued receipts with confirmed acceptance, local receipts still awaiting acceptance, and external VSDC receipts. An external VSDC signing response does not independently confirm upstream delivery; reconcile that delivery through the configured VSDC. These counts describe stored receipts for the selected company/environment, not billable usage or payment collection.

Questions about onboarding, keys or branches? Contact your EBM Hub onboarding contact.