Skip to content

Opening balance

Books an opening balance in day book BEGINBALANS, period 0 of this year, then deletes it again. Without --save it only shows the request. With --save it changes data in Twinfield.

Twinfield documentation: Journal transactions.

Twinfield has several kinds of journal: memorial, wages, opening balance and year end. They are all journal transactions; the day book decides the kind. An opening balance can only be booked in period 0, a year end booking only in period 55. Give the period with period(Period::of($year, 0)): without it Twinfield derives the period from the date.

The day book codes differ per company: look them up in Twinfield, or with Finder TRS ($twinfield->finder(FinderType::TransactionTypes)).

The example uses the first two balance sheet accounts of the company.

$twinfield = Example::twinfield();
$journal = $twinfield->journalTransactions();
// In your own application: your opening balance day book and balance sheet accounts, e.g. the
// bank account and equity.
[$bank, $equity] = Example::generalLedgerAccounts($twinfield, 'BAS', 2);
$year = (int) date('Y');
// An opening balance goes in period 0 of the year. Twinfield refuses it in another period.
$input = JournalTransactionInput::create('BEGINBALANS', new DateTimeImmutable($year . '-01-01'))
->period(Period::of($year, 0))
->debit($bank, '2500.00', description: 'Opening balance')
->credit($equity, '2500.00', description: 'Opening balance');
if (!in_array('--save', $argv ?? [], true)) {
echo 'Dry run; add --save to create it as provisional transaction and delete it again:', PHP_EOL, PHP_EOL;
echo Example::xml($input->toXml((string) $twinfield->companyCode())), PHP_EOL;
exit(0);
}
try {
$transaction = $journal->create($input);
} catch (ProcessXmlException $exception) {
foreach ($exception->result->messages() as $message) {
echo $message->type->value, ' at ', $message->path, ': ', $message->text, PHP_EOL;
}
exit(1);
}
echo 'Created: ', $transaction->dayBook(), ' ', $transaction->number(), ', period ', $transaction->header->period,
PHP_EOL;
// Clean up: delete the provisional example transaction again.
$journal->delete($transaction->dayBook(), $transaction->number(), 'twinfield-php example');
echo 'Deleted: ', $transaction->dayBook(), ' ', $transaction->number(), PHP_EOL;
Terminal window
php examples/journal-transactions/opening-balance/example.php
Dry run; add --save to create it as provisional transaction and delete it again:
<transaction destiny="temporary">
<header>
<office>1002</office>
<code>BEGINBALANS</code>
<period>2026/00</period>
<date>20260101</date>
</header>
<lines>
<line type="detail" id="1">
<dim1>01000</dim1>
<debitcredit>debit</debitcredit>
<value>2500.00</value>
<description>Opening balance</description>
</line>
<line type="detail" id="2">
<dim1>01001</dim1>
<debitcredit>credit</debitcredit>
<value>2500.00</value>
<description>Opening balance</description>
</line>
</lines>
</transaction>

Add --save to send it. This creates a provisional transaction and deletes it again:

Terminal window
php examples/journal-transactions/opening-balance/example.php --save

What the SDK sends to Twinfield and what Twinfield sends back, for a call like the one in this example. The responses come from the tests, with example data.

Twinfield documentation: Journal transactions: Create.

$twinfield->journalTransactions()->create(
JournalTransactionInput::create('BEGINBALANS', new DateTimeImmutable('2026-01-01'))
->period(Period::of(2026, 0))
->debit('1010', '2500.00', description: 'Opening balance')
->credit('0500', '2500.00', description: 'Opening balance'),
);

The SDK sends this XML as xmlRequest of ProcessXmlString to processxml.asmx:

<transaction destiny="temporary">
<header>
<office>1000</office>
<code>BEGINBALANS</code>
<period>2026/00</period>
<date>20260101</date>
</header>
<lines>
<line type="detail" id="1">
<dim1>1010</dim1>
<debitcredit>debit</debitcredit>
<value>2500.00</value>
<description>Opening balance</description>
</line>
<line type="detail" id="2">
<dim1>0500</dim1>
<debitcredit>credit</debitcredit>
<value>2500.00</value>
<description>Opening balance</description>
</line>
</lines>
</transaction>

Twinfield answers with the saved transaction, with its number and the names of the codes, in the same format as Create journal transaction.

View examples/journal-transactions/opening-balance/example.php on GitHub.

Made by SolveBeam

Twinfield and Wolters Kluwer are trademarks of Wolters Kluwer. Their names and logos are used only to refer to their products.