Commit Graph

67 Commits

Author SHA1 Message Date
marshal
cc7efe4af3 temporarily disable crew gate enforcement on train dispatch 2026-09-07 08:03:20 +00:00
marshal
4113cd1214 test 2026-09-06 15:58:27 +00:00
marshal
19145306c9 fix issues 2026-09-06 13:50:07 +00:00
marshal
75b75e3d4e feat: add contract extension request functionality
- Implemented  method in  to allow customers to request an extension for expired contracts.
- Added  component in  for users to initiate extension requests.
- Updated  to include logic for handling extension requests for expired contracts.
- Enhanced  to display extension request options and status.
- Created migration to add  and  columns to the contracts table.
- Added unit tests for contract extension request and handling in .
- Defined DTOs for request and extension in .
- Updated types in  to include new fields related to contract extensions.
2026-09-06 12:33:40 +00:00
marshalyordanos
c5c8712c5b feat(train-crew): implement crew assignment functionality
- Added TrainCrewAssignment module with controller and service for managing crew assignments.
- Integrated TrainCrewAssignmentService into TrainSchedulingService to ensure crew readiness before train dispatch.
- Updated TrainScheduling module to include TrainCrewModule for dependency injection.
- Introduced new permissions for assigning train crew in freight permissions registry.
- Enhanced front-end ScheduleCrewPage to allow assignment of crew members to train schedules, including validation and UI for adding/removing drivers and support crew.
- Created trainCrewAssignment.service to handle API interactions for crew assignments.
2026-09-06 10:29:22 +03:00
marshalyordanos
380ba4c4c9 Refactor code structure for improved readability and maintainability 2026-09-03 22:27:00 +03:00
marshal
13ac3144e2 merge conflict resolved 2026-09-02 22:35:18 +00:00
marshal
1d3361d442 feat(freight): GL rebook of cancelled wagons, seal+train required on completion, train/voyage in SMS 2026-09-02 22:28:11 +00:00
marshal
3e274cc2a2 fix(freight): gate loading on booking paymentStatus only; default schedule voyage no. to train's voyage number 2026-09-02 21:15:48 +00:00
marshal
ec5df4b328 Merge pull request #1472 from Tria-plc/freight_feature/usermanagement
feat: Implement handling for partially loaded bookings in train sched…
2026-09-01 23:56:07 +03:00
marshalyordanos
d51bed5630 feat: Implement handling for partially loaded bookings in train scheduling
- Added  to manage decisions on partially loaded bookings during log-pass and dispatch actions.
- Enhanced  to track and manage bookings left behind when a train departs a yard.
- Updated  and  to pass necessary station data for handling partially loaded bookings.
- Modified  and  to account for customer-fault fees and ensure proper handling of credits.
- Introduced fault tracking in  interface to differentiate between customer and EDR faults.
2026-09-01 23:53:58 +03:00
Hagernesh
f23500c273 fix(train-scheduling): drop wagon slots with no physical wagon pinned from marshalling docs
A slot can hold a LOADED allocation with no physical wagon backing it
— a fleet shortfall can leave a booking's allocation unpinned, and a
REAL cut nulls physical_wagon_id without ever touching the slot's own
status. Neither buildImportLoadListHtml, buildExportLoadListHtml, nor
intercityOnBoardView checked for this: they rendered a ghost row (dash
wagon number, but cargo/container info still listed) and counted it
toward the Wagons tile.

Reproduced live on S-2026-00073: 5 slots (seq 60-64) with no physical
wagon, from a booking currently held out for lack of fleet, rendered
as phantom rows on the origin doc and every numbered marshalling doc
— visible as the Seq column running up to 64 despite only 54 real
wagons.

All three now additionally require physicalWagonId (or a resolved
wagonNumber, for the import doc's already-flattened shape) before a
slot gets a row. Added coverage for all three call sites.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 10:43:34 +00:00
Hagernesh
7df96d3609 feat(train-scheduling): per-row Departure/Arrival Station on marshalling docs
buildExportLoadListHtml's wagon table (origin export doc, Marshalling
2/3, and the intercity fallback) had no station columns — only the
import doc did. Adds Departure Station / Arrival Station per row,
mirroring the import doc's existing pattern: a whole-route wagon reads
the schedule's own origin/destination, a leg-slot wagon reads its own
boardYardId/alightYardId instead (resolved via a new yardLabelById
opt, computed once per document from board+alight yard ids across the
trainSet).

Also fixes two pre-existing off-by-one colspans on the EMPTY row and
the 'No wagons on this train set' placeholder, now that the real
column count changed with the two new ones.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 10:02:46 +00:00
Hagernesh
122b6d447a fix(train-scheduling): scope numbered marshalling docs to their own stop's coupling
Marshalling 2's wagon list was computed from intercityOnBoardView's
CURRENT state (boardYardId == null || hasLoaded), which can't tell
'coupled at THIS stop' from 'coupled at a LATER stop that has, by
generation time, also already happened' — both read LOADED once the
trip has moved on. Reprinting Marshalling 2 (Dire Dawa) after
Marshalling 3's stop (Adama) had already run leaked Adama's 5 coupled
wagons into Dire Dawa's document (54 wagons became 59), reproduced
live on S-2026-00073.

marshallingDocumentAt now corrects the on-board list against the
adjustment log: a leg-slot wagon belongs on a stop's document only if
it has a logged ADD at or before that stop's own timestamp. Extracted
as wagonsAsOfStop so it's unit-testable without mocking the DB.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 09:38:53 +00:00
Hagernesh
80a057dde8 fix(train-scheduling): drop not-yet-boarded wagons from every marshalling doc
Leg-slot wagons planned to couple at a LATER stop were being counted
into the Wagons/Allocations/Total containers tiles on the ORIGIN
marshalling document (Import Load List, export load list) — inflating
the departing count from 54 to 64 on a real train, plus a 'TO BE
LOADED AT X' / 'TO LOAD AT X' row and a separate 'To load en route'
tally to work around it.

Filters those slots out of buildImportLoadListHtml / buildExportLoadListHtml
entirely instead: a wagon not part of the departing consist gets no
row and no count on this document, full stop. Its own coupling shows
up on THAT stop's own numbered marshalling document once it actually
happens (intercityOnBoardView already filtered correctly there,
unaffected). Deletes the now-dead pendingBoardYardLabelBySlot special-
casing, loadsHere guards, and the 'to load en route' tile.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-29 09:27:29 +00:00
marshal
abf856547a Merge pull request #1453 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-29 10:40:53 +03:00
Marshal
7e163088d9 fix issue, add transit flow, fix cancellation 2026-08-28 22:13:49 +00:00
Hagernesh
3f4fd8648a feat(import-operations): bulk Excel upload for yard-resident empty containers
Empties already sitting in an EDR yard but never entered in the system had
to be typed one at a time. Adds a bulk path: parse the sheet in the browser
(all-or-nothing, row-numbered errors), preview it, then POST one batch.

The server rejects the batch if any container already has a non-COMPLETED
return, so re-uploading the same sheet cannot duplicate boxes. No interchange
notification fires — these are historical rows, not a live handover.

Company is an Autocomplete over registered customers that also accepts a
typed name, since a backfilled box may belong to a company that is not a
customer yet. Exact name match sets customer_id; the name always lands in the
new empty_container_returns.company_name.

Also fixes the single Record Return modal, which collected Yard and Zone and
then dropped them before the API call, and did not invalidate the returns
list after a standalone return.
2026-08-28 11:38:19 +00:00
Hagernesh
9cd29a21ed feat(train-scheduling): log leg-slot board/alight events at checkpoints
Leg slots (stampSlotLegs — bookings boarding/alighting mid-corridor)
reaching their board/alight yard produced no ScheduleWagonAdjustmentLog
row, unlike planned couples/cuts. Without it the marshalling document
has no way to show a wagon coupling in already loaded, or uncoupling
with cargo, at a mid-corridor stop.

recordCheckpoint now logs ADD at the board yard and REMOVE at the
alight yard for these slots, deduped against existing rows since
passedYardIds re-includes earlier stops on every checkpoint call.
Purely observational — the physical wagon was already pinned to the
slot at schedule-build time, so no wagon/consist state changes.

Stage 3 of the multi-stop marshalling plan (per-event numbered docs);
stages 4-6 (generalized doc builder, endpoints, UI) still open.
2026-08-28 11:16:46 +00:00
marshal
b33e70d85b Merge pull request #1437 from Tria-plc/freight_feature/usermanagement
fix issues
2026-08-28 13:35:20 +03:00
Marshal
3015de7508 fix issues 2026-08-28 10:34:02 +00:00
marshal
081f66fb82 Merge pull request #1434 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-28 10:34:31 +03:00
Marshal
ba56974e32 feat(train): enhance train history and scheduling features
- Added a reason field to train history entries for detach/maintenance actions.
- Updated TrainHistoryPanel to display the reason for wagon detachments.
- Introduced per-wagon load/unload functionality in ScheduleWorkspacePanel with a modal for managing individual wagons.
- Implemented API endpoints for loading and unloading specific wagons, including the ability to cancel remaining wagons with a reason.
- Refactored detach request handling in TrainBuilderDetailPage to streamline the process and remove the approval flow, requiring a reason for detachments.
- Updated types and services to support new wagon loading/unloading features and booking wagon retrieval.
2026-08-28 07:33:28 +00:00
Nathnael Wondisha
a3b29b2792 Merge pull request #1422 from Tria-plc/freight_feature/usermanagement
feat: refine loading window validation and improve error messaging fo…
2026-08-27 08:26:44 +03:00
Marshal
d9017df730 feat: refine loading window validation and improve error messaging for dispatching 2026-08-27 03:26:44 +00:00
marshal
3f353e52b8 Merge pull request #1420 from Tria-plc/freight_feature/usermanagement
feat: enhance station work logging with user display names and improv…
2026-08-27 05:30:58 +03:00
Marshal
6ec3c8c5e0 feat: enhance station work logging with user display names and improve loading/unloading logic 2026-08-27 02:29:50 +00:00
Hagernesh
42ae6b9752 feat(train-scheduling): show coupled/uncoupled wagons on intercity marshalling doc
Marshalling 2 rendered only the final consist after a mid-corridor
adjustScheduleConsist call, with no signal that anything changed.
Reuses the existing ScheduleWagonAdjustmentLog (already recording
every ADD/REMOVE/SWITCH) filtered to the printed stop's yard and to
ADD/SWITCH, and prints a Consist changed at this stop box. Origin
import/export docs are untouched — the option is only passed from
intercityMarshallingDocument.
2026-08-26 19:00:43 +00:00
Hagernesh
69062389c7 fix(train-scheduling): marshalling docs respect mid-corridor wagon coupling
Origin marshalling (import + export) now prints leg slots as
TO BE LOADED AT <board yard> with board/alight stations and keeps
their containers out of the loaded tallies. Intercity Marshalling 2 no
longer hides whole-route cargo whose allocation never left PLANNED
(import flow confirms loading at schedule level), so the on-board view
matches the physical consist before and after mid-corridor coupling.
2026-08-26 08:30:38 +00:00
marshal
bcc5daa137 Merge pull request #1415 from Tria-plc/freight_feature/usermanagement
feat: implement MANUAL_ONLY status for bookings and update related logic
2026-08-26 01:02:18 +03:00
Marshal
29371b0b39 feat: implement MANUAL_ONLY status for bookings and update related logic 2026-08-25 22:01:03 +00:00
marshal
1459e646f6 Merge pull request #1414 from Tria-plc/freight_feature/usermanagement
feat: enhance train scheduling and contract management features
2026-08-26 00:46:17 +03:00
Marshal
b926a3116e feat: enhance train scheduling and contract management features
- Added StationWorkControls to manage loading/unloading phases in TrainScheduleV2DetailPage.
- Implemented API endpoints for recording station work and managing wagon detach requests.
- Updated contract templates to include Ethiopian customs handling options.
- Enhanced shipment forms to collect customs clearing agent details for without-customs bookings.
- Introduced NUMBER_OF_WAGONS as a unit of measure for bulk cargo, allowing customers to specify wagon counts.
- Improved validation for customs clearing agent information in shipment forms.
- Updated various components and services to accommodate new features and ensure data integrity.
2026-08-25 21:44:21 +00:00
marshal
a4e9466915 Merge pull request #1412 from Tria-plc/freight_feature/usermanagement
feat: enhance booking and audit log functionalities
2026-08-25 02:50:34 +03:00
Marshal
d5a5085d6d feat: enhance booking and audit log functionalities
- Implemented read-only locking for customer-requested container sizes and billing currency in the GlCreateBookingForm component.
- Added functionality to lock partner quantities based on shipment requests in the ConsolidationPartnerPanel.
- Introduced a new Leave action in the LogPassYardWorkModal to unassign bookings from trains.
- Enhanced the AuditLogsPage to support filtering by action and added a Go button for direct navigation to entity detail pages.
- Updated WagonCancellationsPage to handle odd-20ft credits requiring partner selection during rebooking.
- Improved TrainScheduleV2DetailPage to allow manual loading of cargo and display warnings for unassigned bookings.
- Added a new reference field to the audit logs for better searchability and tracking of actions.
- Created a migration to add the reference column to the audit logs table and established an index for efficient querying.
- Defined a registry for audit reference sources to streamline the retrieval of human identifiers for various entities.
2026-08-24 23:49:20 +00:00
Nathnael
17c2dca3cc feat(reports): record loading and unloading time per stop
The OCC report publishes total loading and unloading time and the other
activity left over from a station stay, but nothing recorded when handling
started or ended — the July 2026 seed had to write the figure into a
checkpoint note. Four nullable stamps now ride the stop's arrival row, which
is the row the staying-time report builds a stay from (a turnaround's
departure belongs to a different schedule).

Handling is unloading start to loading end, so a container stop reads as one
window and a bulk station that only loads or only unloads still reports its
half; other activity is the rest of the stay. Both stay NULL where nothing
was logged rather than collapsing to zero.

- station-staying-time: + loading/unloading and other activity per stop
- turnaround-cycle: + the same, summed over the cycle's stops
- loading-unloading (new): per train per station per period, so a week or
  month view is that train's average over its stops
- the stop/stay query moves to operations-classification, shared by both
2026-08-24 12:09:04 +00:00
Marshal
e2189040fa feat: add pagination to schedule history and consolidation approvals
- Implemented pagination in ScheduleHistoryPanel to manage large history entries.
- Updated API to support pagination parameters for schedule history.
- Enhanced ConsolidationApprovalsPage with tabbed navigation and pagination for approval rows.
- Introduced new types for paginated responses in bookings and train scheduling services.
- Added a database migration to create an index on wagon_booking_allocations for performance improvements.
2026-08-23 04:49:58 +00:00
Marshal
8e6fc09aac feat(train-scheduling): mid-route consist changes, audit history, safer workspace
- planned couples: loose wagons join the train at a route stop, added
  from the schedule yards tab; capacity credits them per corridor edge
  and coupling validates locomotive weight/length caps per leg
- real-cut toggle: a cut wagon permanently leaves the train build at
  its cut yard (soft cut still sits out one trip only)
- fix heaviest-leg display counting a shared slot's full cargo on
  every spanned edge (phantom pull-weight overload on S-2026-00045)
- confirmation dialogs for workspace add/load/unload/remove actions
- train-builder History and Detached-wagons tabs, backed by paginated
  endpoints; builder detaches now always write adjustment-log rows

Migrations 3660 (planned_wagon_couples, planned_wagon_real_cuts) and
3670 (adjustment log train_schedule_id nullable) — both applied to the
dev DB by hand; watch mode does not run migrations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 03:55:54 +00:00
Marshal
1ab2cfdb3b fix issue 2026-08-22 01:23:50 +00:00
Marshal
b6c1efa043 fix issue 2026-08-22 00:49:53 +00:00
Marshal
bad418d79e changes 2026-08-22 00:09:00 +00:00
Marshal
09deecd04c fix issue and add consolidation 2026-08-21 23:16:06 +00:00
Marshal
4c549029fe feat(clearance): preview charge documents before and after upload 2026-08-21 07:04:22 +00:00
Marshal
d99b294c21 fix issue 2026-08-20 18:10:29 +00:00
Marshal
9e1d5ee9f2 [200~feat: add CustomsPaymentsCard and PaymentsTab components for handling customs payments and payment summaries 2026-08-20 15:45:42 +00:00
Nathnael
2ec818e590 Merge branch 'dev' into freight/nati-2
# Conflicts:
#	apps/edr-freight-api/src/app.module.ts
#	apps/edr-freight-api/src/seed/freight-permissions.registry.ts
#	apps/edr-freight-web/backoffice/src/components/layout/sidebar-sections.tsx
#	apps/edr-freight-web/backoffice/src/constants/URLS.ts
#	apps/edr-freight-web/backoffice/src/lib/permissions.ts
2026-08-20 11:33:19 +00:00
Nathnael
7446adaa88 feat(api): accept several yards on each end of a route filter
Bookings, contracts and train schedules all validated originYardId /
destinationYardId (originStationId / destinationStationId) as a single
@IsUUID and matched with `=`, so a list could be narrowed to exactly one
lane. The filter bar can now ask for several stations per end, and each
end independently, which needs the same on the server.

@IdListParam() is the shared transform: one id, a comma-separated list,
or a repeated query param, always landing as a string[]. It yields
undefined rather than [] when nothing usable is left — a repository that
branches on `?.length` can then never hand TypeORM an empty array, which
compiles to the syntax error IN (). It stays backwards compatible with
the single-value form, so existing deep links and saved views are
unaffected.

Matching moves to IN (:...ids) — for contracts inside the two existing
EXISTS subqueries, which keeps meaning "has a route from one of these
origins" AND "has a route to one of these destinations", not necessarily
the same route. All three statements were EXPLAIN-validated against
edr_dev.
2026-08-20 11:24:46 +00:00
Marshal
c723b660e2 feat(freight): offer built-train wagons per boarding yard on multi-yard consists 2026-08-18 08:27:18 +00:00
Marshal
0e228bfd8d changes 2026-08-17 06:14:25 +00:00
Marshal
5ce5cbe29d feat: enhance booking and scheduling features with shipping line support and improved search functionality 2026-08-16 08:18:40 +00:00