ZuloOne
English
Sign in
Menu

Process map

Updated

How each business contour runs, and where it stops. Object fields and registers are the reference docs/reference/business-layer/; the buttons that change a document's state are the commands. The mobile client is its own page.

← Business process wiki

Contours#

# Process How it runs Limits
1 Master data and organisation Countries, currencies, legal entities (VAT included), addresses with a country and a district, divisions, sites, the BuySell profile on ApplyOrg, the country package by the legal entity's ISO2, the payment term PaymentTerm and the delivery term DeliveryTerm (Incoterms 2020, 11 shipped rows) —
2 Units and packaging Quantity class + RatioToBase, the ItemUnit packagings, both converters —
3 Pricing The price list on the item card (PriceTypeHistory), the ladder, a live line hook (OnFieldChanged: empty unit and price), fill commands, tier discount —
4 Manual posting and the chart of accounts Chart, periods, journal, the Post command, Dr=Cr balance, a closed month refuses every posting; the GL by legal entity and account layout (legal entity, account, debit and credit; zero values on both sides are hidden); a JournalEntry is only ever a manual entry — no business document spawns one (see process 16); exchange differences on receivables and payables, realised at payment and unrealised by ReceivableRevaluation / PayableRevaluation —
5 Store: receipt and put-away PurchaseOrder → Received, a draft PutAwayTask, the store yard when the flag is on — EnforceWarehouseTasks is off by default on purpose: a stand that does not run a bin-addressed yard must not be forced into put-away tasks to receive goods
6 Store: picking Manual PickTask; when process discipline is followed, the FulfillmentScheme shipping scheme works as follows: simplified posts a StockTransfer to the order cell if storage has enough; extended and an empty field leave a draft pick for each storage cell that gives quantity (a line that is short in total gets no draft), and the storekeeper moves the rest; Gather pick wave combines drafts of several orders from one storage cell into one task; confirming picking does not take another reservation on the storage cell, and its own draft does not block itself —
7 Store: adjustment, transfer, stocktake, issue Four documents plus posting commands, the stocktake delta in Tx; a line has its own cell (empty means header cell): one transfer can take from several cells, write-off and issue check the line balance, stocktake compares the count with the line cell; a transfer line also has its own ToCell (empty means the header target), so one transfer can spread one source over several destinations; issue, transfer and write-off refuse when free stock (physical stock minus another reservation) is below demand —
8 Purchase order → payment Draft→Ordered→Received, input tax, VendorPayment, PurchaseReturn (net, does not take another cell's reservation), PurchaseCreditNote (input VAT), GL; AutoReceiveOnOrder receives from Place order; DueDate from terms (IPaymentDueService); line field Receive now receives part of the quantity and puts the rest into a new Ordered order; Payable by supplier layout (supplier, zero outgoing hidden); SupplierInvoice is a document of its own — Enter supplier invoice on a received order, Register books only the difference from what the receipt accrued, with input tax, and refuses a blank supplier number or a difference beyond PurchasingSettings.InvoiceMatchTolerance; the difference is booked as a purchase price variance in P&L; a receipt may be invoiced in parts, each invoice matched against the receipt price of its own quantity, never beyond what was received The difference does not re-cost received stock — that is the costing policy, not a gap
9 Sales order → money Submit/Approve → a realization in Reserved…Issued, mandatory contract, credit/prepaid by the contract slice, tax and debt only on Issued, release does not write off another cell's reservation (the realization's own reservation and this order's picking are not a refusal), payment and credit note are separate documents; SalesLead New→Qualified→Quoted creates a draft quotation; SalesQuotation Draft→Issued→Converted creates a draft order; DueDate from terms; Incoterms travel from the contract through the order and quotation into the realization and print form; Receivable by customer and contract layout (customer, then contract, zero outgoing hidden); Revenue by item, customer and contract layout (item, customer, contract, line amount without tax) e-invoice
10 Reservation and free balance ReservedStock is written by the realization (Reserved…Shipped) on the realization cell; a draft PickTask holds the same amount on the storage cell, and pick confirmation moves the reservation to the picking cell; cancelling the order removes it; a draft ProductionOrder holds components on the write-off cell, and release/finish remove the reservation together with the Stock write-off and refuse when free stock (excluding another reservation, not excluding its own draft and what this order already wrote off) is below demand; free = Stock − reserved; ATP adds a placed purchase order with ExpectedReceipt no later than the shipment date (empty and payment term do not promise a receipt; a received order is already stock); Reserved stock by item and cell layout (item, cell, zero outgoing hidden) —
11 Production BOM, Explode, Routing → Operations on the order, Released (write-off + WorkInProgress) → Finished (output, Mix removes WIP), capitalisation; shop-floor operation mark (ActualMinutes / CompletedOn / Employee + Confirm operations) and labour in cost by the position or work-centre rate; BuySell disables the order; print ProductionOrderZr; ledger: Released Dr WIP / Cr stock, Finished Dr stock / Cr absorbed labour; WorkCenter.CapacityMinutesPerDay and IWorkCenterLoadService queue — release warns about overload, and marking an operation removes it from the queue; Schedule operations schedules operations by sequence and daily capacity; output cell on the order (empty copies the module setting if set, otherwise the product lands on the write-off cell; components and WIP stay on the order cell); Work in progress by item and cell layout; shift calendars with holiday and overtime exceptions, and parallel machines on a work center, each operation planned onto its own machine (MachineNo); Replan shop replans all released orders by Priority and RequiredBy and names the late ones The replan is greedy (first fit), not an optimiser minimising lateness
12 Stock and sales cost FIFO and average (the receipt includes non-recoverable input VAT), COGS in the ledger, surplus/shortage, standard cost as a price type (CostingSettings.StandardPriceType), sales margin IGrossMarginService, GrossMarginReport (revenue − write-off of the same document and item), labour share through the production order (ILaborCostService); Inventory value by item layout (item, quantity and amount; both zero outgoing values hidden) —
13 Tax: determine and compute Codes, rates, rules, NonRecoverablePct → stock, dated TaxRegistration, TaxExemptionReason on exempt lines, TaxProfile / TaxMapping; all five document paths (invoice, credit and debit note, receipt, supplier return) supply ITaxService.DeterminationContext. The calculation lives and dies with its source (TaxCalculationLifecycle): every unpost — a step back to Draft, a re-post after an edit, the first step of a delete — withdraws the TaxCalculation to Draft, so its TaxLedger, ledger and settlement movements leave with the source's own; the next posting re-determines the same calculation in place, and deleting the source deletes it. A Filed return is the hard stop — the withdrawal is refused by name, and the correction is a credit or debit note. Determination asks the seller's country before it asks the stand: the entity's Country → ISO-2 → TaxJurisdiction → the one standard-treatment TaxCode that also has a rate in force on the tax point. A Saudi entity is therefore computed with the Saudi code the moment it exists; the PinSaudiTaxCodes job stays, because the pin is what makes the decision visible as data. The country answers only when it names exactly one such code, and it steps aside when the entity already carries a TaxMapping row, including a disabled one: switching the pin off is a decision ("compute this entity with the stand default"), not a blank. A purchase under a REVERSE_CHARGE code produces one TaxCalculation with two lines — the self-assessed output half and the input deduction, same base, same amount, same code — because they are one tax event and must post, unpost and reverse together; the reversal gives each line back its own direction, and TaxReturnService nets output − input while both halves stay visible per direction. A partly recoverable reverse charge is refused rather than guessed a country whose jurisdiction carries several standard-treatment codes cannot answer for itself. Ukraine's carries VAT, the single tax, personal income tax and the military levy — more than eight standard codes — and which of them applies depends on the entity's regime, so there it is still TaxMapping (written by the Ukrainian settings when UaTaxRegime changes) or the stand default that decides. There is no country-independent tax-regime switch on the legal entity
14 Tax: return and payment TaxReturn assembled from the ledger by Build return on TaxPeriod (BuildTaxReturn), named TaxPeriod, TaxReportMapping cells, TaxPayment, TaxSubmission log (mock); prints TaxReturnZr / TaxPaymentZr; Tax ledger by code, direction and entity layout; the Saudi package ships the VAT-SA box layout (sales 1/3/5, purchases 7/10/11, both directions of RC-SA into 9; out-of-scope deliberately unmapped) and Export for filing → SaTaxFilingExport (all sixteen boxes, each marked ledger / computed / manual), the Ukrainian one form J0200126; a reverse-charge import is declared twice in the return and shown once on the sheet, its self-assessed half spent in box 13 (box 6 VAT + self-assessed − box 12 VAT) rather than added into box 9 a second time live HTTP to the tax authority; no Saudi electronic return file or upload; Saudi import box 8 (VAT paid at customs) has no source — Purchasing has no customs clearance document to take it from
15 E-invoice and ZATCA TaxDocument; VAT/CRN; atomic ICV; UBL; C14N hash; QR embedded in Payload; XAdES when CSID DER exists; fatoora-* queue on stub; CSR+OTP+six sample kinds+PCSID in the model; Standard by buyer VAT; S/Z/E/O from TaxCategory.Treatment (E/O with VATEX on the category extension); a Standard invoice cannot be handed to the buyer before Cleared (IEInvoiceRelease / ISaudiEInvoice); InvoiceZr/CreditNoteZr/DebitNoteZr and ZATCA forms; Cleared/Reported from the channel (ApplyFatooraOutcomes job); ERP debit note SalesDebitNote live gw-fatoora, C14N 1.1 / schematron, mixed rates in lines
16 Posting to the general ledger Sales, purchasing, payroll, contributions, payments, VAT, COGS, stock write-offs, closed FiscalPeriod; account profile as references to ChartOfAccounts; production: WIP on release, absorbed labour on finish. Ledger legs live in the models that own the documents: IGeneralLedgerService writes GL movements straight from the posting document; a JournalEntry is only a manual entry. Exchange differences: realised at CustomerPayment / VendorPayment, unrealised at ReceivableRevaluation / PayableRevaluation, to FxGainAccount / FxLossAccount of the settings; an empty account posts no leg and the registers still move —
17 Payroll Timesheet grid (40-hour week + TimeOff), accrual → payment, net after contribution, GL; Position.MonthlySalary pro-rated by hours; Voided on accrual / payment / contributions / payment to fund; prints TimeSheetZr / PayrollAccrualZr / PayrollPaymentZr; Payroll liability by employee layout (employee, amount and withheld); Social insurance by employee layout (employee, employee share and employer share). Overpaying an employee is refused per employee in PayrollPaymentEventHandler.OnBeforePostAsync — PayrollLiability.allowNegativeBalance:false does not do that job, because the register keeps Employee as an analytic and the engine guards the balance over dimensions, so at engine level the whole register is one bucket — Other payroll taxes are a country package's job by design, not a hole in HR: the reference states twice that HR must not know personal income tax or a military levy, and gives the seam instead — PayrollLiability.Withheld, which no HR tx script writes. LocalizationUkraine is the working consumer (ПДФО and ВЗ, UaPayrollLevyEventHandler), and the split is load-bearing rather than cosmetic: ЄСВ is capped at 15 minimum wages while the two withholdings have no ceiling at all, so reusing the contributory base would under-withhold from everyone above the cap. A stand with no country package withholds contributions only, which is the intended behaviour
18 Social insurance Accrual from payroll, withholding, payment to the fund, GL; prints SocialInsuranceAccrualZr / SocialInsurancePaymentZr. Contributions beyond statutory social insurance are the ContributionType dictionary: own employee/employer rates, own foreign-staff pair, own wage ceiling, own expense and payable accounts. One accrual carries the statutory line plus one line per active type; the SocialInsurance register is sliced by the ContributionType analytic, so a payment to one fund does not close the debt to another —
19 Loyalty Points from invoice, tiers, redemption, discount on invoice, earn rate from LoyaltyTier.EarnRate, dated LoyaltyCampaign with optional ItemGroup and customer type (empty means all; card text means only this type; the narrow window beats the wide one); purchase history CustomerPurchaseHistoryReport; the agent phone catalogue shows the campaign without customer type (CachedCampaign, own group beats common); Loyalty points by customer layout —
20 Transition commands in UI A button on every working edge; checks go through services; RejectSalesOrder returns Submitted to Draft —
21 Register totals report (Stock) Hierarchy, chips, ledger by document, slice by enabled dimensions; the StockByItemCell layout (item, then cell, opening/incoming/outgoing/closing, zero closing hidden) is shipped with Inventory; a custom layout is saved from the report tab
22 ABC/XYZ Profiles, bands, Recalculate, AbcClassification log, nightly RecalcAbcClassifications; the agent phone shows the class from the slice (CachedAbc: one profile is A/X, two include the profile name) on item and customer lists, in selection and in the order line; AbcPolicyCell cells (keep N days of consumption or order to demand) and AbcSuggestion log by Build replenishment; item profile field Item group narrows recalculation (empty means whole catalogue, Pareto inside group); the nightly job writes AbcSuggestion for enabled item profiles (skips customer profiles); desktop widget ABC replenishment shows lines with quantity to order above zero; Create purchase drafts writes a draft from lines with quantity above zero, supplier and price from the last accepted receipt, expected receipt empty, repeat does not spawn another draft
23 Delivery and trips DeliveryTrip, route and vehicle dictionaries, trip commands; planned departure from the schedule and actual dispatch/completion; stop windows copied to lines; per-stop actuals (ArrivedAt / DepartedAt, window verdict on completion, refusal if departure is earlier than arrival); print DeliveryTripZr; planned pin on a stop is copied to the line, actual latitude/longitude, route tolerance in metres names the stop farther than planned; Optimise stop order on the draft. A time window steers that choice instead of refusing the trip: SalesSettings.RouteAverageSpeedKmh (empty or zero = 30 km/h) turns metres into minutes, and the next stop is the cheapest by travel + waiting + lateness + the slack left in its window, so the stop whose promise expires soonest is pulled forward. An unwindowed stop is charged the same constant slack as a full window, so an all-unwindowed trip is ordered by distance. The outcome counts the stops still at risk, before and after No road graph: distances are straight-line, so the lateness count in the outcome is optimistic and says so
24 Field sales AgentVisit, VisitRoute, AgentGpsLog, check-in/check-out, Field desk, Manager: Submitted queue + ApproveSalesOrder / RejectSalesOrder; office has the same pair; Warehouse: Pick / Put away / Cells by the yard zones of the task store (Store/StoreZone/StoreCellType) with balance by bin and bins on the item card; prints VisitRouteZr / AgentVisitZr; an order with Visit is linked to the visit (card and print name the number, without amounts); Approve order on the purchase order above PurchasingSettings.ApprovalThreshold (empty or zero = off, the default), approval is granted for a SUM and goes stale when lines are added Approval is one step by decision: the reference specifies one threshold, one ApprovedAmount and one ApprovePurchaseOrder command, and a second level is not part of it. The approver role is a command right, not a field — grant Execute on the command in the role matrix (MetaObjectPermissions, object Command); until a row exists the button is open to everyone, once it does a granted role is required. A field naming the approver would be worse than nothing: a command does see CommandContext.UserName, but it arrives in the request body rather than from the verified token, so the document would carry a signatory the client named for itself
25 Ukraine: VAT (ПДВ) on the first-event rule (перша подія) Its own Tax with Ukrainian codes (countries do not share one tax), dated 20 / 7 / zero / exempt rates from vat-UA; first-event accrual — UaVatFirstEvent register + totals driver and UaFirstEvent service: prepayment is taxed before shipment, shipment does not accrue a second time, partial prepayment adds up to full VAT; credit note moves the base, not only tax, and does not release it while the prepayment is retained; VAT of different outlets of one customer is not mixed; UaVatPayable; LocalizationUkraineSettings (3%/5% single-tax codes, ПДФО and military levy (військовий збір) codes, invoice and adjustment form codes, e-invoice flag; the tax number lives on LegalEntity.TaxRegistrationNumber); tax regimes UaTaxRegime on the legal entity: VAT payer (default), simplified 3% with VAT, simplified 5% without VAT, general without VAT — one database computes an LLC (ТОВ) and several FOPs (ФОП); legal entity is a dimension of UaVatFirstEvent; single tax (єдиний податок) goes into Tax.TaxLedger with its own EpAccrued base counter (for a 3% simplified payer ЄП is taken from income WITHOUT VAT); payment with a legal entity contradicting the line contract is refused, and an empty legal entity is taken from the contract; input VAT credit on the first-event rule (ПКУ 198.2) — UaPurchaseFirstEvent (legal entity × supplier: Received net / PaidOut gross / Credited) and UaVatCredit; supplier advance gives credit before delivery; annual income limit (ПКУ 291.4) is dated in UaSingleTaxLimit, and excess is taxed by LEGAL FORM, not by regime: ФОП — 15% UA-EP15 (row 07 of form F0103309), legal entity — double 6/10% UA-EP6/UA-EP10 (row 2 of form J0103509, ПКУ 293.5); LegalEntity.IsLegalPerson, empty = ФОП; Export for filing on TaxReturn writes a neutral file to UaTaxFilingExport; payroll: ЄСВ 22% in HRSettings, ПДФО 18% and military levy withheld into UaPayrollLevy and TaxLedger; Ukraine payroll levies by employee and tax code, Ukraine VAT payable by customer and contract, Ukraine input VAT credit by supplier layouts; withholding reduces debt through PayrollLiability.Withheld; ЄРПН — TaxDocument envelope from invoice and credit note, erpn-send queue, receipt collection by PullUaTaxInvoiceReceipts and a button. Export DPS payroll forms on the return writes J0500111 (розрахунок), J0510411 (4ДФ), J0510111 (Д1) and, when there are events in the period, J0510511 / J0510611 (Д5 / Д6) — each as a CSV workpaper and an unsigned DECLAR XML with the real field tags, for import into M.E.Doc Operator specification: ДПС form field names and receipt format are a neutral contract with one adapter point; no live M.E.Doc / bank cabinet, so the exchange itself is not covered by tests. ZuloOne prints no rendered 4ДФ sheet — the filing program renders the form, ZuloOne supplies the figures and the import file. Д2 and Д3 are not written (an ordinary employer does not file them), and neither is the № 499 КЕП container

End-to-end contours#

Purchase ──► Receipt ──► [put-away, if the flag] ──► Storage
                                                │
                    Production ◄────────────────┤
                                                ▼
Lead ──► Quotation ──► Order ──► Realization(Reserved…Shipped) ──► Issued ──► Payment
                       reservation             │
                       [picking, if the flag]  ├── tax / ledger / loyalty
                                               └──► Return

Tax and the ledger hang off the receipt and only off Issued on the realization (not off the reservation). A payment is always another document. The trip is an option, not the axis.

What's not there yet#

Do not hunt for these as missing settings. They are not in the product.

  • Live filing to the tax authority. TaxSubmission logs Accepted/Rejected. The mock rejects when TaxAuthorityConnection.IsMockReject is on. There is no live HTTP in the country-neutral core. Saudi live gw-fatoora is the e-invoice contour, not this one.
  • Saudi VAT return file. The sheet and Export for filing exist; there is no electronic return upload. Import box 8 (VAT paid at customs) has no source document.
  • E-invoice. Live Fatoora, C14N 1.1 / schematron, and mixed VAT rates on credit/debit note lines are not in the product.
  • Ukraine operator. MakeDoc/ToGov is in the package; there is no live M.E.Doc or State Tax Service cabinet on the stand, and no rendered 4ДФ sheet.
  • Production replan is greedy first-fit, not an optimiser.
  • Trip distances are straight-line; there is no road graph.
  • Multi-code tax jurisdictions (Ukraine) cannot pick a default code from country alone; they use TaxMapping or the stand default.

The period close is in place: a closed FiscalPeriod refuses posting and unposting on every path (DocumentPostingService). With no calendar row for the date, operations are not blocked. The core posting boundary is a different door: one date per tenant, not a calendar of months.

Not doing / deliberately different from the reference#

The reference How it is done, and why
SalesRealization Draft→Issued→Paid Paid is unreachable. Payment is CustomerPayment. Mix would erase stock and revenue.
One SaleDocument for everything (Mix) Two documents: the order (commerce) + realization (reservation→stock/debt/tax).
Reservation on the confirmed order Reservation is on the realization Reserved…Shipped; the order writes no scripts.
PurchaseOrder straight into receipt There is Ordered. Receipt is a separate command.
ProductionOrder Draft→Released→Completed Ours is Draft→Released→Finished. There is no Completed.
Reservation as Reserved/Available dimensions on Stock A separate ReservedStock register (Sales). Free = Stock − reserved.
IWarehouseLocationService IStoreCellService covers the role.
Double entry on Stock against the outside world Dropped: the cell balance is the on-hand stock.

Where next#

Was this page helpful?