Commit Graph

947 Commits

Author SHA1 Message Date
marshal
ca8a7602ef Merge pull request #876 from Tria-plc/freight_feature/usermanagement
changes
2026-07-21 15:15:19 +03:00
Marshal
07c390a3b2 changes 2026-07-21 12:14:47 +00:00
Hagernesh
1fae0752a0 Ticket: Warehouse dashboard Needs Attention cards — fix trucks-on-site aging counters (EDR trucks, UNLOADED status) and make each card open the exact list behind its count via new inventory drill-down filters. 2026-07-21 11:03:40 +00:00
Hagernesh
b616f520ae feat(fleet): validate vehicle plate numbers against a letters-and-digits format
Plate, power-plate and trailer accepted any free text — a vehicle could be
saved with a plate of "assadasd". They must be letters, a hyphen, then digits,
like ET-9875 or AA-8642.

The server now enforces it on CreateVehicleDto (and UpdateVehicleDto via
PartialType): each plate is trimmed and upper-cased, then matched against
^[A-Z]{2,3}-\d{2,6}$, so "et-9875" is accepted and stored as ET-9875 while an
empty optional trailer/power plate still passes.

The fleet form gains the same check inline: FleetFormFieldDef takes an optional
pattern, the dialog tests it on submit against the upper-cased value, and the
vehicle config points plate and trailer at a regex that mirrors the server's.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 11:03:40 +00:00
Marshal
9ca4075c1e Implement intercity document handling and rejection notes for contracts 2026-07-21 10:39:21 +00:00
Marshal
6f8456631c Implement intercity document handling and rejection notes for contracts 2026-07-21 10:20:36 +00:00
Marshal
ceb32e0a80 Implement intercity document handling and rejection notes for contracts 2026-07-21 10:15:18 +00:00
Hagernesh
92a0cc197b feat(fleet): make the dashboard stat cards link to their detail
The four headline cards — total vehicles, drivers, fuel spend, maintenance —
were static numbers with no way through to the list behind them. Each now takes
an optional href and, when set, wraps in a link to its detail page (vehicles,
drivers, fuel purchases, maintenance). A card without an href stays exactly as
before. The Card is wrapped rather than turned into a link so Mantine's Card
typing stays clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:22:47 +00:00
Hagernesh
64a4bcbd5c feat(warehouse): make the ops KPI cards link to their detail
The dashboard counters were static — "Trucks on-site" showed a number with no
way to open the list behind it, same for the others. KpiStrip now takes an
optional href per item: a cell with one becomes a link (pointer, hover tint,
aria-label) and a cell without one stays exactly as before, so every existing
strip is unaffected.

The warehouse ops strip wires each card to its detail: trucks on-site to the
Trucks on Site page, received-today and pending-inspection to the inventory
board filtered to RECEIVED, items-aging to the inventory board.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:22:46 +00:00
Marshal
603537a20b add yard distances management to rule engine
- 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.
2026-07-21 08:50:50 +00:00
Hagernesh
2397c6bca4 fix(warehouse): show assigned trucks on the Trucks on Site page, not only arrived ones
The page filtered on arrived_at IS NOT NULL, so a truck appeared only once the
warehouse receive flow stamped its arrival. Assigned trucks that had not yet
reached the yard were invisible, which left the page empty whenever nothing had
been received — every assigned truck was missing.

It now lists every truck assigned to a booking that has not departed, from both
haulage paths, tagged INBOUND (assigned, not yet arrived) or ON_SITE (arrived).
A scope toggle filters between them, dwell time shows only once a truck has
actually arrived, and the KPI count on the dashboard stays strict (arrived only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 08:24:39 +00:00
Nathnael
af171974f8 Merge branch 'dev' into freight/feat/fixes-v1 2026-07-21 07:36:09 +00:00
Nathnael
fd5aedcec7 feat(companies): per-document change requests and resubmission review queue
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.
2026-07-21 07:34:40 +00:00
Hagernesh
36f0045b5d auto generate grn on import arrival unloading 2026-07-21 07:25:45 +00:00
marshal
db466a6b27 Merge pull request #861 from Tria-plc/freight_feature/usermanagement
Update IntercityCapacity to allow null values and handle formatting i…
2026-07-21 09:50:49 +03:00
Marshal
1647681840 Update IntercityCapacity to allow null values and handle formatting in CapacityBadges 2026-07-21 06:46:25 +00:00
marshal
370aa09c65 Merge pull request #853 from Tria-plc/freight_feature/usermanagement
changes
2026-07-20 22:44:22 +03:00
marshalyordanos
15705d6b26 changes 2026-07-20 22:43:22 +03:00
marshal
92375caa59 Merge pull request #852 from Tria-plc/freight_feature/usermanagement
Fix CSS formatting for bookings table class to ensure proper styling …
2026-07-20 22:35:50 +03:00
marshalyordanos
8e74604a07 Fix CSS formatting for bookings table class to ensure proper styling and layout. 2026-07-20 22:35:01 +03:00
marshal
d3324bc580 Merge pull request #850 from Tria-plc/freight_feature/usermanagement
Enhance BookingRequestsPage layout and styling
2026-07-20 22:11:14 +03:00
marshalyordanos
8aaccf3f36 Enhance BookingRequestsPage layout and styling 2026-07-20 22:10:48 +03:00
marshal
0a73b8edb5 Merge pull request #847 from Tria-plc/freight_feature/usermanagement
chnages
2026-07-20 20:52:57 +03:00
Marshal
26f73cbe5f chnages 2026-07-20 13:55:26 +00:00
Hagernesh
7b777792e3 feat(warehouse): expand an inventory row to see which containers ride which truck
The inventory table has one row per inventory item, so on a self-haul booking
with several trucks there was no way to tell which container sat on which
truck without opening a document. The plate column now lists every plate, but
not the mapping.

Each row with a customer truck gets a chevron that opens a per-truck
breakdown: plate, driver, type, the containers it carries, and whether it has
arrived. Bulk trucks show "Bulk" — they haul loose tonnage, not containers.

The breakdown fetches only when opened, so a table nobody expands costs no
extra requests, and it reuses the existing per-booking trucks endpoint rather
than widening the inventory query.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 12:54:10 +00:00
Hagernesh
0c0de284b0 feat(warehouse): show the trucks in the yard, not just a count of them
Multi-truck self-haul had no list anywhere on the warehouse side. The ops
dashboard counted trucks on site and offered no way to open the list, and
the inventory table showed a blank plate on exactly the bookings that have
several trucks: it read booking.customer_truck_plate_number, which
multi-truck self-haul leaves null because plates live in
customer_truck_assignments. Booking BK-2026-000033 has a truck and a driver
on file and displayed neither.

Adds a Trucks on Site page listing every truck that has arrived and not yet
departed, across bookings, with plate, driver, booking, customer, containers
and dwell time. It covers both haulage paths because the gate does — a
customer's own truck and an EDR last-mile truck reach the same barrier — and
flags anything sitting over four hours. It lives under Warehouse Management
rather than Imports or Exports, since the yard is not per-direction.

The inventory queries now read plates and drivers from the assignments and
keep the booking columns as the fallback for single-truck bookings written
before that table existed.

Both new statements were EXPLAIN-validated against the live schema; the
plate fix returns the data that was previously null.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 12:54:10 +00:00
marshal
b9b2075207 Merge pull request #837 from Tria-plc/freight_feature/usermanagement
contrat nad booking modification
2026-07-20 15:25:51 +03:00
Marshal
b90afadfba contrat nad booking modification 2026-07-20 12:24:58 +00:00
Nathnael
804c72f14a Merge branch 'dev' into freight/feat/fixes-v1 2026-07-20 12:12:30 +00:00
Nathnael
0549a88d57 feat: otp double sending 2026-07-20 12:10:49 +00:00
Nathnael
aa02700e4c fix: disable global errors 2026-07-20 11:52:08 +00:00
Hagernesh
c8a70593cf fix(mile): apply one truck-load rule to customer and EDR haulage alike
A truck holds one 40ft or two 20ft, a container booking takes no more trucks
than it has containers, and a bulk booking takes trucks until its tonnage is
hauled away. The same physics whoever drives, but the rule was written out
four times — addTruck, updateTruck, departTruck and LastMileService — beside
a byte-identical container-size query. Copies drift: that is how the
self-haul guard ended up enforced on one side only.

The bulk cap was the real gap. EDR summed net_weight_tons of departed trucks
and refused another once the booking was drawn down. The customer side had
no cap at all: for bulk it skipped straight past every check, so a self-haul
bulk booking could take unlimited trucks.

It could not simply reuse the EDR sum. customer_truck_assignments had no net
and no tare, only a gross_weight_kg that holds tonnes despite its name and
that nothing in the live flow ever wrote — release() recorded exit weights
against the EDR table alone, which is why all five customer trucks on dev
have neither weight nor departure. Any drawdown keyed on it would have
summed zero forever and never fired.

So the customer table now carries tare_weight_tons and net_weight_tons to
match the EDR one, release() records the customer truck's exit as it already
did for EDR, and the drawdown counts both sources — a booking hauls by one
path or the other and "until no tonnage is left" means the same either way.

Also locks a load once its truck has arrived on the EDR side, which the
customer side has always done, and fills the arrival form from the customer
truck on file: the prefill read booking.customer_truck_*, which multi-truck
self-haul leaves null, so a booking with a truck assigned opened blank.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 11:41:57 +00:00
Marshal
540f4a1ff6 changes 2026-07-20 11:41:57 +00:00
Marshal
0727de0f4d Refactor clearance terminology to document approval across services and UI components 2026-07-20 11:41:57 +00:00
Nathnael
6cb921e617 fix: 194 and 183 plane takss 2026-07-20 11:41:57 +00:00
Nathnael
ccd9afacb1 feat: setup forget password to the backoffice 2026-07-20 11:41:57 +00:00
Nathnael
9fbe1c5236 feat: setup attachment to the freight chat 2026-07-20 11:41:57 +00:00
Nathnael
6420c72e89 feat(auth): implement staff-triggered password-reset links 2026-07-20 11:20:50 +00:00
Marshal
eb532399d9 changes 2026-07-20 10:52:20 +00:00
Nathnael Wondisha
bed1208dee Merge pull request #833 from Tria-plc/freight/feat/fixes-v1
Freight/feat/fixes v1
2026-07-20 11:26:30 +03:00
Nathnael Wondisha
f41463748d Merge pull request #788 from Tria-plc/freight/feat/chat-app
Freight/feat/chat app added attachment
2026-07-20 11:23:16 +03:00
Nathnael
2c7a4b7112 Merge branch 'dev' into freight/feat/fixes-v1 2026-07-20 08:20:34 +00:00
Marshal
e22b336e8c Refactor clearance terminology to document approval across services and UI components 2026-07-20 07:46:38 +00:00
Nathnael
c7195f077a fix: 194 and 183 plane takss 2026-07-20 07:41:25 +00:00
Hagernesh
536d6043c2 fix(clearance): allow customs risk to be corrected and keep the trail
RiskStep returned early to a badge as soon as a risk level existed, so the
control was unreachable and a mis-assigned level could never be corrected.
Both the server and the sibling AssignRiskCard treat risk as correctable
until duty is advised off it — completeWithMetadata has no already-completed
guard and overwrites metadata.riskLevel. RiskStep was stricter than either.

It now keeps the control mounted alongside the assigned badge, offers
"Reassign risk", and locks to badge-only once DUTY_TAXES_ADVISED completes.
The control also reads the persisted level (it was hardcoded to GREEN, so
unhiding it alone would have misreported the assignment), and the T1 gate is
skipped once a level exists, since risk cannot be assigned without a closed
T1 and stale T1 data must not hide the badge.

Correcting a level previously left no record of the old value, who changed
it, or when — thin ground for a customer-visible level that may be disputed.
assignRisk now appends each decision to metadata.riskHistory: the level, the
level it replaced, the timestamp, the user id, and a display name resolved
at assignment time so the trail shows a person rather than a UUID. riskLevel
still carries the current value and always equals the last entry, so
existing consumers are unchanged.

History lives on the existing metadata JSONB column, so no migration is
needed, and the logic sits in assignRisk rather than the shared
completeWithMetadata that adviseDuty and others also use. Re-picking the
level already in force is not recorded — it changed nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 07:13:52 +00:00
Hagernesh
a5973de6e1 feat(intercity): a facility only handles the cargo its equipment can lift
Containers need a reach stacker or gantry, so only Indode, Modjo and Dire Dawa
take them. Bulk needs far less and is handled at all five facilities. Having a
facility was previously enough to load anything, so a container booking through
Sebeta or Adama would have been accepted and then had nothing to lift it.

- yard_facilities gains handles_container / handles_bulk, both defaulting true so
  a facility handles everything unless told otherwise; the seeder states the real
  capability.
- The intercity gate now refuses cargo a facility cannot lift, saying which type,
  not just "no facility". canHandleFreight keeps that rule in the resolver so
  callers cannot get it subtly wrong.
- The intercity list resolves each end against the booking's own freight type, so
  the view flags a container booking routed through a bulk-only yard while the
  train is still coming rather than when the load is refused.

Import/export untouched — the gate is still DOMESTIC-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 07:13:51 +00:00
Marshal
771aa2a605 Add train deactivation feature and import train number management
- Introduced DEACTIVATED status for trains, allowing staff to park trains indefinitely.
- Implemented methods to deactivate and reactivate trains in the TrainBuilderService.
- Added UI components for train deactivation and reactivation in TrainBuilderDetailPage.
- Created a dropdown setting for admin-managed import train numbers, with corresponding migrations.
- Updated yard code length to accommodate soft-delete suffix.
- Enhanced train status handling to include DEACTIVATED state.
2026-07-20 07:04:23 +00:00
Nathnael
3d4996e4df feat: setup forget password to the backoffice 2026-07-20 06:19:12 +00:00
marshal
f672d66a92 Merge pull request #826 from Tria-plc/freight_feature/usermanagement
changes
2026-07-20 06:06:06 +03:00
Marshal
4969f62896 changes 2026-07-20 03:05:28 +00:00