Skip to main content
Version: 7.0

Numerator

The Numerator module generates sequential, human-readable numbers and codes for objects — order numbers, invoice numbers, partner codes, and similar. Each kind of object keeps its own counter, the generated value carries an optional series prefix and a fixed number of leading zeros, and the generation survives several users creating objects at the same time without producing duplicate or skipped numbers.

Numerator object

A numerator is a settings object of the Numerator class — one counter that several objects share. Its settings:

PropertyMeaning
name[Numerator]Name shown when a numerator is picked
series[Numerator]Series prefix prepended to every generated value (may be empty)
minValue[Numerator]Starting counter value; curValue[Numerator] is set to it when the numerator is created
maxValue[Numerator]Largest allowed value; once curValue[Numerator] reaches it, generation stops and a message is shown
stringLength[Numerator]Width the counter is padded to with leading zeros
curValue[Numerator]Current counter value — the number that will be issued next

The next value is formed as series[Numerator] followed by curStringValue[Numerator], where curStringValue[Numerator] is curValue[Numerator] written as text and padded on the left with 0 to stringLength[Numerator] characters. For a numerator with series WKO, current value 42, and length 6, the issued value is WKO000042.

Producing the next value

Two actions issue the current value and advance the counter; they differ in how they hold the counter against concurrent saves.

incrementValueSession[Numerator] advances the counter inside the current session, so issuing the number and saving the object happen in one transaction. When two users save at the same time, both transactions update curValue[Numerator] of the same row, so the second one gets a CONFLICT UPDATE; the platform rolls it back and replays it automatically, with no user action. The user only sees a slightly slower save, and the numbering stays gapless.

incrementValue[Numerator] advances the counter in a separate short transaction of its own and exposes the issued value through incrementedValue[]. This keeps the lock on the counter row out of the object's main save transaction, which shrinks the window for a conflict; in exchange the number is consumed even when the object is not ultimately saved, so gaps in the numbering become possible.

Both actions show a message and issue nothing once curValue[Numerator] has reached maxValue[Numerator].

Numbering a class

A set of metacodes attaches numbering to an application class. The number-carrying properties go into the system numbered group.

MetacodeWhat it adds to the class
@defineNumbered(class, stype)Stored number (text) and series (of type stype) properties, and seriesNumber — their concatenation, materialized and indexed as the combined searchable key
@defineNumerated(class)A numerator reference on the class and an event that fills number and series from it (via incrementValueSession[Numerator]) as soon as the numerator is set and the number was not entered manually or by import
@defineNumeratedDefault(class, caption, series)Everything @defineNumerated adds, plus a default numerator for the class, chosen on the defaultNumerators form and assigned to every new object automatically; an initial numerator (caption, series, range 1..99999, length 5) is seeded through loadDefaultNumerators
@defineNumeratedID(object, caption)A default numerator whose issued value is written into the object's own id instead of a separate number, for objects whose code is their identifier

@defineNumbered also normalizes the entered number and series, governed by three options on the options form: useLoweredNumber[] lowercases the number, useUpperedSeries[] uppercases the series, and spaces are stripped from the number unless keepNumberSpaces[] is set.

When the order of saving must not depend on the counter — to reduce conflicts on a heavily used numerator — @addEventGenerateNumberOnForm(form, object, class) adds an event that runs before the form's save and, while the generateNumberOnForm[] option is on, issues the number through incrementValue[Numerator] (the separate-transaction variant above) rather than during the save itself.

Default numerators

loadDefaultNumerators is an abstract list action that the seeding metacodes extend to create the initial numerators on a fresh database; it is wired into the platform's initial-data mechanism. The numerators form manages the catalogue of numerators, and defaultNumerators — added to the Master data navigator group — collects the default-numerator choice of every class set up through @defineNumeratedDefault or @defineNumeratedID.