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.