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
dimensionsunless 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.