Skip to content
Automation

Automation

BigLedger has no workflow engine, and this page is the honest answer to what it has instead: four separate mechanisms, none of which is a visual designer or a rule language, and each of which is worth knowing about before you build an integration around any of them.

There is no business rule engine, no workflow designer and no automation builder. Nothing in BigLedger lets you write a condition over a document and attach an action to it. The one package in the platform called a rule engine belongs to the contact centre and does exactly one thing: route an incoming task to a team or an agent. It has two rule types and twelve actions, all of them assignment, queueing, or handing the item to an OCR processor. It cannot see an invoice.

The Workflow Design applet is a catalogue of statuses and transitions — a status track a document applet can display — not an engine. It runs nothing.

If you need “when X happens, do Y”, Y runs in your system, triggered by a webhook and carried out through the API. The rest of this page is what BigLedger contributes to that.

The four mechanisms

You want to…UseWhere it runs
React to a change in a tenantWebhooksyour endpoint
Run something on a scheduleThe Scheduler — the tenant’s cron tableBigLedger
Run one of BigLedger’s own background jobsA job processor, put on the SchedulerBigLedger
Gate a purchase document on sign-offThe document approval engineBigLedger

Everything else — branching, retries, escalation, orchestration across steps — is yours to build.

React to a change: webhooks

Register a subscription (a URL, a topic, one optional header) and BigLedger POSTs the changed record to you. Webhooks documents the whole mechanism, including four absences that change how you must build:

  • no signature — the payload is not signed; the only credential is a static header you chose;
  • no retry — one attempt, ever, with no dead-letter queue and no replay;
  • no alerting — the notification fields on a subscription are loaded and never looked at again; no mail or SMS sender exists in the delivery path;
  • no readable delivery log — attempts are recorded, but the endpoint that lists them always returns an empty list, whatever was delivered.

The consequence is the single most important design rule on this page: treat a webhook as a hint that something changed, never as a delivery guarantee. Re-read the record through the Data API before you act on it, and pair every subscription with a periodic updated_date_from reconciliation pull. The webhook makes your integration fast; the pull is what makes it correct.

Run something on a schedule: the tenant cron table

Each tenant has a cron table. A row pairs the queue code of a background job processor with a UNIX cron expression and an optional JSON payload of properties for that job. On each platform tick, BigLedger reads the tenant’s active rows, works out which are due, and puts the matching job on the tenant queue.

The Scheduler applet is the screen for this and documents the behaviour in full. Over the API:

PurposeEndpoint
List schedulesGET /core2/tnt/dm/sch/crontabs
Filter schedulesGET /core2/tnt/dm/sch/crontabs/query
Read oneGET /core2/tnt/dm/sch/crontabs/{guid}
CreatePOST /core2/tnt/dm/sch/crontabs
UpdatePUT /core2/tnt/dm/sch/crontabs
DeleteDELETE /core2/tnt/dm/sch/crontabs/{guid}
Run one nowPOST /core2/tnt/dm/sch/crontabs/scheduler/execute/backoffice-ep/{guid}

These need API_TNT_DM_SCH_CRONTAB_READ, _CREATE, _UPDATE or _DELETE, or the broader _OWNER / _ADMIN grants. There is no documented etl-ep path for any of them, so a scheduled job is set up by a signed-in user rather than as part of a server-to-server integration.

A schedule row carries:

FieldNotes
codeThe job processor’s queue code. Stored upper-cased and trimmed.
nameA label.
cron_expressionParsed with the UNIX five-field definition. A six- or seven-field Quartz expression will not behave as written.
event_propertiesA JSON object handed to the job as its properties.
statusOnly ACTIVE rows are read.
execution_strategyINSERT_TO_QUEUE or RUN_NOW; the backend fills in INSERT_TO_QUEUE when it is absent.
last_run_timeMaintained by the platform. Defaults to the moment the row was created.
Three ways a schedule silently does nothing. A code that does not resolve to a job processor the platform knows is filtered out before the cron check — no error, no event, no change to the last-run time. A row that is not ACTIVE is never read. And because the next occurrence is computed forward from last_run_time, which starts at the moment of creation, a daily job created this afternoon does not back-fill this morning’s run.

What you can schedule: job processors

Everything BigLedger does in the background is a job processor — a named unit of work with a queue code, a description and a properties class. There are 597 of them registered in the platform. A processor has to be registered and enabled for your tenant before it can be selected; that is a platform-side step, visible in the Developer SysAdmin applet.

A few that show what the mechanism is for:

Queue codeWhat it does
RECURRING_GENERIC_DOCUMENT_PROCESSORCreates the next generic document when a recurring period comes round
STOCK_REPLENISHMENT_RUN_PROCESSORRuns every stock replenishment configuration against the current date and time
STOCK_LEVEL_MONITORING_RUN_PROCESSORChecks stock levels for a configured scope and records breaches
E_INVOICE_BATCH_PROCESSING_CYCLE_RUN_PROCESSORBuilds the to-IRB submission rows from the batch pool
BI_REPORT_QUERY_RUN_PROCESSORExecutes the one report query run or query event it is handed

That last one is not a report scheduler, and scheduling it does nothing. Reports are defined in the BI report surface (/core2/tnt/dm/bi-reports/…, backoffice-ep throughout; there is no documented etl-ep path into it). The processor acts only when the request that queues it names a specific query run or query event, which is what the Dynamic Report screens do when you create one. A cron row with that code, as the Scheduler creates it, names neither, so each time the clock fires it queues a job that finishes without doing anything.

Scheduled reporting does not work today. A Query Event’s future occurrences are stored in a waiting list that nothing reads, so a recurring event produces the runs that were already due when you saved it, and then nothing more. BigLedger intends scheduled reports to work. Until they do, run the schedule in your own system and pull the figures through the Data API on your own clock. See Dynamic Report › Scheduled runs. There is no “generate report of type X” API endpoint.

A registered processor is not a promise that it does something. At least one processor in the list is a stub whose processEvent returns immediately while its description claims real work (recorded as a product defect). A processor you have not seen produce an effect on a test tenant is a processor you should test before you schedule.

Chained jobs, and why you cannot define one

BigLedger can run a second job when a first one finishes: a platform-level applet trigger template links a publisher job processor to a subscriber job processor, and a tenant enables that link by holding a matching trigger-configuration row. The e-invoice pipeline is built this way.

The half that decides which job follows which lives in the platform registry, not in the tenant. A tenant can enable or disable a link that already exists; it cannot create one, and neither can you. If you need work chained, chain it in your own system.

The largest chain in the product starts when somebody finalises a document

Finalising a generic document — a sales invoice, a cash bill, a purchase order, a credit note — is not a save. It is its own endpoint, PUT /core2/tnt/dm/erp/gen-doc/{docType}/update-posting-status/{guid} with posting_status: FINAL in the body, and the last thing it does before returning is put one row on the tenant queue for the Generic Document Primary Processor. That processor exists to fan out: it reads the subscriber links for its own queue code and queues one job for each.

Dozens of processors subscribe to it in the platform registry — the journal posting, the inventory transaction line, the cashbook line, two e-invoice matching queues, the membership point update, four coupon processors, finance charges, budget register lines, historical aging for a back-dated document, intercompany, the open-queue (knock-off) processor, bundle and make-to-order unwrapping, sales commission, non-stock trade-in, and several integration-specific ones. None of that is on the screen, and the count is a property of the platform rather than of your tenant.

Three filters decide which of them actually run for one document, in this order:

  1. Your tenant’s subscription. Only links whose applet trigger template has an ACTIVE bl_applet_trigger_config_hdr row in your database are returned at all. This is the switch that matters: the same button in two different databases does different amounts of work, because the subscription list behind it differs. The stock chain is one template covering all three of its levels, so it is on or off as a unit.
  2. Your company’s override list. bl_fi_mst_comp.posting_final_json may carry includeJobProcessorCode and excludeJobProcessorCode arrays; an excluded code is skipped, and if the include list is non-empty everything not on it is skipped. It is an override on top of the subscription, not the thing that enables anything, and it stays unset until somebody sets it — so unless your company has one, the subscription is the whole answer.
  3. The document type on the link. A link may carry serverDocTypes and clientDocTypes constraints; the job is queued only if this document matches. Most links carry none and therefore match every document type.

The chain is deeper than one hop

A subscriber may itself be a publisher. Stock is three levels below the button:

Finalise  →  BLG_ERP_GENERIC_DOCUMENT_PRIMARY_PROCESSOR
          →  INVENTORY_TRANSACTION_LINE_PROCESSOR                     (writes the stock ledger line)
          →  INVENTORY_TXN_LINE_TO_CURRENT_STOCK_BALANCE_PROCESSOR    (balances, moving average, write-back)
          →  INVENTORY_FIFO_LIFO_COSTING_PROCESSOR                    (FIFO baskets, FIFO write-back)

Each level re-runs the same lookup for its own queue code, so the depth is data, not code.

What the queue does with a job that fails

The queue row is deleted before the handler runs — DELETE … RETURNING is how a worker claims it. So a handler that throws does not leave a row to retry: the failure is written to app_scheduler_std_error with the event code, the properties (which carry the document GUID) and the message, and nothing re-drives it.

The safety net covers the other failure: a row that was inserted and never attempted. The Main Tenant Processor’s tick reads up to ten distinct event codes from app_scheduler_queue and calls the job endpoint once for each, and that endpoint pulls a single event per call. That is what makes asynchronous posting safe against a restart — and it is also why a tenant producing work faster than one job per code per tick accumulates a visible backlog in that table.

A subscriber whose queue code is not an enum constant breaks the whole fan-out. The fan-out resolves each subscriber with JobProcessorClassName.valueOf(code) and does not guard it, while the scheduler path guards the identical call with a Try and skips the row. One subscriber link in the platform registry today names a queue code that no enum constant matches, so on a tenant that enables that template the exception aborts the loop and every subscriber after it in the list — journal, stock, e-invoice — is never queued, silently. Recorded as a product finding; if you are enabling trigger templates, enable them one at a time and check app_scheduler_std_error afterwards.

Approvals

There is no approval API to build custom chains on. BigLedger’s approval engine is a fixed, optional feature of three applets — Purchase Requisition, Purchase Order and Stock Requisition — and it is configured through their Settings → Approval Settings screens, not through code. It has no public rule engine, no SLA or timeout, no escalation, no delegation and no approval portal API. If you need approvals on any other document, the control is permissions, not a workflow you can register.

What the engine does expose over the API is the approval record for a document, so an integration can read where a purchase order stands and react to it:

PurposeEndpoint
Read approval headers for a documentGET /core2/tnt/dm/erp/generic-doc/approvals/backoffice-ep/query?generic_doc_hdr_guids=…
Read an approver’s outstanding requestsGET /core2/tnt/dm/erp/generic-doc/approvals/approval-requests/login-entity-ep
Record an approve or reject decisionPUT /core2/tnt/dm/erp/generic-doc/approvals/approval-requests/processors/login-entity-primary-ep
Read the approval historyGET /core2/tnt/dm/erp/generic-doc/approvals/approval-histories/backoffice-ep/query
Submit or resubmit a document for approvalPOST / PUT /core2/tnt/dm/erp/generic-doc/approvals/processors/submission/backoffice-ep
Withdraw a pending approvalPUT /core2/tnt/dm/erp/generic-doc/approvals/processors/withdrawals/backoffice-ep

The behaviour behind them — levels, quorum, the Min Approval Amount rule, the two notification e-mails, and the move to FINAL on the first approval — is described in Document Approvals. Anything beyond that (reminders, escalation, routing by supplier or category, a mobile approval app) has to be built in your own system.

The pattern that works

Automation that holds up on this platform looks the same every time:

  1. Subscribe to the topics you care about, one URL per subscription.
  2. Re-read the record through the Data API when a webhook arrives. Do not trust the body.
  3. Decide and act in your own system. Your conditions, your retries, your audit trail.
  4. Write back through the etl-ep endpoints in the API Reference.
  5. Reconcile on a schedule with an updated_date_from pull, because step 1 drops events silently.
  6. Schedule BigLedger’s own jobs for the work that has to happen inside BigLedger — recurring documents, replenishment runs, e-invoice sweeps. Not report runs: those do not run on a schedule today (see above).

Start at Integration: Getting Started, which takes you from no credential to moving real data.

What is not there

Stated plainly, because it changes what is worth designing:

Not availableWhat to do instead
A workflow engine or visual designerOrchestrate in your own system
A business rule engine over documentsEvaluate conditions in your own system
Webhook signatures, retries, replay or a readable delivery logRe-read every record; reconcile on a schedule
An API to create a job processorJob processors are platform code; only scheduling is tenant-side
An API to chain one job to anotherChain in your own system
An approval API for documents other than the three named aboveUse permissions
A “generate report” endpoint, or scheduled reportsPull the figures through the Data API on your own schedule. Scheduling BI_REPORT_QUERY_RUN_PROCESSOR does nothing, and a Query Event’s future occurrences never run today
A BigLedger client SDK for JavaScript, Python, PHP, Java, .NET or GoCall the REST API directly. The published Angular libraries are for applet development, not for server-side integration

Related documentation

Last updated on