Blog— Anton Ignashev

Optima's multi-company module: the accounting office already has a status layer and does not read it

Optima's multi-company module: the accounting office already has a status layer and does not read it

The Module Nobody Treats as Data

Seventh guide in this series on integrating Polish ERP systems. Second one in a row where the interesting part is something the vendor already shipped.

Yesterday's piece on Rewizor nexo made a simple argument: the posting automation clients come to a developer for is already in the box, switched off. The Optima module for accounting offices — renamed from Biuro Rachunkowe to Operacje wielofirmowe, which is why half the internet calls it one thing and the software calls it another — is a different case, and a stranger one.

Here the feature is not switched off. Offices live in this module. They open it every morning, switch between client databases without logging in again, run declarations in batches, send from several mailboxes. It gets used, hard, every working day of the month.

What nobody uses is the data it produces while being used. And that data happens to be the exact thing every integrator building for an accounting office spends their first two weeks trying to construct from scratch.

Eleven Attribute Groups Are a Status Table

Configuration sits under Start → Konfiguracja → Operacje wielofirmowe, with branches for Atrybuty, Grupy atrybutów, Kategorie czasu pracy and Parametry. There is a company-level branch too, and a per-station one. That second one matters, and I will come back to why.

The module ships eleven predefined attribute groups. Dane firmy alone holds sixteen attributes of contact and identification data. Then: Deklaracje VAT, Deklaracje CIT, Deklaracje PIT, Deklaracje Intrastat, Deklaracja ZUS DRA, JPK, Ogólne (acronyms, closure status, document counts), Operator (who the opiekun is), Parametry firm (tax, contribution and depreciation rates) and Urzędy (which tax office).

Now look at what one declaration group holds, per company, per month. A status, moving through brak → w buforze → zatwierdzona → wysłano → odebrano UPO. An amount to pay or refund. A calculation date. A count of computed positions.

Read that as a schema instead of a screen. It is a status table keyed by client and month, maintained across every database the office serves, computed by the ERP rather than by you. You did not build it. You do not maintain it. It is already populated.

The hard part of building anything for an accounting office is exactly this join. I wrote about the version of the problem you hit head-on in the post on Optima's performance ceilings: the module gives the office one panel to switch between forty client databases, but underneath sit forty logins, forty sets of categories, forty schemas drifting apart. For document-level work that is unavoidable. For the question that actually runs an office's month — who is not ready — somebody already did the aggregation.

Why Integrators Walk Past It

The reflex is understandable. You are handed an integration brief, you ask what the API is, and the answer is one of the five things people call an Optima API — which I sorted out in the Optima API guide because the ambiguity eats the first meeting of every project. CDN.API or direct SQL, per client database, forty times.

For invoice lines and postings, that answer is right. For status, it means you are about to rebuild something that already exists and is already filled in.

Two honest caveats before anybody plans around this.

It is a licensed module, sold per station, and configured partly at the station level. Its presence is not a given at every office, and the answer to "do you have it" is commercial before it is technical.

And the attributes are computed on entry and refresh, not pushed at you. This is a nightly read against a table, not an event stream. If your design needs to know within a minute that a declaration state changed, this is not the mechanism. Stop designing it that way now, rather than in week six.

"Brak" Is the Word That Breaks the Dashboard

Here is where the obvious build goes wrong. It goes wrong the same way every time, and I can now predict the timeline.

Count the clients whose VAT status for this month is brak, paint them red, put it on a screen. An afternoon of work, and the first thing anyone proposes. Within two weeks nobody looks at the screen.

The reason is that brak means one thing mechanically and four things in practice. No declaration of that type was calculated. That is all it asserts. It does not distinguish:

  • not done yet,
  • not applicable because the client files a different form,
  • not applicable because there was no activity that month,
  • not applicable because the client was deregistered and nobody removed the database.

So your red list is a mix of real gaps and permanent non-gaps. By the third morning of scrolling past the same eleven clients who are never going to file VAT, the list has finished teaching the office to ignore it.

Same shape as the false-overdue rate from the receivables post — technically correct, operationally useless, and dangerous precisely because it looks finished.

The artifact worth building is the applicability map: for each client, which declarations should exist in which months. VAT monthly or quarterly. PIT advances or not. ZUS DRA at all. JPK obligations. Intrastat above thresholds.

Nobody has one. It lives in the head of whoever has been at the office longest, and it gets reconstructed from memory on the 18th of every month. Writing it down takes an afternoon with that person, and that afternoon is the real deliverable — the same conclusion as the receivables piece, restated for the close: the filter is the thing worth automating, not the sending.

On a forty-client portfolio, expect the raw brak count to sit near forty in the first week of a month and somewhere around ten to fifteen by the 20th, of which a meaningful share — often a third — is legitimately not applicable. Until you can subtract that share, you do not have a readiness report. You have a scroll.

One Value Is Evidence. The Rest Are Intentions

Look at the status sequence again and ask, for each value, who put it there.

brak, w buforze, zatwierdzona, wysłano — your own installation, recording its own actions and intentions. odebrano UPO — a confirmation that came back from a system outside the office.

Exactly one of those five is evidence. The other four are notes to self.

That distinction is not academic. The failure it hides is the most expensive one an accounting office can have: a submission that went out and never came back confirmed looks, on every internal screen, identical to one that landed. An office tracking wysłano believes forty clients are filed. It may have thirty-eight.

So: the UPO gap. Count the client-months where wysłano is set and odebrano UPO is not. It should converge to zero within a few days of each deadline. It does not. There is almost always a small standing residue, and each item in it is either a filing that did not land or a confirmation nobody collected — and you cannot tell which without looking. That is the whole point of looking.

It costs one column of a report against data the office already owns. It needs no applicability map. And unlike the brak dashboard, it has no noise floor at all: every row is a real question. If you build one thing from this module, build this.

Serial Conversion Is the Integrator's Landmine

Among the module's administrative functions are serial backups and serial database conversions across selected or all client databases. A genuine convenience for the office. A structural hazard for anything reading those databases.

Two distinct failure modes, and the second is the one that gets missed.

Convert everything at once and a SQL-reading integration breaks for every client on the same morning. That is the operational argument behind the rule I keep repeating from the API guide — read the database freely, never write to it — extended one step: reading it still couples you to a schema that forty clients change simultaneously.

Convert selectively — and offices do, because they schedule conversions around client deadlines — and you are reading databases at two different builds at the same time. Nobody meets this while testing. A test environment has one database. It surfaces instead as an integration that works for thirty-one clients and returns nonsense for nine, which reads like a data problem and is a version problem, and that misdiagnosis burns a week.

The rule that survives both: detect the build per database at connect, and fail loudly for that one client rather than globally. A per-client health line saying this database is at a version this connector has not seen is worth more than any retry logic you can write. Same drift alarm I argued for with enova365 custom fields, aimed at the schema version instead of the field list.

Czas Pracy: The Only Effort Data in the Stack

One more branch. It is also the least-used thing in the module.

Kategorie czasu pracy supports work sessions of type A (automatic) and type R (manual), with categories carrying codes and hourly rates. This is the only place in an accounting office's software where per-client effort gets recorded at all.

Which makes it the denominator for every automation argument anybody will ever put in front of that office. Without it, "this saves time" cannot be proved or disproved, and I would rather not make claims nobody can check afterwards.

The caveat is big enough that it has to travel with the recommendation. Type A sessions measure how long that client's database was open, not how long anyone worked in it. A window left open over lunch counts. Treat automatic sessions as a loose ceiling, not a measurement.

The categories with rates are the part that produces a real cost-to-serve number. They also require somebody to classify their time honestly every single day — exactly the discipline no office has and no software can install. If an office does have it, the ROI conversation turns into arithmetic. If it does not, say so out loud instead of quoting type A totals as though they meant something.

Blast Radius Is the Whole Difference

There is a structural difference between automating inside a company and automating inside an accounting office, and this module is where you see it plainly.

In a company, a rule that is wrong produces one wrong result. In an office, the same rule runs against forty client databases — and the batch functions here exist precisely to make that easy. A wrong applicability map does not cause a mistake. It causes forty.

Which puts the boundary in an obvious place, the same one as in the post on who signs: reading the status layer and answering who is not ready and why is safe, cheap and genuinely useful. Batch calculation and batch submission are not the next step up from that. They are a different category of act, they sit on the far side of the line between proposing and sending, and the multiplier is the reason.

One practical note if remote access is part of the plan: the browser-based version of Operacje wielofirmowe is available only to offices working in Comarch's cloud. A commercial fact that decides an architecture, so settle it in the first conversation rather than the third.

Where to Start

Export the attribute table for the last three closed months. That is the whole dataset. One export.

Compute the UPO gap on it. If it is not zero — and it will not be — you have found real money in the first hour, without building anything.

Then sit down with the person who reconstructs the applicability map from memory every month and write the thing down. That conversation is the project. Everything worth automating in an office's close sits downstream of it, which is also the argument I made about taking the office's own system seriously first — the constraint is rarely the ERP.

Only then build the readiness board, and measure it the way I would measure any of this: the share of a month's clients whose declarations are confirmed by the 10th. That is the distribution metric from the month-end piece applied to filings instead of documents. It either moves or it does not.

Wondering whether your office's readiness problem is a data problem or an undocumented filter? Get in touch. Three months of attribute exports settle it, and that is a much shorter conversation than writing a specification.

Check a Polish VAT counterparty in seconds, free

KsięgoAI checks a NIP against the VAT white list and VIES, scores the risk and saves proof of due diligence. Works in Telegram and Claude.

Try KsięgoAI→

Let’s talk about your project

Free 30-minute consultation. We’ll figure out if and how I can help.

Book a Free 30-Minute Call

Select a date

November 2026
Mon
Tue
Wed
Thu
Fri
Sat
Sun
← Back to Blog

Related Posts

What Subiekt nexo and Subiekt GT cost in 2026: licence prices, the Abonament, and the 30 days that raise the renewal by half
Blog

What Subiekt nexo and Subiekt GT cost in 2026: licence prices, the Abonament, and the 30 days that raise the renewal by half

Subiekt nexo for 3 workstations is 1 275 zł net, Subiekt GT 1 045 zł, nexo PRO 2 575 zł. Those are perpetual licences, and then there's the yearly Abonament: 349 zł for nexo if you renew within 30 days of expiry, 539 zł if later. Plus Sfera (the API), the accounting-office client licences, and a comparison with Optima and enova365.

Read more→
What Comarch ERP Optima costs in 2026: the subscription list, Basic vs Pro, and three costs it leaves out
Blog

What Comarch ERP Optima costs in 2026: the subscription list, Basic vs Pro, and three costs it leaves out

Optima's price list is public: Podstawowy 59 zł a month, Logistyka Basic 75 zł, Księga Handlowa 175 zł. The catch is the word Pro: it's a top-up on Basic, not a separate tier, so full accounting in Finanse costs 250 zł, not 200. Plus the Podstawowy limits, how HR counts employees for accounting offices, and two worked examples.

Read more→
December pay paid in January 2027: a 2026 or a 2027 cost? The 8 January payday and ZUS by 15 or 22 February
Blog

December pay paid in January 2027: a 2026 or a 2027 cost? The 8 January payday and ZUS by 15 or 22 February

December payroll paid in January is a 2026 cost, but only if the pay leaves on the date in the client's pay rules and the ZUS contributions reach ZUS on time. 10 January 2027 is a Sunday, so the statutory deadline ends on Friday 8 January. The same pay lands in the employee's 2027 PIT-11. Here's what an office checks in December and in February.

Read more→