⚠️ Important Notices
User-supplied XSLT transformations (record xslt, used via the format parameter) are now executed in secure mode: they can no longer call Java extension functions, including flexibee.Tool, load external resources via document(), xsl:include, and xsl:import, or use external entities and DTDs. A custom stylesheet using any of these constructs will fail with an error and must be updated — there is no substitute available.
Fixed an issue where, on cloud installations, the ability to change other users' passwords was incorrectly derived from the User Management permission instead of the Change Password permission. Following this fix, behavior on the cloud now matches on-premise installations — the right to change other users' passwords is now governed exclusively by the Change Password permission. Note for cloud company administrators: For users whose User Management and Change Password permissions are set differently, deploying this fix will change behavior as follows: users with the User Management permission but without the Change Password permission will lose the ability to change other users' passwords (which they previously had incorrectly), while users with the Change Password permission but without User Management will gain this ability.
For security reasons, impersonation during server authentication (server-auth.xml) has been removed without replacement — the X-FlexiBee-Authorization header, which allowed a session to claim to be a specific user, no longer has any effect. Integrations that relied on it must now log in using an actual user account.
New Features
Custom buttons can now pass a large record selection to the target application. If the resulting URL would exceed the allowed length, Flexi stores the list of selected records in temporary storage and passes only a
data-urllink in the URL, which the target application uses to download the data itself. Application developers need to add support for this transfer method in their apps — without it, a large selection will pass a link the application cannot process; smaller selections continue to work unchanged. Stored data has a limited validity period, and local temporary storage is cleared on every server restart.The Unified Monthly Employer Report is now accessible via the API. The
jmhz-podani-hlavrecord can be read, exported, and used to create new submissions; a submission is always imported in full, including nested items, since editing or deleting an existing submission via the API is not possible.Payroll processing can now be managed via the API without the desktop client. New records have been added:
vypocet-mzdyfor calculating a single payslip,zruseni-vypoctu-mzdyfor canceling a calculation (optionally including user changes to payroll components),vypocet-mezdfor bulk payroll calculation for a given year and month, andgenerovani-zavazku-mezdfor subsequently generating liabilities and internal documents.
Legislation
The Chart of Accounts for Non-Profit Organizations now includes the expense account 523 Remuneration of Members of Business Corporation Bodies, classified in the profit and loss statement on line A.III.10. Wage Costs. The account is also added to existing companies using non-profit legislation, allowing remuneration of elected members of statutory bodies (typically in homeowners' associations) to be booked in accordance with Decree No. 504/2002 Sb.
Improvements
Financial statement reports can now be fully defined outside the desktop application as well — new API records have been added:
uziv-predpisfor the custom rule defining a report line androzpad-radkufor breaking down a report line into individual accounts. For custom reports, rules can not only be read but also modified and imported; the line breakdown is read-only.The create user endpoint (
/u) now accepts data in XML and JSON as well, not just as form data or URL parameters. The/u/{userId}endpoint for editing a user now also supports XML and can modify permissions, making it functionally equivalent to/c/{firma}/uzivatel/update.Record metadata now includes flags such as
visible,editable, and others for collections (relations) as well, just as it already does for regular fields.Balance loading is faster. The paid/unpaid filter used to be evaluated twice, and for companies with a large number of unmatched items and matching symbols, this could block the balance listing for a long time; now everything is calculated in a single pass, and the balance opens significantly faster.
The account name in the Turnover Trial Balance and Account Balances now displays in the application language — for example, in an English environment, the English account name is used, and if none is set, the original name is displayed instead. Account names behave the same way in related printed forms.
Exporting external identifiers (ExtID) via the API for records that assemble data from multiple tables — such as
skladova-karta,odberatel, ordodavatel— is now significantly faster. When exporting hundreds of thousands of records, processing time has been reduced by an order of magnitude. Sorting of inventory cards by price list price, which previously did not respect the correct order, now also works correctly.Database optimizations. Queries that check for the existence of records are now faster — instead of scanning and counting all matching rows, it is sufficient to find the first matching record. Custom database functions (e.g.,
fnn,minvalue,compareid) are now more efficient and support parallel processing. This speedup applies across the entire system, especially with large volumes of data.Generating document UUIDs and searching by them is faster.
When generating liabilities from payroll, work is now split across cost centers even when an employee has no worked hours entered — for percentage-based (fixed) allocation, the specified percentages are now used instead of previously booking the entire amount to the default cost center. If an employee has a monthly allocation based on hours and worked hours are missing, a new warning message alerts you to this.
A customizable print report is now available for the outgoing order record, which you can customize yourself — just like with invoices, outgoing quotes, or incoming orders.
Newly registered customers now work directly in the new look in the web interface.
Bug Fixes
A person's password is now stored only on the person's header, not on individual settings, and is applied consistently regardless of whether you enter it in the application or via the API. Previously, an entered password was sometimes ignored or not saved to the header at all. The password can now also be deleted by clearing both fields (via the API, by setting the
passwordproperty to an empty value), and it can be entered when creating a new employee; saving a record without changing the password does not alter it, and a password change alone does not create a new person setting.An import using a filter with the
deleteaction to delete multiple settings for the same record at once used to fail with an error for a person and, for a dependent person, the setting was not actually deleted. Such an import now succeeds for persons, employment relationships, and dependent persons alike, and the timeline is correctly recalculated — the adjacent setting is extended so no validity gap is created; additionally, for dependent persons, the import now applies the same validity date checks as for persons and employment relationships.In the Account Movements module, clicking the Balance button caused an application error if the selected row had no account specified. The button is now disabled in such cases.
Entering an excessively large number in a numeric field — for example, the Rate field in the Pricing Rates module — caused a crash with a generic database error message. The digit count check did not account for decimal places and allowed values outside the permitted range to reach the database. A clear validation message is now displayed instead.
When importing a person including nested employment relationships, employment relationship checks were silently skipped, and only an error about a non-existent person setting was logged — the setting was not yet saved in the database at that point. The setting from the data currently being imported is now used, so validations proceed normally, and any resulting error message additionally specifies which person and date it concerns.
Fixed a security vulnerability in the
/mini-rmiinterface, which in previous versions stopped respecting the server's list of allowed classes.Fixed a permission check issue in the batch administrator API when using a versioned prefix (
/v2/admin/batch).Fixed a security vulnerability that allowed server-side code execution via a template in the custom button URL. Templates can no longer instantiate classes intended for executing commands; standard template constructs remain unchanged.
On non-cloud installations with server-side login enabled, it was possible to perform batch administration via
/admin/batchcompletely without credentials — the request went through with instance administrator rights, which could allow an attacker to create their own administrator account.Company restoration from a backup now also operates under the company's unprivileged database role in subsequent steps (cleanup of add-on data, etc.).
Attachments accessed via
?inline=truenow display in the browser only for the typesapplication/pdf,image/png,image/jpeg,image/gif, andimage/webp; all others are now always downloaded. Additionally, responses containing attachment content now include restrictive security headers, and the login cookie carriesSameSite=Laxand Secure over HTTPS — web integrations on a different domain that relied on cross-site cookie transfer will need to be updated.A credit note created using the Create Credit Note function did not respect the Variable Symbol Primarily from Order Number setting on the document type — the variable symbol was derived from the credit note's own number before data was taken over from the invoice being credited, and was not recalculated afterward. This applies both to the desktop application and to the credit note action called via the API.
Payroll calculation called via an action could fail with an internal error in situations where it should only have shown a warning to the user — typically for a payroll component with a negative base in periods where this is merely a warning. The calculation now completes successfully and the warning is displayed correctly; in cases involving an actual error, the calculation still fails as expected.
A monthly employer report split into multiple batches used to open as several separate tabs when using the Open in Browser option and exporting to XML, with each tab only seeing its own batch — meaning that saving the submission back to Flexi was incomplete. Now all batches of a single submission are passed to the browser together in one tab and can be saved as one complete submission.
On macOS, working with a bill of materials repeatedly triggered an error dialog with the message "column must be valid, was -1" — it appeared with every click in the bill of materials tree, making it impossible to work with reasonably. This error no longer occurs, and value editing and saving of column widths and order continue to work as before.
In the XML for the bulk notification to the health insurance company, the postal code was written exactly as entered — including any spaces (e.g., "530 02") — causing the file to fail schema validation and be rejected by the insurance company. Spaces are now stripped from the postal code, both for the employer's address taken from the company settings and for the employee's address from their personal record. This change does not affect older printed outputs of the bulk notification or the Insurance Payment Summary.
Fixed adding deductions to already calculated payroll — deductions are now automatically added to calculated months without needing to cancel and recalculate. Also improved validation of deductions in locked periods, which now checks locking only within the Payroll module and allows editing basic deduction properties even in other locked modules.
The calculation of exchange rate gains when revaluing foreign currency balances is now correct — under certain circumstances, documents outside the selected period were previously included in the total, resulting in an incorrect exchange rate difference. Additionally, the closing wizard now displays the message "The previous period is not closed. Calculated exchange rate differences may be incorrect." if revaluation is to be performed as part of closing and any prior period remains unclosed.
If you have the new Outlook set up on Windows, sending emails from Flexi now works correctly, including attachments.
Items on a summary invoice created from a business case were missing the "copy from document" flags for VAT accounts and base accounts, as well as for VAT classification or the VAT control statement. Although accounts were correctly populated when the invoice was created, later changes on the invoice header were not propagated to the items, risking incorrect posting.
Deduction of an advance tax document from a final invoice with a different VAT rate can now be performed even when items have no fulfillment group specified. The fulfillment group selection is now always offered during deduction — even when there is only one or none on the items — and a new option, "Other Group", is now available, allowing deduction of items with an empty or different fulfillment group; this applies both in the application and via the API.
The Advanced Payment Matching add-on, for a cash document settling multiple invoices, kept showing the first matched invoice in the description of all split payments. The description now reflects the document the payment actually settles; descriptions entered by the user or via import remain preserved.
Issuing goods with a tracked batch or expiration date — for example, during an inventory correction — no longer fails with an error about a disallowed negative stock level in situations where the goods are physically in stock; customer reservations, which have their own separate check, are no longer included in the available quantity for a specific batch or expiration date. We have also fixed the calculation of stock levels for items with negative quantities, so the available quantity now correctly reflects reality.
When creating a goods issue from an incoming order, the oldest available expiration date is now pre-filled more reliably: when the oldest expiration date does not cover the required quantity, the next available one is offered instead of leaving the field empty, and reservations linked to the source order item are taken into account, so the order no longer blocks its own fulfillment. For multiple identical items on a document, the quantity already selected for the same expiration date is also tracked; the pre-filled quantity to fulfill remains unchanged.
When creating a bulk order from a user-defined query, price list items with packaging set showed a zero quantity instead of the value calculated by the query, making the order unusable. These items are now also pre-filled with the correct quantity from the query; ordering from source business items is unaffected and still works with breakdown by packaging.
The bulk notification to the health insurance company now correctly offers employees who previously had an employment relationship with you at any point in the past — previously, any prior insurance contribution was enough to exclude such an employee from the notification entirely. Registration is only omitted when the employee had another—continuing or concurrent—employment relationship immediately before the start of the new one, under which insurance coverage is already ongoing.
When creating a corrective monthly report, marking an employment relationship for cancellation failed with an error stating that an individualized cancellation-type form may contain only a header, preventing the report from being completed. The individualized section is now no longer loaded or filled in for employment relationships marked for cancellation, and the report is created correctly.
Creating a goods receipt from an incoming order with an item that has a bill of materials whose component is missing from stock used to cause an application error. This was caused by the automatically generated component reorder order being opened and validated using goods receipt rules. Each newly created document now uses the rules appropriate to its type, and order fulfillment into a goods receipt completes without error.
When matching payments to a foreign currency invoice, an unreasonably large exchange rate difference could occur if a payment was matched out of posting-date order — typically an offset with an earlier posting date matched after later payments. The invoice's residual exchange rate is now calculated from the same set of payments in both CZK and foreign currency, so the exchange rate difference is calculated correctly regardless of matching order.
If a saved filter had a form that the filter dialog could not display (for example, an "or" condition between two different fields), opening it or applying it from favorite filters used to fail with an error and crash the dialog. Now, in such cases, a clear warning about the unsupported saved filter format is shown, the filter is not applied, and the dialog remains usable.
For agreements to complete work and small-scale employment, the Unified Monthly Employer Report no longer requires the "P" character at the second position of the ELDP code for deferred income, and the ELDP section of the report is no longer generated. According to the General Principles for Completing ELDP, income settled after such a relationship ends is considered income for the month in which the relationship ended.
Exporting a record to XLS and XLSX format via the API for records with relations (e.g., price lists) used to fail with an error. A relation is now written in the workbook as a reference to a record in the same format as in XML or CSV export (e.g.,
code:ZBOZI); the descriptive text of the referenced record is no longer exported.Strengthened report security. Stricter checking of expressions in print reports, which can no longer access internal object properties that could be exploited to execute arbitrary code. A resource specified in a report by text location — image, subreport, stylesheet, or translations — is now loaded only via HTTP and HTTPS, and access to internal and local addresses is denied. Images and subreports from public addresses continue to load as before.
Technical Changes
Updated third-party libraries with reported security vulnerabilities — including components for XML and print report processing, the PostgreSQL database driver, and a cryptographic library.
Schemas for the Unified Monthly Employer Report are based on version 1.4.3.4 released by the Czech Social Security Administration (ČSSZ), including three newly added forms (foster parent, international workforce leasing, and disabled/reduced work capacity employees). Validation of the generated submission thus matches the current ČSSZ data interface.
The schema for the REGZEC electronic submission is based on ČSSZ version 1.4.0.3. Data validation is now stricter — a field with an empty value will cause the submission to fail and must be filled in before sending.
