- 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.
- 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.
The External Truck Assignment card only exposed the Excel template from inside the Bulk Upload modal. A Download Template button now sits beside Bulk Upload in the card header, matching the container-import pattern in the booking form, so customers can grab the template without opening the modal first.
Added assertCapacity() checks before saving (matches single receive)
Added applyCapacityDelta() after save to increment counters
Now validates warehouse → yard → zone capacity hierarchy
Single receive already had both checks; bulk receive was gap.
Fixes
Download Excel template with instructions
Parse uploaded file, preview trucks
Validate container assignments (1x40ft OR 2x20ft per truck)
Commit bulk upload in one call
Display cargo warehouse location (warehouse, yard, zone, arrival time) on
the portal booking detail page once the cargo has been received and
assigned to a warehouse location.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
A suspended customer trying to create a contract was told their account
was "awaiting approval" - the guards collapsed every non-active status
into the pending message. Contract and booking creation now go through a
shared assertCompanyActiveFor that names the real company status, and
the per-role guard names the role's actual state (suspended,
blacklisted, rejected - with the reviewer note) so a customer suspended
for one operation knows the others still work.
Portal: the operation dropdown gets a Suspended badge, the block modal a
suspended branch quoting the staff message, and the wizard a
suspended/blacklisted gate instead of falling through to a submit error.
EDRFREIGHT-234
A customer whose role was rejected saw only a bare "Rejected" chip in
settings - the reviewer's note and the resubmit action existed solely
inside the contract wizard's block modal, so fixing and reapplying from
the profile page was impossible. The settings role card now shows the
reviewer note (for suspended roles too) and offers "Resubmit for
approval", which flips the role back to Pending and notifies the
backoffice through the existing roleReapplied inbox event.
RoleCard's locked variant now renders as a plain box instead of a
button so it can host the action button (buttons cannot nest) and the
new detail line.
EDRFREIGHT-233
- Introduced new yard distances resource with CRUD operations.
- Created migration for yard distances table with necessary constraints.
- Implemented service and repository for yard distances handling.
- Added controller for API endpoints to manage yard distances.
- Updated rule engine configuration to include yard distances.
- Enhanced rule engine resource page to support yard distance selection.
- Updated contracts and train builder pages to handle new yard distance logic.
- Added error handling utility for better error message extraction.
Two review-workflow gaps for freight customer onboarding:
Request for change per document. Backoffice can now flag a single uploaded
document (company document, profile licence, or POA delegation letter) with a
note the customer sees, instead of rejecting the whole role over it. Adds
review_status/review_note/reviewed_by/reviewed_at to freight.files (migration
AddFileReviewStatus, partial index for the gate), a POST
documents/:fileId/request-change endpoint, the backoffice action + modal, and a
portal banner/badge so the customer knows what to re-upload. Re-uploading clears
the flag. Approving a role is blocked while any of its documents has an open
correction; the gate check and the status write share a pessimistic write lock
on the company row (as does the change-request write) so a correction can never
slip in between the check and the profile going Active.
Resubmission is visible to reviewers. When a customer resubmits a rejected role
or amends a change request, backoffice staff are notified (allBackoffice inbox
item, deep-linked to the customer) and the resubmission surfaces in a new
"Pending changes" list view + KPI, since such companies are status = active and
never matched the pending-approval filter.
The documents step of CompanyProfileForm uploads company documents via
onUploadDocuments() and then triggers submit synchronously in the same
nextStep() call. The setDocumentFiles({}) that clears the staged files has
not re-rendered by the time finishMutation's closure runs, so reading
documentFiles there re-sent the exact same files and created a duplicate
row per document.
Drop the company-document upload from finishMutation — the documents step
already persisted them. Licenses stay, since they have no auto-upload path.
- Integrated CompanyInfoCard, ContainersCard, and ContractInfoCard into ChangesRequestedView, DraftBookingView, and ReadonlyBookingView components.
- Updated utils to handle new booking detail types and improve container summary calculations.
- Enhanced ShipmentDetailsCard and ScheduleCard to utilize updated booking detail structure and display relevant information more effectively.