Skip to content

SO Consolidation

The batch biller: it gathers the order lines of many finalised sales orders and, when you press GENERATE SI, issues one internal sales invoice per company, branch, customer and sales agent, from a run you create or from a dated event. The invoice is created as a draft, so nothing posts until someone finalises it in Sales Invoice (Internal), and undoing a run means voiding or deleting that invoice there. No screen shows whether a run worked, so judge it by its Sales Orders and Sales Invoices tabs, and check what was billed before, because the run cannot.

Your job, and the screen for it

The jobScreen or tabRead
Bill many finalised sales orders together — one invoice per company, branch, customer and sales agent; pick the template on Create, date it today or earlier; finish the last run for that company and branch firstSO Consolidation Run › Create, with an SO Consolidation TemplateTemplates, and what a run actually picks up; Run — Create
Choose the order lines and issue the draft invoices — tick only lines not on an invoice yetRun detail › Sales Orders tab, then GENERATE SIThe pipeline; Templates, and what a run actually picks up
Check what a run produced — the listing’s Status column is not the resultRun detail › Sales Orders and Sales Invoices tabs; reload Sales Invoices after GENERATE SITroubleshooting
Finalise the consolidated invoices — they are drafts and post nothing until then; check each one’s date and billing address firstSales Invoice (Internal) appletPosting proof
Schedule a dated or repeating consolidation — give a repeating rule an end, and check a run appeared after each event dateSO Consolidation Event › Create, with Is Recurring / RRULEEvent — Create
Set up a billing group to reuseSO Consolidation Template, then its filter tabs after saving; a sales agent on every Sales Order (Internal) headerBefore you can use it; Templates, and what a run actually picks up

Overview

SO Consolidation is the batch biller. Where a customer has accumulated many finalised sales orders over a period — a month of deliveries, a week of counter orders — this applet gathers the order lines and issues one consolidated internal sales invoice per customer, instead of one invoice per order.

It has three objects. A Template is a saved filter set you can reuse. An Event is a dated (and optionally repeating) instruction to consolidate. A Run is what an event produces, or what you create directly: a named, date-bounded batch whose lines you can inspect and whose resulting invoices you can see.

The same consolidation machinery also carries a parallel Job Sheet variant — Job Sheet to Sales Invoice — with its own applet, JS Consolidation. Its page says where it differs from this one.

A run’s recorded result cannot be trusted, and no screen shows it anyway. A known defect means the run never counts the order lines it matched, so after making its lines it records the run as FAILED with the message “There is no Job Sheet under company: … branch: … customer: … salesman: …”. On a run you create on the screen, that result is then overwritten with a success. The listing’s Status column is neither: it is the record’s own ACTIVE or INACTIVE. Judge a run by its Sales Orders tab (were lines made?) and its Sales Invoices tab (were invoices made?). See Troubleshooting.

Where it fits

DirectionAppletWhy
UpstreamSales Order (Internal)Only lines of a Sales Order (Internal) at posting status FINAL are eligible
DownstreamSales Invoice (Internal)The consolidated invoice is an ordinary internal sales invoice, created as a draft; finalising it there is what posts revenue and moves stock
BesideJob Sheet (Internal)The same consolidation machinery has a Job Sheet to Sales Invoice path of its own
BesideSchedulerNot used. The consolidation jobs run when you save a run or an event, or press GENERATE SI. A Scheduler entry cannot start them, and nothing sweeps them later

Screens and menus

Three screens, all linked, plus the standard Settings and Personalization sections.

Menu itemRouteWhat it is
SO Consolidation Runso-consolidation-runThe main screen. A listing of runs (Run Name, Created Date, Updated Date, Status), a Create form, and a detail view
SO Consolidation Eventso-consolidation-eventDated instructions to consolidate, with optional recurrence
SO Consolidation Templateso-consolidation-templateReusable filter sets that an event or run can be seeded from

The Run detail view has eight tabs: Details, Branches, Companies, Customers, Sales Agent, Export, Sales Orders, Sales Invoices. The four filter tabs each have an Add sub-screen that picks the entities for that run; the Sales Orders tab lists the candidate order lines (Branch, Customer, Sales Agent, Item Code, Qty) and is where selection happens — selection is at line level, so part of a sales order can be consolidated and the rest left open; the Sales Invoices tab shows what the run produced.

Screenshots for this page are still to be captured. A capture session on a scratch tenant needs: the Run listing; Run → Create with a template selected; the Run detail Details tab; the Sales Orders tab with lines selected; the Sales Invoices tab after a successful run; the Event listing; Event → Create with recurrence on; and the Template listing. Invented customers and sales agents only — the run screens are full of counterparty names.

Configuration

Before you can use it

PrerequisiteWhereWhy
Sales orders at posting status FINALSales Order (Internal)Draft and non-final orders are invisible to the query
A sales agent on the order headerSales Order headerThe salesman filter is mandatory and the grouping key includes it; orders with no sales agent can never be matched
At least one company, one branch, one customer and one sales agent selected on the runThis appletAll four are hard-required — see below

Applet settings

This applet has no working configuration. All three settings screens are non-functional, and nothing in the applet changes its behaviour based on a setting.

ScreenState
Settings → Field SettingsThe toggles shown (Unit Discount, SST/VAT/GST, WHT, Blanket Order, Department Settings…) are copied from a sales-document settings screen, describe nothing in this applet, and SAVE does nothing
Settings → Default SelectionDisplays, but what you enter is never saved
Personalization → Default SelectionThe same result

The reason is mechanical, not a permission: the Field Settings screen is a stub with no form behind its toggles, and both Default Selection screens declare a save output that nothing emits and nothing binds. The Personalization menu also lists a Field Settings entry with no route behind it, so that click opens nothing.

Two batch behaviours that would normally be settings are instead fixed by the platform when it queues the job, not anywhere a user can reach: the page size in which a run reads sales-order lines, and whether a job processes one named event or run or sweeps every unprocessed one. Everything you start from this applet processes the one event or run you saved.

Feature visibility / permissions

This applet has no feature-visibility codes of its own.

The Permission Set screen carries a full six-verb set (_OWNER, _ADMIN, _CREATE, _UPDATE, _DELETE, _READ) for each of Consolidation Template Hdr, Consolidation Event Hdr, Consolidation Run Hdr and Consolidation Run Line, all prefixed TNT_DM_ERP_SALES_ORDER_TO_SALES_INVOICE_CONSOLIDATION_….

GENERATE SI is governed by the run line create permission.

Fields

Run — Create

FieldMeaningRequiredNotes
Run NameThe batch’s nameYesShown in the run listing and not on the invoices, so name it for the month or channel it covers, not “run 1”
SO Consolidation TemplateCopies a saved template’s four filter lists into the runNo, but see TemplatesThe only way this form fills the four lists
Companies / Branches / Customers / Sales AgentsThe four filter setsYes, in effectNot on this form: they come from the template, or from the run’s tabs after it is saved. Each is checked only when the run executes, and an empty one fails the run
Current Run Start Date / End DateThe start date decides when the run is processed, not which orders it takes. The second date is stored and nothing that processes the run reads itNo, but treat the start date as requiredIt opens at the date the previous run closed on, so check it. Today or earlier: the run is processed as you press Create. Later than today: it is never processed (see Templates). Empty: the create path reads it at once, so the run either fails to save or is never picked up (read in the code, not run)
Previous Run · Name · Start Date · End DateThe preceding run, for continuityRead-onlyFilled from the most recently created run; its end date becomes this run’s start date
DescriptionFree textNoLeft blank, the template’s description is copied in when the run is saved
StatusACTIVE by default—Not read by the run job. An INACTIVE run is still processed; only deleting it stops it

Event — Create

FieldMeaningRequiredNotes
Cycle Start Date / Cycle End DateAn event dated today or earlier becomes a run when you save it. An event dated later may never become a run (see below). Both dates are copied onto the run, and neither chooses which orders are billedYes, though the form does not mark themThe server refuses an event missing either date. On a repeating event each occurrence gets its own start date, and the second date you typed is replaced by the close of that occurrence’s calendar period (for daily and weekly rules, of its first day)
Is Recurring / RRULERepetitionNoAn iCalendar RRULE string, the same recurrence model Stock Replenishment uses — editing or deleting a recurring event asks whether the change applies to this occurrence, this and future ones, or all. Occurrences are created up front as separate events; an unending rule stops after about a hundred. A rule that repeats every period (interval 1) with no finish date and no count creates only the first event, so give the rule a finish date or a number of occurrences, then open the Events listing and count them. Only the occurrences already due when you save become runs; the later ones share the caution below
SO Consolidation TemplateCopies a saved template’s four filter lists into the eventNoThe only way this form fills the four lists
Companies / Branches / Customers / Sales AgentsThe four filter setsYes, in effectCopied from the event’s own lists onto every run the event creates
Description, StatusNoThe description is copied onto every run the event makes. Status is not read by the event job: an INACTIVE event still turns into a run on its date; only deleting it stops it

An event dated in the future may never become a run. When you save an event, the platform checks it once, there and then. An event not yet due is skipped, and as far as the source shows nothing checks it again when its date arrives: no Scheduler entry can start the event job, and the platform’s per-tenant processing pass does not look at this applet’s queue. That holds for a one-off event dated later and for every future occurrence of a repeating one. This was read in the code and has not been tested on a tenant. After each event date, open the Event listing and check that a run appeared. If none did, create the run by hand.

Lifecycle and effects

Posting proof

Server document typeNone of its own. Templates, events, runs and run lines are not financial documents
Amount signum / quantity signumNot applicable. The document it creates is an ordinary Sales Invoice and carries that document type’s signums
What it createsOne internal sales invoice per company, branch, customer and sales agent, at posting status DRAFT
Dr/Cr equationNone here. The draft posts nothing; when it is finalised in Sales Invoice (Internal) it posts exactly as any internal sales invoice does
GL precedenceNot applicable here; inherited from the sales invoice
Stock processorNone here; inherited from the sales invoice
What VOID reversesThere is no void on a run. Reversing means voiding or deleting the consolidated sales invoice in its own applet
What it does writeRun lines, one per eligible sales-order line; one draft sales invoice per group; document links tying the orders to the invoice; and a permanent removal of the orders from the sales-order-to-sales-invoice open queue

The pipeline

    flowchart TD
    T["Template<br/>saved filter set"] -.seeds.-> E
    E["Event<br/>date + optional RRULE + filters"] -->|event job<br/>event date &lt;= today| R["Run header<br/>filters copied from the event"]
    RC["Run created directly<br/>in the applet"] --> R
    R -->|run job| RL["Run lines<br/>one per eligible FINAL sales-order line"]
    RL -->|GENERATE SI<br/>run-line job| G["Group by company + branch<br/>+ customer + sales agent"]
    G --> SI["One draft Sales Invoice per group<br/>posts when finalised"]
    SI --> L["Document links<br/>sales order to sales invoice"]
    SI --> Q["Open-queue rows for SO to SI<br/>permanently deleted"]
  

Three background jobs drive the chain, and each is started by something you do on this applet’s screens, not by a clock. The Scheduler cannot start them.

Event → Run. Saving an event starts the event job for that event. If the event is due (dated today or earlier) and has not yet produced a run, the job creates a run from it — copying the four filter sets, the dates, the name and the template link — records the run on the event, and starts the run job at once. An event that already has a run is never processed again. An event not yet due is skipped, and see the caution under Event — Create about when it is looked at again.

Run → Run lines. The run job processes a run only once. It requires all four filter sets to be non-empty and fails the run with a specific message if any is missing. It then works through each company and branch, counting eligible sales-order lines — a Sales Order (Internal) whose posting status is FINAL, whose customer is in the customer set and whose sales agent is in the salesman set — and compares that with the run lines that already exist for the pair in any run. What it does next is in Templates, and what a run actually picks up.

Run lines → Invoice. Pressing GENERATE SI on the Sales Orders tab queues the run-line job and returns at once: the “The sales invoices were successfully created” message means the work was queued, not done. The job skips any ticked line that already has an invoice or carries any status. It takes the distinct (company, branch, customer, sales agent) combinations among the rest and, for each, reads back exactly the selected order lines and builds one Sales Invoice from them, created exactly as a hand-keyed internal sales invoice is and then immediately updated so the running number and derived fields are populated. It is created as a draft. It is dated the moment the job runs, its billing and delivery address and customer details come from the last sales order in the group, and its description reads “Consolidated from Sales Order id: …”, naming that last order only. Only item lines are carried. The run lines are then stamped with the invoice link and a shared group reference, and the orders are permanently removed from the sales-order-to-sales-invoice open queue so they no longer offer themselves for conversion. A failure is written to the run line, not shown to you; reload the Sales Invoices tab to see what was made.

Run-line status values

The status on a run line is free text, not a fixed list — and no tab in this applet shows it. The Sales Orders tab fetches the run lines but puts only branch, customer, sales agent, item and quantity in columns; the Status on the run listing is the record’s ACTIVE/INACTIVE flag, and the Status on the Sales Invoices tab is the invoice’s own posting status. The processing result lives in two fields on the line — a processing status and a processing error (the exception message, or the stack trace) — and the way to read them is the run-lines query the Sales Orders tab itself calls, filtered by the run’s guid (the field names and the path are in this page’s sources), or to ask BigLedger support to read them for you. The values written are:

ValueMeaning
POSTEDThe whole chain succeeded and at least one open-queue entry was found and removed
FAILED_TO_CREATE_CONSOLIDATED_SALES_INVOICEThe consolidated invoice was rejected on creation; the message column carries the reason
FAILED_TO_UPDATE_CONSOLIDATED_SALES_INVOICEThe invoice was created but the follow-up update failed
FAILED_TO_UPDATE_SALES_INVOICE_DATA_IN_RUN_LINEThe invoice is correct; writing its link back onto the run lines failed
FAILED_TO_DELETE_GENDOC_LINE_OPEN_QUEUEEverything succeeded except clearing the open queue
(unchanged)No open-queue entries were found. POSTED is written only when there were open-queue entries to remove, so a successful consolidation of orders that had none leaves the run line’s status untouched

Templates, and what a run actually picks up

A template is a name, a description, a status and four lists: companies, branches, customers and sales agents. You fill the lists on the template’s own filter tabs after you save it. Pick the template on the Run or Event Create form and its four lists are copied into the new run or event. That is the only way the Create form fills them. It has no picker of its own for companies, branches, customers or sales agents.

What happens behind the screen.

  • The copy is taken once, when you pick the template. Editing the template afterwards changes no run or event already made. That includes a repeating event. The event copies its own four lists onto every run it makes, not the template’s. A customer you add to the template next month is not billed by an event you created last month.
  • The run remembers which template it came from, and nothing uses that. The run job chooses orders from the run’s own four lists. The template view has no list of the runs made from it.
  • The run’s dates do not choose orders. The run takes every sales-order line at posting status FINAL whose company, branch, customer and sales agent are in its lists, whatever the order’s date. The start date only decides when the run is processed.
  • Nothing new since the last run: the new run gets no lines for that company and branch. When the eligible lines are no more than the run lines already held for the pair, by any run, the new run makes none. Its Sales Orders tab stays empty for that pair; the earlier run keeps its lines.
  • New orders finalised since: the run takes every such line again, including lines an earlier run already invoiced. It first deletes every run line for that company and branch, from every run and for every customer. That includes an earlier run’s record of which invoice each line went to. It then lists every eligible line again under the new run, with no mark on those already invoiced. When you press GENERATE SI, the only check is the run line’s own invoice link, and a re-listed line has lost it, so it can be billed a second time.
  • The Qty column is not a quantity. It shows how many eligible lines the run found for that company and branch, the same number on every line of the pair.

Four cautions, each with the symptom you will see:

  • Pick the template on Create, or the run has nothing to work with. A run whose start date is today or earlier is processed the moment you press Create. Without a template its four lists are empty, so it makes no lines, and a run is never processed twice. Symptom: the Sales Orders tab stays empty.
  • Do not date a run in the future. A run with a later start date is queued and marked as handed over straight away. The run job only takes runs that were never marked, so as far as the code shows, that run never makes its lines. Symptom: the start date passes and the Sales Orders tab stays empty. Create the run on the day you want it to run. A future-dated event is no way round this (see Event — Create).
  • No screen shows whether a run was processed. The listing’s Status column is the record’s own status, ACTIVE or not. It is not the result of processing, and no screen shows the processing error. The Sales Orders tab is your evidence: empty means this run made no lines, either because it failed or because an earlier run already holds every eligible line for that company and branch.
  • Two runs over the same company and branch interfere. The second can delete the first’s lines, including the link to the invoice they produced. Finish and check one run before you create the next.

Your job. Whoever bills these customers keeps one template per billing group, for example one per branch and sales agent, and keeps it current. When a customer or sales agent joins or leaves the group, edit the template and re-create any event made from it. Before you press GENERATE SI, compare the Sales Orders tab with the invoices the last run produced. Tick only lines that are not on one yet, because nothing here stops a second invoice for a line a later run has re-listed. Afterwards, open the Sales Invoices tab and count one invoice per customer and sales agent you expected, then finalise each draft in Sales Invoice (Internal), checking its date and billing address. If the orders were already invoiced by hand, do not select them. The run does not know that. Do not create the next run for that company and branch until this cycle’s invoices are final.

Related applets

  • Sales Order (Internal) — the source documents, and where the sales agent that forms part of the grouping key is set.
  • Sales Invoice (Internal) — where the draft the run produces is finalised; everything about posting, tax and stock is decided there.
  • Job Sheet (Internal) — the sibling consolidation path in the same backend subsystem.
  • JS Consolidation — the job-sheet twin of this applet; its page lists where the two differ.
  • Scheduler — not used by this applet’s runs or events.

Troubleshooting

SymptomCauseFix
Support, or the API, reports a run as FAILED with “There is no Job Sheet under company: … branch: … customer: … salesman: …”, although its run lines and invoices existA known defect: the run never counts the lines it matched, so the “nothing found” check always fires. On a run created on the screen the result is then overwritten with a success, so the recorded result is wrong either wayCheck the Sales Orders and Sales Invoices tabs rather than any status. A fix in the platform is needed
A run that made no lines is never retriedThe run job processes a run once. Once any result has been recorded, that run is permanently skippedCreate a new run
“The sales invoices were successfully created” but the Sales Invoices tab is emptyThe message appears when the work is queued. Creation failed or has not finishedReload the tab. If it stays empty, the failure is in the run line’s processing status and error fields, which no tab shows — read them through the run-lines query or ask support; see Run-line status values
A new run’s Sales Orders tab is empty although orders are FINALAn earlier run already holds lines for every eligible order in that company and branchUse the earlier run, or finalise new orders first and accept that the earlier run’s lines move to the new one
An order already invoiced appears again, unmarkedA later run deleted and re-created the lines for that company and branchCheck against the invoices before ticking; see Templates, and what a run actually picks up
A future-dated event never produced a runAn event is checked when you save it; nothing checks it again on its dateAfter each event date, check the Event listing and create the run by hand
The invoice’s address or description names only one orderThe header is taken from the last sales order in the groupCorrect the draft before finalising it
The run fails immediately with “There is no company/branch/customer/salesman guid to process”One of the four filter sets is empty. All four are mandatory — there is no “all customers” optionPopulate all four tabs before running
A finalised sales order is never picked upThe run requires a Sales Order (Internal) at posting status FINAL, whose customer is in the customer set and whose sales agent is in the salesman set. An order with no sales agent matches nothingSet the sales agent on the order header, or widen the salesman filter
Orders from several customers end up on one invoice, or one customer’s orders are split across severalThe grouping key is the full tuple (company, branch, customer, sales agent) — not the customer alone. Two sales agents on the same customer’s orders produce two invoices; two branches produce two moreExpected. Narrow the run if you need one invoice per customer
Run lines read back (through the API) with a blank processing status after an apparently successful runPOSTED is written only when open-queue entries were found. Where the company has no knock-off flow configured for sales order → sales invoice, there are none, and the status is left as it wasCheck the Sales Invoices tab; see the company’s Knock Off Configuration
An earlier run’s lines have disappearedA later run over the same company and branch found new orders and deleted every run line for that pair, whichever run made themDo not create a second run for a company and branch until the first run’s invoices are final
The consolidated invoice exists but the sales orders still offer themselves for conversion elsewhereThe open queue is cleared in a separate step after the invoice is saved; if that step fails the run line records FAILED_TO_DELETE_GENDOC_LINE_OPEN_QUEUEConfirm it through the run-lines query (or ask support); the invoice itself is good, so warn whoever converts orders not to invoice those again until the queue rows are cleared; see Run-line status values
Settings screens do nothingNone of the three works; see Applet settings—

Related documentation

Last updated on