Skip to content
Intercompany automation

Intercompany transactions automation that books the other side for you

Intercompany transactions automation in Ledgeriano works like this: when a qualifying entry is posted in one business, a workflow creates the matching entry in another business right away, in the background, with the right accounts, amounts and counterparty. No re-keying, no month-end hunt for missing invoices.

Intercompany transactions automation: a posted sale in one company creating the matching purchase in a sister company
The problem

The same transaction, typed twice, in two sets of books

In a group, every intercompany sale is also an intercompany purchase. When two people record the two sides by hand, the books drift apart.

  • Double work

    A wholesaler that invoices its own retail shop 150 times a month creates 150 extra entries for someone in the shop to type again.
  • Amounts that disagree

    A typo of 36,000 as 63,000 on one side stays hidden until the intercompany balances refuse to match.
  • Timing gaps

    The seller posts on the 30th, the buyer on the 3rd of next month, and the month-end balances no longer eliminate.
  • Painful consolidation

    Eliminating intercompany sales, receivables and payables only works when both sides were recorded the same way.
How it works

Trigger, conditions, actions

A workflow belongs to your account, watches one source business and can write to any business where you have permission to record entries.

  1. Step 1

    Trigger

    Choose the event in the source business: an entry is created, posted or reversed. Most intercompany flows use the posted event, so only approved entries travel.

  2. Step 2

    Conditions

    Filter by voucher type, entry kind, total, description, reference, tag, source, currency, account (has, debit or credit on a code prefix), party, or a free expression. Match all or any.

  3. Step 3

    Actions

    Run one or more actions in order: build an entry from a template, mirror the entry through an account map, or call a webhook URL. Each action reports its own result.

Three action types

Pick the action that matches the transaction

  • Create entry from a template

    You define the target lines: account code, side, and an amount expression such as credit("4101") or percent(total, 9). Descriptions and references accept tags like {{entry.number}}. Negative results flip to the other side automatically, and zero lines can be skipped.

    Best for intercompany sale to purchase, management fees and recharges.

  • Mirror the entry

    Copy every line of the source entry into the target, translating account codes through a map. Exact codes win, then the longest prefix wildcard such as 41*. Unmapped lines go to a default account, are skipped, or stop the action. Swap sides, apply a multiplier, keep parties or merge lines per account.

    Best for consolidation mirrors and branch reporting.

  • Call a webhook

    POST a JSON summary of the entry (number, date, lines, totals) to any URL, with the workflow id in the X-Ledgeriano-Workflow header. The run records the HTTP status so failures are visible.

    Best for notifying an ERP, a data warehouse or a chat channel.

Expression cheat sheet

Amount formulas and template tags

Amounts and custom conditions use a small, safe expression language. Account functions sum the source entry's lines whose code starts with the prefix you give, in the source business's base currency.

Amount formulas and template tags
ExpressionWhat it returnsIn the worked example
totalTotal debits of the source entry (equal to total credits)60,000.00
debit("41")Sum of debit amounts on accounts starting with 410.00
credit("4101")Sum of credit amounts on accounts starting with 410136,000.00
net("11")Debits minus credits on accounts starting with 1112,000.00
round(x, 2)x rounded to 2 decimals (any precision you pass)round(total / 3, 2) = 20,000.00
percent(total, 9)9% of the value, rounded to 2 decimals5,400.00
abs(x), min(a, b), max(a, b)Absolute value, smaller and larger of valuesmin(total, 50000) = 50,000.00
entry.currency_code == "USD"A condition on entry fields, combined with and / ortrue

Template tags for descriptions and references

  • {{entry.number}}Source entry number
  • {{entry.reference}}Source reference, such as the invoice number
  • {{entry.description}}Source description
  • {{entry.date}}Source entry date (YYYY-MM-DD)
  • {{entry.voucher_type}}Voucher type code, such as SAL
  • {{source.business}}Name of the source business
Worked example

B2B wholesaler to B2C retailer, both sides in one step

Alpha Wholesale LLC sells stock to its sister company Beta Retail Store, which sells to consumers. Both use the IFRS chart template. In Alpha, Beta is customer C001; in Beta, Alpha is supplier S001.

1. Alpha posts sales invoice INV-1001

Alpha Wholesale LLC (B2B)

Entry 42 · Sales

SALINV-10012026-03-05Posted
CodeAccountPartyDebitCredit
1111Trade receivablesC001 Beta Retail36,000.00
4101Sales of goods36,000.00
5101Cost of goods sold24,000.00
1124Merchandise inventory24,000.00
Total60,000.0060,000.00

2. The workflow posts the purchase in Beta

Beta Retail Store (B2C)

Entry 17 · Purchases

PURALPHA-422026-03-05Created by workflow
CodeAccountPartyDebitCredit
1124Merchandise inventory36,000.00
2111Trade payablesS001 Alpha Wholesale36,000.00
Total36,000.0036,000.00

The workflow triggers on entry posted, requires voucher type SAL and party C001, and uses credit("4101") for both target lines. That picks up the 36,000.00 of revenue and ignores the 24,000.00 cost of sales, which is Alpha's internal cost and means nothing to Beta. Using total here would have been wrong: it is 60,000.00.

Beta's entry carries the reference ALPHA-42 and metadata that points back to Alpha's entry, so either accountant can trace one side to the other. At consolidation, Alpha's 36,000.00 revenue and Beta's 36,000.00 inventory purchase eliminate cleanly, along with the matching receivable and payable.

workflow configuration (simplified)
{
  "trigger": "entry.posted",
  "source_business": "Alpha Wholesale LLC",
  "conditions": [
    { "field": "voucher_type", "operator": "eq",  "value": "SAL" },
    { "field": "party",        "operator": "has", "value": "C001" }
  ],
  "actions": [{
    "type": "create_entry",
    "target_business": "Beta Retail Store",
    "voucher_type": "PUR",
    "status": "posted",
    "reference": "ALPHA-{{entry.number}}",
    "description": "Purchase from {{source.business}}, invoice {{entry.reference}}",
    "lines": [
      { "account_code": "1124", "side": "debit",  "amount": "credit(\"4101\")" },
      { "account_code": "2111", "side": "credit", "amount": "credit(\"4101\")", "party_code": "S001" }
    ]
  }]
}

Mirror action with prefix wildcards

For a consolidation business, a mirror action copies each posted entry and maps codes: 4101 goes to 4190, anything else starting with 41 goes to 4100, all assets starting with 1 go to 1999, and the rest falls back to 9999.

mirror_entry
{
  "type": "mirror_entry",
  "target_business": "Group Consolidation",
  "account_map": [
    { "from": "4101", "to": "4190" },
    { "from": "41*",  "to": "4100" },
    { "from": "1*",   "to": "1999" }
  ],
  "default_account": "9999",
  "swap_sides": false,
  "merge_lines": true
}
Built-in safety

Automation that cannot run away with your books

  • Loop protection

    Entries created by a workflow do not trigger other workflows unless you allow chaining, and a workflow never fires on its own output.
  • Maximum depth of 3

    Even with chaining on, a chain of workflow-created entries stops at depth 3 and the run is recorded as skipped.
  • Dry-run test

    Pick any existing entry and see which conditions pass and the exact entries each action would create, without writing anything.
  • Run history

    Every run is logged with status (success, partial, failed or skipped), duration, the entries it created and any error message.
  • Permissions at run time

    At every run Ledgeriano checks that you can still view the source and create entries in the target. Without posting rights, entries arrive as drafts.
  • No duplicates

    Each action writes with an idempotency key built from the workflow, action, entry and event, so a retry never books the same entry twice.
Cost

What a workflow run costs

Workflows use the same credits as the rest of Ledgeriano. At the default prices a run costs 2 credits (workflow.run), plus the normal cost of each entry it creates (3 credits for entry.create). The sale and purchase in the example above cost 5 credits for the automated side. Entries that do not match the conditions cost nothing. Administrators can change prices, so the pricing page always shows the current ones.

Workflow run
2 credits
Entry created in the target
3 credits
Conditions not met
0 credits
Use cases

Where groups use workflows

  • Intercompany sale and purchase

    Seller's revenue becomes the buyer's inventory or expense, with the payable to the right sister company.
  • Management fees and recharges

    When the holding company posts a management fee, the subsidiary records the expense and payable. Use percent(total, 5) for a fee charged as a share.
  • Consolidation mirror

    Mirror every posted entry into a consolidation business with a compact account map and merged lines.
  • Notify your ERP

    Send a webhook when an entry tagged invoice is posted, so your ERP or warehouse updates without polling.
Step by step

How to set up an intercompany workflow

  1. 1

    Prepare both businesses

    Make sure you can record entries in both companies, and create each company as a party in the other: Beta as customer C001 in Alpha, Alpha as supplier S001 in Beta.

  2. 2

    Create the workflow

    Choose the source business (Alpha) and the trigger. Use entry posted so only approved entries are copied.

  3. 3

    Add conditions

    Require voucher type SAL and party C001, so sales to outside customers are left alone.

  4. 4

    Add the action

    Pick Create entry, choose Beta as the target and add the lines: debit 1124 and credit 2111 with party S001, both with the amount credit("4101").

  5. 5

    Test on a real entry

    Run the dry-run test on an existing sale and check the conditions and the entry it would create. Nothing is written.

  6. 6

    Activate and monitor

    Switch the workflow on and review the run history after the first few sales.

FAQ

Intercompany workflow questions

What is intercompany transactions automation?

It is recording the second side of a transaction between two related companies automatically. In Ledgeriano, a posted entry in one business triggers a workflow that creates the matching entry in the other business.

Do both companies need the same chart of accounts?

No. Template actions name the target accounts directly, and mirror actions translate codes through an account map with exact codes and prefix wildcards such as 41*.

What happens if the source entry is reversed?

Reversal is its own trigger. Add a workflow on entry reversed to create the counter entry in the target, or reverse the target entry by hand. Nothing changes silently.

Can a workflow post entries in a company where I am only a bookkeeper?

It can create them, but a role without posting rights means the entry arrives as a draft for someone with the right permission to review and post.

Can two workflows trigger each other forever?

No. Workflow-created entries only trigger other workflows when chaining is allowed, a workflow never fires on its own output, and chains stop at depth 3.

Can I automate intercompany entries through the API instead?

Yes. You can post both sides yourself with the accounting API and idempotency keys. Workflows save you from writing that code.

Stop typing the same invoice twice

Create two businesses, connect them with a workflow and post a test sale. New accounts get free credits, and pricing is pay as you go.