ZuloOne
English
Sign in
Menu

Create a register

Updated

A register is movements (TR_) plus balances. Resources are the numbers that accumulate. Cuts are dynamic analytics: values are not columns on TR_; a movement points at an immutable set by one id.

Note

Do not add physical dimensions unless you will read raw movements filtered by that cut (QueryMovementsAsync). Balance reads (GetBalanceAsync) already re-aggregate analytics. A dimension is a schema column; an analytic is not.

How to#

1. Reuse an analytic from the global catalog (Analytics/<Name>.json) before you create one. Basics (Currency, UnitOfMeasure, …) already ship with Common. An analytic points at a dictionary through a Reference EDT.

2. The register — Registers/<Name>/<Name>.object.json: resources, bound analytics, registerEngineType: "Standard". Bind a foreign analytic by declaring the dependency, do not copy the analytic file.

3. Write it from a posting script on the document — typed transactions.Add(new <Register> { … }), or RegisterMovementSpec("<Register>").Dim(…).An(…).Res(…). The shape of the movement stays in the posting script. A service may compute the numbers; it must not assemble the movement.

4. Menu item in the model's Registers subgroup (the user opens totals from there), and bump modelVersion.

A balance on a date is ITotalsManager.GetBalanceAsync(register, resource, cut, onDate). Without a date it reads TB_ — the current total, which has no history. Use the dated overload whenever a backdated document asks "how much was there".

Tip

An information register (Set / SliceLast / SliceFirst) is a different object. Settings that change over time go there, not on an accumulation register. See Create an information register.

What's not there yet#

Virtual totals and custom reports are their own objects. This cookbook is the accumulation register a document writes.

Where next#

Was this page helpful?