Invoices are produced by the freight workflow, not by a person, so filing is
not a Finance job function. The manual endpoints exist for controlled testing
and exceptional operations, and are left out of every role preset so they are
assigned to named admins instead.
Split resolve onto its own permission, invoices:eims_resolve: resolving an
unacknowledged submission clears the system-wide chain block and can record an
IRN against an invoice, which is a supervisor action rather than an
operational one. eims/status stays on the ordinary invoices:view.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add manual single-invoice registration, verification and reconciliation.
Nothing submits automatically; invoice creation is untouched.
Sequencing uses a durable reservation. The counter is consumed and the
holder recorded in a committed transaction before the request leaves the
process, and the HTTP call runs outside every transaction. A counter is
therefore never reused once an attempt begins, a crash mid-flight leaves the
reservation standing instead of inviting a blind resubmission, and an
ambiguous result blocks the whole system number rather than one invoice --
PreviousIrn is unknown, so any later document would chain to a stale IRN.
Deterministic rejections (400/406/401/403) mark the invoice FAILED and clear
the block. Timeouts and 5xx mark it UNKNOWN and keep it. Since /v1/verify
takes an IRN we never received in that case, POST :id/eims/resolve is the
exit: record the IRN confirmed in the MoR portal, or discard. A recorded IRN
is verified against the gateway first and refused unless EIMS reports it
against this invoice's document number.
Business and tax configuration is validated locally before anything is
locked, allocated or sent, so a missing tax code fails naming the exact
environment variables instead of at the gateway. No tax value is defaulted.
Filing gets its own permission (invoices:eims_register) rather than riding
on invoices:export -- registration is irreversible at MoR and must not
follow from the right to download a PDF.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`<module>:view` gates the backoffice sidebar entry, the route, and the API
read all at once, so granting a user another module's list endpoint for a form
dropdown also hands them that module's whole page.
Seed a `:read` twin for every `:view` key and teach the freight guards to
accept it wherever the matching `:view` is required — on GET/HEAD/OPTIONS
only, since class and method guards AND together and a write route without its
own method gate would otherwise be reachable. The frontend never checks
`:read`, which is what keeps the module hidden.
Twins are derived, not hand-written, so a new `:view` gets one for free.
Grants stay hand-curated in iam.position_type_permissions.
Adds the support, procurement, compliance, facilities, trade-access,
overview, reports and staff-users keys, plus the split action keys for
bookings, contracts, train scheduling and settings. Retires eight seeded
keys that no feature ever enforced, revoking their grants first.
- Implemented a method in to permanently delete wagons without history.
- Added corresponding permissions for hard delete actions in .
- Updated the UI components to include purge actions, ensuring they are only available to users with the appropriate permissions.
- Created modals for confirming permanent deletions in and .
- Enhanced API services to handle purge requests for locomotives, wagons, and routes.
- Added tests for the purge functionality in both and services to ensure proper behavior and error handling.
Returned-containers list now uses the shared DataTable + useListControls
(search, inclusive date range, status select, pagination) instead of a
hand-rolled table. Adds two charts below the list — returns per day by
truck type and returns by status — driven by the same filtered rows.
Series colors validated for CVD separation and surface contrast.
- Added pricing service integration to ContractsService for pre-persistence contract pricing.
- Updated LegCapacityPanel to display cargo weight instead of gross weight for better clarity on booked cargo.
- Enhanced train scheduling service to include cargo weight in booking details.
- Modified ClearanceDocumentsPage to include FULLY_EXECUTED status in booking status options.
- Refactored FileUploadSettingsPage to categorize file upload settings into tabs for better organization.
- Removed legacy onboarding fields and settings from file upload settings seeder.
- Improved type definitions for train scheduling to include cargo weight without wagon tare.
- dars delegation paper mandatory wherever poa state changes (named,
removed, forwarder role applied for/approved), not just onboarding
- ethiopian companies verify owner (and poa, once named) via fayda;
identity, not general manager, is the verified subject
- foreign companies require a typed owner passport number instead,
independent of an optional fayda verification
- fanNumber removed from client-writable dtos; server-derived only
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Added functionality to cancel contracts, allowing users to provide a reason for cancellation.
- Updated contract statuses to include SUSPENDED and changed CLOSED to COMPLETED.
- Enhanced the UI to reflect the new cancellation option and updated messaging for contract statuses.
- Refactored contract booking actions to accommodate changes in booking logic for ONE_TIME and GENERAL contracts.
- Removed clearance document management from the contract detail page, as it is now handled per booking.
- Introduced a SQL script to reset bookings and train schedules for development purposes.
- Add TransferFulfillModal for fulfilling wagon transfer requests.
- Create TransferRequestFormModal for filing new wagon transfer requests.
- Introduce TransferCloseShortModal for closing requests that cannot be fully fulfilled.
- Develop WagonTransfersPage to manage and display wagon transfer requests.
- Implement utility functions for handling wagon transfer request data and UI components.
- Enhance UI with Mantine components for better user experience.
- Introduced HazardDeclarationPanel component to display dangerous goods declaration details.
- Updated URL constants to include CLEARANCE_PROCEED endpoint for re-requesting operations.
- Enhanced permissions to include hazardous approval roles for contract approvals.
- Integrated HazardDeclarationPanel into ContractRequestDetailPage and ContractClearanceDetailPage.
- Added proceedToOperation method in bookings service for handling operation re-requests.
- Updated contract forms and schemas to include hazard class and UN number fields.
- Implemented validation for hazardous contracts in the contract creation flow.
- Added expiry notice functionality for contracts nearing validity end.
- Created tests for expiry notice calculations and labels.
- Updated UI components to reflect hazardous cargo information and validation errors.
- Introduced StampUpload component for uploading company stamp images.
- Integrated stamp upload in contract signing modal, supporting PNG and JPG formats.
- Implemented validation for file type and size (max 5 MB).
- Added visual feedback for drag-and-drop functionality.
- Updated contract-related pages to handle duplicate contract alerts and pricing notices.
- Enhanced contract expiry management with a nightly sweep service.
- Added unit tests for new features and updated existing tests for contract handling.
Join truck_types via vehicles.truck_type_id (normalized legacy
vehicle_type only as fallback) so type renames can't unmatch detention
rules and FK-less vehicles keep billing.