# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [7.1] - 2026-08-07

### Fixed
- Batch data import no longer crashes on a water slot with no requested weight.

## [7.0] - 2026-08-07

### Added
- The new pump order and material sale forms offer a "clear form" button instead of "back", like the new order form.

### Changed
- The new pump order form field order now matches the order form.
- The new pump order form's right column matches the order form: the surcharges section is headed "Příplatky" and the print-pumping-sheet tick has a heading.

### Fixed
- KDX import no longer fails when the same material is listed under several type slots; a cement arriving in an Addition slot keeps that slot in the .ord sent back to control and is promoted to Cement in the material list (migration 197).

## [6.7] - 2026-08-04

### Added
- A material sale can record the construction site it went to and the vehicle and driver that collected it. All three are optional and follow the same module gates as the expedition form (`module_contracts`, `module_cars`). **Irreversible:** applying migration 196 alters the schema; a downgrade requires rolling it back.

### Changed
- The material sale form field order now matches the expedition (new order) form.

### Fixed
- The material sale pricelist field is now the same plain select the order form uses, without the quick-add "+" button.

## [6.6] - 2026-08-03

### Added
- Direct material sales: sell raw material to a customer outside the order workflow, priced from a pricelist (or a manual override), stock-coupled and invoiceable. Gated by `module_prices`. **Irreversible:** applying migration 195 alters the schema; a downgrade requires rolling it back.

### Changed
- Top menu: "Objednávky" is now "Výroba" and material sales appear as "Prodej"; the Lists menu is reordered so entries are grouped with the module they belong to.
- The new pump order form is split into two columns — data entry on the left, surcharges and prices on the right — matching the expedition and material sale forms.
- Setup: each number prefix now sits directly above the counter it applies to.
- Stock movements written by a material sale can no longer be edited by hand in the listing.
- Ticking "issue tax document" without picking a payment type no longer issues a cash document. The order or sale is still created; the document is declined with a message, so it can be issued once a payment type is chosen.

### Fixed
- Clicking a list column header back to its default ordering no longer leaves the list in database order, which buried the newest rows at the bottom.
- The material sale form now explains when a sale's frozen unit price no longer matches the pricelist, for example after the material was changed.

## [6.5] - 2026-07-29

### Added
- Material stock movements have their own listing (Lists / "Pohyby na skladě"), and the stock-up form now shows the stock-ups entered so far.

### Changed
- Stock movements written by production can no longer be edited by hand in the listing.
- REST API: stock movements are a top-level `/stock-movements` collection instead of `/materials/{id}/stock`, and can now be created and updated through it.
- REST API: collection filters accept `field:isnull:true` / `:isnull:false`, the only way to select rows on a NULL column.

## [6.4] - 2026-07-13

### Fixed
- A batch-data file (.ce) arriving after its order was already finished no longer crashes the input processing loop; the delivery is recreated so the batch data is preserved.

## [6.3] - 2026-07-09

### Added
- New `--port` command-line option to override the web server listen port.
- Tax documents track the issue date and the taxable-supply date (DUZP) separately; existing documents keep their original date as DUZP.

## [6.2] - 2026-06-30

### Added
- The "issue tax document" checkbox default is now configurable globally (Setup) and per contract.
- Tax document edit form now lists the orders and pump orders it covers.
- Orders can be produced for unpriced recipes, with an optional per-order unit-price override.

### Changed
- Renamed "recipe prices" to "recipe pricelists" throughout the UI.
- Menu: the quick-add "+" now precedes the main link, and the order "+" is wider.

### Fixed
- Tax document forms/listing use the DUZP (taxable-supply) date caption; date and time captions split.
- Tax document order pick list shows the full date and time.
- A unit-price override of 0 is treated as a valid price.
- ATX D300 importer: tolerate missing optional tables and an optional recipe number; set material weight on imported deliveries.
- ATX D300 importer: fix DBF field-name matching at the last window; the unused-key guard no longer aborts on known legacy columns.

## [6.1] - 2026-06-08

### Added
- REST API: manage recipe composition via a flat `/recipe-materials` resource.
- REST API: manage recipe prices via a flat `/pricelist-recipes` resource.

### Changed
- The listing search box moved from the top menu to the list footer.
- Reorganized the expedition/orders/pump orders menu.
- REST API docs: document `POST /orders` dispatch preconditions and surface write constraints in the OpenAPI spec.

### Fixed
- `material.ini` is now re-exported when materials are written via the REST API.
- An empty `material.ini` is now written when the last material is deleted.
- Include previously missing migrations in the Docker image.

## [6.0] - 2026-06-07

### Added
- Added REST API.
- REST API self-documents at `/api/v1/docs` (a JS-free HTML page) and `/api/v1/openapi.json` (generated OpenAPI spec).

### Changed
- Internal DB foreign-key and snapshot field renames (migrations 190/191 rename columns); the legacy GUI JSON keys change accordingly, while the `/api/v1` wire contract is unchanged. **Irreversible:** applying migrations 190/191 renames columns; a downgrade requires rolling the migrations back.
- REST API now emits relative `Location` headers and pagination links, so it works unchanged behind a reverse-proxy sub-path (e.g. `/dispatch/api/v1`).
- REST API is now off by default; enable it with the `--api` command-line flag.
- REST API no longer exposes internal underscore-prefixed fields (e.g. the precomputed `_search_string` search blob) — they cannot be read or set over the API.

### Fixed
- Some fields not being rendered correctly in printouts.
- ATX D300 importer fixes.


## [5.0] - 2026-06-02

### Added
- Pump orders can now be invoiced via a TaxDocument, mirroring regular orders. Adds a nullable `pumporder.taxdocument_id` foreign key (migration 189). **Irreversible:** applying migration 189 alters the schema; a downgrade requires rolling the migration back.

### Changed
- TaxDocument creation is deferred until the pump order is submitted; customer and construction-site fields lock once an order is linked to a document.
- The "Vystavit daňový doklad" (issue tax document) checkbox now defaults to unchecked.
- Updated dependencies.

### Fixed
- `produce`: deferred TaxDocument intent is now audit-logged so interrupted flows can be recovered.
- `produce`: unexpected exceptions during Flow A TaxDocument creation are caught, and `UserInputError` from TaxDocument creation is surfaced to the user.
- `produce`: the in-memory order's `taxdocument` is refreshed after `create_with_orders`.
- `pump_order_add`: the response is refreshed from the post-link PumpOrder so the tax-document number is no longer stale; `ValueError` and `DoesNotExist` during the deferred finalize are now handled.
- `order`: customer and construction site lock in the edit form once the order is document-linked; `from_enhanced_dict` runs in a transaction so a surcharge rewrite rolls back if a freeze is rejected.
- `taxdocument`: customer and TaxDocument FK freeze on linked items.
- `dispatch` / printouts: the issued document number is now shown, and the pumps note is hidden when the pumps module is disabled.


## [4.9] - 2026-05-15

### Added
- `Setup.decimal_comma` (default `True`) — global toggle for `,` vs `.` as the decimal separator in user-facing numbers (listings, edit forms, ZAPA/taxdocument printouts).
- Configurable number-prefix Setup fields (`delivery_sheet_number_prefix`, `taxdocument_number_prefix`, `pumporder_number_prefix`); the prefix is snapshotted onto the row at creation so later Setup changes don't rewrite already-issued documents.

### Changed
- Rename `Order.auto_number` → `Order.number` and `PumpOrder.auto_number` → `PumpOrder.number` so all three numbered documents share the same field name. `State.*_num_counter` names are unchanged to avoid breaking existing installations.

### Fixed
- `taxdocument.html`: volume cells, VAT line and totals no longer leak `.`-formatted floats — they now honor the decimal-comma setting.
- `delivery_sheet_zapa_overlay.html`: the *Expedováno* cell now respects the decimal-comma setting.
- `bridges/standby.py`: `get_or_make_order` now propagates `ConstructionSite.distance` (and `distance_driven`) onto the Order, fixing the `0 km` "vzdálenost na stavbu celkem" cell on standby-imported ZAPA delivery sheets. Pre-fix orders need a re-import or manual save to backfill.
- `bridges/standby.py`: `make_or_update_contract` now links the created/updated `Contract` back to the Order, fixing the empty "číslo objednávky" cell on standby-imported ZAPA overlays. Pre-fix orders need a re-import or manual save.
- `bridges/standby.py`: `delivery.set_driver(driver)` is no longer gated on `if created:`, so existing drivers get copied onto repeat-trip Deliveries and "převzal řidič" is filled on the ZAPA sheet.
- `delivery_sheet_zapa_overlay.html` / `delivery_sheet_zapa_full.html`: the "vzdálenost na stavbu celkem (tam i zpět)" cell referenced a non-existent `delivery.site_distance`, silently printing `0 km`; switched to `order._distance_driven_calculated`.


## [4.8] - 2026-05-14

### Added
- Order edit form now exposes `temperature_air`, `temperature_concrete` and `weather` (gated on `module_delivery_sheets`). Previously these were only settable on the new-order/Expeditions form and frozen afterwards, with no way to correct a wrong value on an existing order.

### Fixed
- Order edit form: the "go back" button rendered as primary (colored) instead of secondary (gray), inconsistent with every other edit form in the app. Added the missing `secondary: True` so the contrast between "back" (gray) and "Save" (primary) matches contract, material, recipe, car/driver, price matrix and the rest.
- `delivery_sheet_zapa_overlay.html`: the "Výroba" cell now renders the aggregated production start/end times (`HH:MM HH:MM`) instead of being empty. Computed in the view from `min(batch.production_start_t)` / `max(batch.production_end_t)` over the delivery's batches and passed to the template as `production_start_time` / `production_end_time` (named without `_t` since these are formatted time-of-day strings, not full date+time timestamps).


## [4.7] - 2026-05-13

### Fixed
- Revert all migration-related "fixes" from 4.3-4.6. The "attempt to write a readonly database" failure on the affected Windows plant was never a SQLite, peewee_migrate, WAL or migration-185 problem — it was the Windows `READONLY` file attribute being set on `dispatch.sqlite3` by rsync running under Cygwin. Cygwin maps Unix mode bits to Windows file attributes, and an `rw-r--r--`-style mode on the source side can land on the destination with `+R` set, which makes SQLite refuse every write regardless of NTFS ACLs. Copying the file via the native Windows shell clears the attribute and the plant recovers. `mount_and_migrate_db` is restored to its pre-4.5 shape and migration `185_MAIN.py` is the simple `migrator.drop_not_null` form from 4.2. Mitigation on the deployment side: pass `--no-perms` to rsync when syncing to Windows, or run `attrib -R` on the synced file as part of the deployment.
- `delivery_sheet_zapa_overlay.html`: the facility address block at the top of the ZAPA delivery sheet was hard-coded to "betonárna 7502 KLADNO areál POLDI" — every non-Kladno provozovna printed Kladno's address and phone numbers. Replaced with `setup.facility_name`, `setup.facility_phone`, `setup.facility_address`, `setup.facility_zip`, `setup.facility_city`, `setup.facility_email` and `setup.company_phone` for the central dispatch line, matching the convention from `delivery_sheet_kvd_overlay.html` and other facility-aware printouts. The company-name prefix on both lines now also reads `setup.company_name` instead of a hard-coded "ZAPA beton a.s.". (Originally shipped in the yanked 4.4.)
- `delivery_sheet_zapa_overlay.html`: the "Vyrobil" field rendered the literal text "TODO" on the printed sheet. The data (= user actually producing the concrete) is not currently tracked, so the field now renders empty and the `TODO` marker is preserved in the HTML comment until the data source is wired up. (Originally shipped in the yanked 4.4.)


## [4.6] - 2026-05-13 [YANKED]

**Yanked:** shipped a `journal_mode` flip during migrations that misdiagnosed the cause. The actual failure was a Windows `READONLY` file attribute (set by Cygwin rsync) — fixed in 4.7 by reverting; no dispatch-side code change was needed.


## [4.5] - 2026-05-13 [YANKED]

**Yanked:** shipped a `db.close()` before the migrator that misdiagnosed the cause. See 4.6 yank note.


## [4.4] - 2026-05-12 [YANKED]

**Yanked:** the migration-185 `writable_schema=OFF` change misdiagnosed the cause; see 4.6 yank note. The ZAPA delivery-sheet fixes in this release are re-shipped in 4.7.


## [4.3] - 2026-05-12 [YANKED]

**Yanked:** the migration-185 `writable_schema` rewrite misdiagnosed the cause; see 4.6 yank note.


## [4.2] - 2026-05-12

### Changed
- `TaxDocument.customer_record` is now optional — Czech VAT rules don't require an identified customer on receipts below the small-amount threshold. The create form, `/add/TaxDocument` endpoint, the post-expedition Flow A and the atxd300 legacy importer all accept a missing customer; the printout hides the customer block when none is set. Migration `185_MAIN.py` drops `NOT NULL` from the column. The single-customer-per-document constraint still holds: a doc without a customer can only group orders that also have no customer.
- Migration `182_MAIN.py` (the 4.0 invoice → tax document backfill) now creates the `customer_record_id` column nullable from the start and no longer skips legacy orders that have an `invoice_number` but no customer — those orphans become TaxDocuments with `customer_record=NULL` instead of being silently dropped. Plants upgrading from ≤3.26 will preserve their orphan invoices automatically. Plants already on 4.0 had their orphan `invoice_number` data dropped at the time of the original 182 run and need to recover from a pre-migration backup if those records are wanted back.
- State migration from `/atx300/state/dispatch.json` is now strictly one-way: after the JSON contents are imported into the `State` table, the file is renamed to `dispatch.json.bak`. File presence is the sole signal that migration is still pending, replacing the previous "State row already exists" check.


## [4.1] - 2026-05-12 [YANKED]

**Yanked:** ships the broken migration `182_MAIN.py` introduced in 4.0 — see the 4.0 yank note.

### Changed
- The expedition form's tax-document checkbox is now checked by default and the Czech caption is clarified to "Vystavit daňový doklad" — almost every dispatched order produces a tax document, so users no longer have to tick the box for each one.


## [4.0] - 2026-05-12 [YANKED]

**Yanked:** the `invoice → TaxDocument` backfill in migration `182_MAIN.py` silently drops legacy orders that have an `invoice_number` but no `customer_record_id`, because the new `taxdocument.customer_record_id` column is created `NOT NULL`. After the migration completes, `order.invoice_number` is dropped and the data is unrecoverable without a pre-migration backup. Plants that have already upgraded need a one-off recovery script run against their backup; plants still on ≤3.26 should skip 4.0/4.1 and upgrade directly to a later release where migration 182 creates the column nullable from the start and preserves orphan invoices.

### Added
- New `State` singleton table (DB migration `184_MAIN.py`) holding the auto-number counters (`order_num_counter`, `taxdocument_num_counter`, `pumporder_num_counter`) and the "last value typed by the user" form defaults (`temperature_air_by_user`, `temperature_concrete_by_user`, `weather_by_user`, `without_water_by_user`). On first startup after upgrade, any existing `/atx300/state/dispatch.json` is read once and its contents (including the legacy `invoice_num_counter` → `taxdocument_num_counter` rename) are imported into the new table; the leftover JSON file is then ignored.

### Changed
- Counter increments for Order, TaxDocument and PumpOrder now share a transaction with the rows they number, eliminating the race where the JSON state file and the DB could disagree if one half of the write failed.

### Removed
- **Irreversible:** `/atx300/state/dispatch.json` is no longer read or written at runtime — all values now live in the new `State` table. The file may be deleted after the first upgraded startup has completed. Downgrading after upgrade will lose any counter increments made under 4.0.


## [3.26] - 2026-05-11

### Added
- Tax documents (daňové doklady) are now first-class records: a new `TaxDocument` table covers one or more orders with a single payment type, VAT rate, currency, and issue/VAT date. The expedition form gained a "Vystavit doklad" checkbox; the payment type selectbox is shown only when ticked. The previous `Order.invoice_number` / `Order.payment_type` fields are migrated into the new table.

### Changed
- Expedition page: the "recently produced orders" list now auto-refreshes every 10 seconds, like other listings.
- Internal naming: the "invoice" terminology has been retired everywhere except the `PaymentType.INVOICE` enum value (which is still a payment type). UI labels in English/German/Slovak now say "Tax document" instead of "Invoice"/"VAT invoice"/"Rechnung"/"faktura"; the Czech text was already "Daňový doklad" and is unchanged. The print URL changed from `/print/invoice/<id>` to `/print/taxdocument/<id>`. The Setup template field was renamed from `invoice_fn` to `taxdocument_fn`, and the default template file from `invoice.html` to `taxdocument.html` (DB migration `183_MAIN.py`).
- Production overview printout: when a tax document's payment type is "Invoice" (external invoicing system), our internal tax-document number is hidden — preserving the prior `invoice_number`-hiding behaviour now that the number lives on `TaxDocument`.

### Removed
- `Order.invoice_number` and `Order.payment_type` (moved to `TaxDocument`). Existing data is migrated automatically.

### Fixed
- Auto-refresh in `viewOnly` listings (e.g. the expeditions "recently produced" list) no longer triggers a 1 Hz redraw of the surrounding page, which was firing the test-synchronisation signal every second and causing intermittent frontend test failures. The visible 10-second data reload is unchanged.


## [3.25] - 2026-05-05

### Added
- New "Export recipes" page under the Misc menu, with a "decimal comma" checkbox so the user can pick whether numeric values use a comma or a period in the exported CSV/TSV.

### Changed
- Recipe listing no longer has the inline CSV/TSV export button; use Misc → Export recipes instead.

### Fixed
- Recipe CSV/TSV export now honours the "decimal comma" preference instead of always emitting raw float values with a period.


## [3.24] - 2026-05-05

### Added
- Setup form: each numeric-series counter shows the highest value already used in the database, so the user can avoid setting a sequence below already-issued numbers.
- Contract listing: a column showing the volume produced so far for each contract.

### Changed
- Order copy count is no longer stored on the order itself; it is taken from Setup at print time. Pump orders have their own separate copy count setting in Setup.

### Fixed
- Invoice printout: surcharges of type "% of concrete price" no longer cause column misalignment and missing VAT/total cells.
- Invoice, `delivery_sheet_bezedos`, and `production_overview` printouts now render currency values with exactly the configured number of decimals (`currency_rounding_precision`).
- Setup form: order/invoice/pump-order numeric series counters can no longer be corrupted. Editing a counter no longer reverts on focus-out. Counters the user did not touch are left alone on save, so editing other fields no longer rewinds a counter that production bumped in the meantime. If the user edits a counter and it has drifted since the form was opened, the save is refused.
- atxd300 importer: customer names from `nazev` and `nazev2` are now joined into a single name (instead of stashing `nazev2` in the comment field), and imported recipe prices are stored in `PricelistRecipe` so the application actually uses them.


## [3.23] - 2026-04-24

### Added
- Recipe edit form shows warning infoboxes when `mixing_duration`, `mixer_semi_opening_duration`, or `mixer_opening_duration` is not filled in (does not block saving).
- Containerfile and Justfile targets (`image-build`, `image-push`, `image-run`) for building and running the application as a dual-arch (amd64+arm64) OCI image.

### Security
- Bumped `lxml` from 6.0.4 to 6.1.0 to address CVE-2026-41066.


## [3.22] - 2026-04-15

### Fixed
- Use write-then-rename (atomic) pattern for all file writes to prevent readers from seeing partially-written files.

## [3.21] - 2026-04-14

### Added
- Continuous mode: vehicle and driver fields are now visible (optional) in the Expeditions form. If selected, they apply to the first delivery only.
- New `distance_rounding_precision` config setting for controlling decimal places on distance in km (default 0).
- Option to display dosed material weights in tonnes instead of kilograms in consumption, stock, and production printouts and exports (checkbox in the report form).

### Changed
- Changed default rounding precision for tonnes to 2.
- Move value/currency formatting from frontend to backend.
- Only allow .ord files to create/update order and recipe in standby mode.

### Fixed
- Fix distance override showing 0 and not accepting zero value.

## [3.20] - 2026-04-10

### Changed
- Tabular printout: don't title-ize translated headers.
- Decimal comma handling for Metrostav exports (work in progress).

### Fixed
- Display names instead of IDs in production printout filter headers.

## [3.19] - 2026-04-08

### Fixed
- Fixed UNIQUE constraint error on construction site name when processing .ord files with the same site name but different site numbers (e.g. "Olomouc" used for multiple ConstructionSiteNumber values). Duplicate names are now disambiguated with the site number suffix.

## [3.18] - 2026-04-07

### Added
- Changelog is now included in the atxpkg package.

## [3.17] - 2026-04-05

### Added
- New `tonnes_rounding_precision` config setting for controlling decimal places on delivery sheet total tonnes (default 3).
- New `volume_rounding_precision` config setting for controlling decimal places on volume in m³ (default 2).
- Show last paired driver in vehicle listing and last paired vehicle in driver listing (mj195).
- Decimal comma toggle for CSV/TSV export.

### Changed
- Renamed `rounding_precision` config setting to `currency_rounding_precision` for clarity. Old name is still supported for backward compatibility.

### Fixed
- Fix vehicle-driver pairings not being saved for new pairs (broken since 3.15), causing driver/pump auto-fill to not work for first-time pairings.
- Fix 0 tonnes on delivery sheets caused by print event firing before DB transaction commits.
- Hide continuous mode auto-print setting on batch plants.

## [3.16] - 2026-04-01

### Fixed
 - Added missing migration

## [3.15] - 2026-04-01

### Added
- Add configurable invoice template.
- Add form to modify car-driver cache.
- Show vehicle volume in select box.
- Add sub-headers to setup form.

### Changed
- Reorder vehicle form fields to be consistent with column order in listing.

### Fixed
- Add missing LockedTable caption translation.

### Security

## [3.14] - 2026-03-30

### Added
- Add recipe pricelists with price matrix UI, replacing single per-recipe price.
- Add per-user can_produce permission.

### Changed
- Show x2/x3/x4 repeated print buttons only on delivery sheets and invoices.
- Filter pump order selectbox to active orders from last 30 days.
- Internally rename CompanySurcharge to Surcharge.
- Internally rename Price to SpecialPrice.

### Fixed
- Persist without_water setting across program restarts.

## [3.13] - 2026-03-22

### Added
- Show tonnes in production printout and export.
- "Group by delivery" option for production printout and export.

### Fixed
- Bind test server to localhost.

## [3.12] - 2026-03-19

### Added
- Email fields for Setup (company and facility/provozovna) and ConstructionSite models.

### Changed
- Upgrade peewee to 4.0.2 and peewee-migrate to 1.15.0.

### Fixed
- Only set k_value/k_ratio on Addition-type OrderMaterials.

## [3.11] - 2026-03-13

### Fixed
- Fix database migrations not found when running PyInstaller-packaged binary.
- Fix populate_db using old 'customer' kwarg instead of renamed 'customer_name'.

## [3.10] - 2026-03-12 [YANKED]

### Added
- Add suppress_print flag to Recipe model.
- Add production enable feature with challenge-based manual override.

### Changed
- Use AtxWSGIServer/AtxWSGIRequestHandler from atxpylib.web and update atxpylib.

### Fixed
- Fix SmartSelectBox losing selection on redraw.
- Fix SmartSelectBox double-click bug when focus changes.
- Fix frontend tests failing when run from non-Prague timezone.

## [3.9] - 2026-03-05 [YANKED]

### Fixed
- Fix compilation.

## [3.8] - 2026-03-04 [YANKED]

### Added
- Add support for weather display.
- Add ConstructionSiteNumber field (for KDX).
- Add facility code to order communication file.
- Add vehicle registration (SPZ) filter to production printout.
- Add operator to zapa delivery sheet.
- Write operator to order file.
- Add bes and miroads logos.
- Parse DistanceJobSite from KDX .ord files and save to ConstructionSite.distance.

### Changed
- Modernize compilation.
- Update zapa delivery sheet templates.
- Update dependencies and atxpylib.
- Make INI file tests case-sensitive.

### Fixed
- Prevent InputField from losing user input on external redraw.
- Fix setMithrilQueryString losing params due to stale route.
- Fix frontend tests failing when system timezone differs from app timezone.
- Fix socket leak in test server port discovery.
- Fix obsolete atxd300 import parameter in manual.

## [3.7] - 2026-01-14

### Added
- Add DriverName and ContractID to Order communication file section.

### Changed
- Update dependencies.
- Move audit from Makefile to Justfile.

## [3.6] - 2025-11-25

### Added
- Optionally show produced volume for contract in expedition form.

### Fixed
- Fix production in non-standby mode.

## [3.5] - 2025-11-17

### Added
- Add initial code to enable production in standby mode.

### Changed
- Add mypy to Justfile.

## [3.4] - 2025-10-27

### Fixed
- Fix crash on continuous delivery handling when deleting order before production.

## [3.3] - 2025-10-23

### Added
- Add separate print event setting for continuous mode.

### Changed
- Unify/simplify production overview selection form.
- Auto-print code cleanups.
- Update dependencies.

## [3.2] - 2025-10-20

### Changed
- Standby mode: ignore temporary files.
- Minor auto-print sequence optimization.

## [3.1] - 2025-10-16

### Fixed
- Fixes after merging bridges refactoring.

### Removed
- Remove orphaned bridges.py file after refactoring to package structure.

## [3.0] - 2025-10-16

### Added
- Add Baris bridge integration with exponential backoff.
- Add standby (listen) mode replacing most of KDX bridge logic.
- Add density field to Material and OrderMaterial.
- Add delivery sheet templates: bezedos, staving, more eurovia variants.
- Add pre-computed date/time human-readable fields to delivery sheets.
- Add preferred table ordering.
- Add better error messages to templates.

### Changed
- Rename material amount to weight, remove unit field.
- Rename listen mode to standby mode.
- Refactor bridges.py into a package.
- Migrate from quitfile to filesig.
- Move .coveragerc into pyproject.toml.
- Change density unit to kg/l.
- Disallow returned_volume for continuous orders.
- Round volume of continuous orders when duplicating.
- Better listing of materials with rounding in batch listing.
- Update dependencies.

### Fixed
- Fix keystroke loss in filter input when typing fast.
- Fix automatic printing error when in continuous mode.
- Fix order._distance_driven_extra and KVD distance_driven in printout.
- Fix grand_total in batch protocol.

### Removed
- Remove RegistrationNumberField.
- Remove reload_config.

## [2.7] - 2025-08-23

### Added
- Add BATCH_COMPLETED printer event, allow selecting for continuous_mode.

### Changed
- Refactor order status change code and input file processing.
- Always have a delivery prepared, not just for batch production.
- Use calc_water_cement_contact_t for all delivery sheets.
- Update dependencies.

### Fixed
- Fix payment type cash displaying as not_set.
- Fix delivery creation in minidisp import.

## [2.6] - 2025-08-18

### Added
- Add grand total to batch protocol.
- Split importer.py into modules, finish import from atxd300.

### Changed
- More logging when importing customers from atxd300.
- Raise if not all DBF fields were used.

### Fixed
- Fix batch_protocol.html layout.

## [2.5] - 2025-08-15

### Changed
- Use calc_water_cement_contact_t for KVD delivery sheets.

## [2.4] - 2025-08-13

### Fixed
- Fix automatic print of single-batch orders.
- Do not send useless requests to atxdispatchprint.

## [2.3] - 2025-08-11

### Added
- Add concrete price percentage multiplier surcharge.
- Translate tabular export headers.

### Changed
- Duplicate driver on order duplication.
- Add actual workability time to eurovia delivery sheets.
- Reorder fields in production overview form.
- Don't show total batch count when continuous_mode.
- Eurovia delivery sheet updates.
- Update dependencies and atxpylib.

### Fixed
- Fix misleading title in Recipe.copy.

## [2.2] - 2025-07-30

### Changed
- Add stamp to eurovia delivery sheet templates.

## [2.1] - 2025-07-30

### Added
- Add prefetch mechanism.
- Add volume to deliveries listing.
- Show continuous_mode in listing if enabled.

### Changed
- Refactor PaymentType and OrderStatus enums.
- Generalize car_driver/pump_driver handling.
- Allow to "forget" car_driver and pump_driver association by selecting "none" driver.
- Order material groups in material selectbox.
- Let user partially control delivery sheet printing for continuous mode.
- Split eurovia delivery sheet templates to half-a4 and landscape-a4 versions.
- Properly format delivery volume column.
- Do not create .ord files for fully recycled orders.

### Fixed
- Fix Delivery.Driver history fields not saving new data.
- Fix wrong names and types for car_driver/pump_driver tables.
- Fix order_delivery form header, show auto_number explicitly.

## [2.0] - 2025-07-25

### Added
- Add remote printing functionality with event stream for print queue.
- Add optional local print mode.
- Add remote printing to pump order.
- Read Production_Start section from .std file to determine actual continuous mode.

### Changed
- Refactor comms files processing.
- Use Manager-provided ContinuousMode.
- Use lang='cs' in printouts when no language provided.
- Improve Enums.
- Update dependencies.

## [1.73] - 2025-07-23

### Changed
- Small fixups for KVD overlay sheet.

## [1.72] - 2025-07-21

### Fixed
- Fix crash on order cancellation with non-zero returned volume.

## [1.71] - 2025-07-09

### Added
- Add Recalc form button to EditOrder form.
- Allow Order unit_price and transport editing.

### Changed
- Make uv the implicit Python and venv runner.
- Remove unused dev dependencies and endpoint.
- Update dependencies.

### Fixed
- Fix edit order tests sometimes failing.

## [1.70] - 2025-06-30

### Added
- Add Order recycled volume field.
- Add 3min +/-10s to water-cement contact time for batch-less deliveries.

### Changed
- Export CSV in cs locale.
- Updates for faked cement-water contact value for eurovia delivery sheets.
- Update dependencies.

### Fixed
- Fix no-break space issue.
- Fix CSV tests.
- Fix KeyboardInterrupt handling in main loop.

## [1.69] - 2025-06-25

### Added
- Add customer logo images.

### Changed
- Move delivery sheet and logo setting from config file to Setup.
- Change phone from company to facility for eurovia delivery sheet.
- Reorder menu.
- Update dependencies.

## [1.68] - 2025-06-09

### Added
- Add User.phone field.

### Changed
- Shrink listings.
- Improve search text normalization.
- Disable auth for /print endpoint.
- Fit eurovia a5 sheet onto one paper.
- Update dependencies.

### Fixed
- Fix material longname extra having space as prefix.
- Fix cache hit ignore.
- Fix typing errors for new mypy.

## [1.67] - 2025-06-09

### Added
- Add tabular export to production overview.
- Print grouped info on all rows in production overview.

## [1.66] - 2025-06-06

### Changed
- Update delivery sheet template for eurovia SBM4000.

## [1.65] - 2025-06-05

### Added
- Pre-fill comment when contract is selected in expedition.

## [1.64] - 2025-05-19

### Added
- Add missing tests for Delivery.driver.

### Changed
- Update dependencies.
- More KVD delivery sheet updates.
- Hide Expeditions temperature if not module delivery sheets.
- Merge KVD printout branch.

### Fixed
- Fix wrong default for Order.payment_type.

## [1.63] - 2025-05-16

### Added
- Add driver field to order+delivery edit form.
- Add VehicleDriver tests.
- Add driver pre-fill to expeditions and new pump order.

### Changed
- Update KVD delivery sheet to new layout.
- Refactor Field locators in tests.
- Update types.
- Uncouple driver from vehicle.
- Show/hide driver details in listings.

### Fixed
- Fix invalid attribute access in templates.
- Small Expeditions cache refactor.
- Optimize lookups in cache code.
- Make cache behave less surprisingly.
- Use list where appropriate.

## [1.62] - 2025-05-15

### Added
- Add a way to import Order.customer and Order.construction_site from minidisp.
- Add Justfile vendor task.

### Changed
- Update dependencies.
- Update vendored JS libraries.
- Update pre-commit hooks.
- Properly size Plus buttons.

### Fixed
- Minidisp importer: be more verbose with errors, use unix style paths, unify naming.
- Minor optimization for importer.
- Prevent input of modified keys to SlimSelect.

### Security
- Update vulnerable flask version.

## [1.61] - 2025-05-07

### Changed
- Order Materials listing by name.

## [1.60] - 2025-05-06

### Added
- Add contract to Order edit if the Order was created via contract.

### Changed
- Reorder Order listing columns.
- Properly hide payment type in Order listing if module prices is not enabled.

## [1.59] - 2025-05-06

### Changed
- Raise eurovia continuous delivery sheet print margin.
- Decouple /prices from module_contract in menu.
- Resolve payment_type todos.

## [1.58] - 2025-05-06

### Changed
- Unbold ufi code.

### Fixed
- Implement delivery_sheet_eurovia_continuous_a5.html changes requested by certification.
- Minor fixes for delivery_sheet_eurovia_continuous_a5.html.

## [1.57] - 2025-04-30

### Fixed
- Be more strict when checking for special URL.
- Fix flaky test.
- Fix Loader count falling below 0.
- Correct super call.
- Use new delivery sheet setup name.

## [1.56] - 2025-04-29

### Changed
- Do not show Prices listing if not module_prices.
- Do not show recipe.price in selectbox if not module_prices.

### Fixed
- Show error when unable to delete an instance.

## [1.55] - 2025-04-29

### Changed
- Add hover effect on tables (listings).
- Move Recipe.price to a different spot in form.
- Merge volume-weight branch.
- Merge fast-cached-spinner branch.

---

**Note:** This changelog records all notable changes made to the project. Earlier versions are not included in this initial changelog but may be added in future updates.
