Commit Graph

24 Commits

Author SHA1 Message Date
Hagernesh
5395d4f346 Customer Name + Customer ID columns removed from the Export Marshalling Document 2026-07-22 08:01:15 +00:00
Hagernesh
19906b273e fix(operations): prefill booking context on single assign; enforce per-truck container loads
- single-row Assign vehicle uses the full single-record flow (details + containers)
- release() rejects exit containers not assigned to the departing truck
- weighing modal offers only the selected truck's assigned containers
2026-07-22 07:24:14 +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
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
Hagernesh
7e934b3433 feat(warehouse,last-mile): truck load size rule, dedup last-mile, driver-required + arrival prefill
Truck loading:
- loadTruck enforces max 2 containers / one 40ft (two 20ft) and auto-marks an
  assigned truck arrived on load; container-items payload + modal expose
  container size with a client-side selection cap.
- Show "#x containers pending assignment" in the portal truck card and the
  backoffice container modal.

Last-mile:
- create() is idempotent — return the existing record for a booking instead of
  inserting a duplicate delivery row (fixed the same booking showing twice in
  Assign-Mile).
- setVehicles/update reject a truck with no assigned driver; the Assign toast
  now surfaces the reason.
- New GET /last-mile/booking/:id/arrival-trucks returns assigned EDR trucks with
  driver details; ReleaseOrderModal fetches and auto-fills them so an assigned
  EDR truck no longer reads as "not assigned yet".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:16:45 +00:00
Hagernesh
9d147fbe26 fix(warehouses): truck-arrival crash on duplicate containers; auto-GRN on import unload
Truck Arrival died with "[@mantine/core] Duplicate options are not supported"
when a booking carried the same container number on two container lines (the
unit uniqueness is per line, not per booking):
- bookingContainerWeights now GROUPs BY container number (MAX weight)
- the weighing modal dedupes both the containers MultiSelect and the
  assigned-trucks Select defensively, so bad data degrades instead of
  crashing the whole page

Import GRN is now issued automatically when the arrived train is unloaded:
autoUnloadArrivedBookings stamps GRN-IMPORT-<date>-<booking> on both the
create and update paths (never overwrites an existing GRN). The per-row GRN
button in the import queue lights up with no extra clicks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 11:13:21 +00:00
Hagernesh
9ef390ef1e fix(warehouses): truck weighing modal resolves bookingId without the relation
The modal read the booking id only from item.booking?.id, but inventory-
workbench rows carry bookingId without the booking relation. Result: the
container-weights and assigned-trucks queries never ran, so "Recorded net
weight (system)" fell back to the inventory row's weight (often 0), the
container MultiSelect never appeared, and the truck dropdown showed
"not assigned" even when trucks existed - while the server correctly computed
the cargo weight and rejected the mismatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 08:34:14 +00:00
Hagernesh
7ab5e9edd5 feat(warehouses): handover-driven approve delivery, weigh-skip, 5-min sign reminders
Approve delivery now tracks the handover lifecycle exactly: the button appears
(detail page + portal dashboard) the moment a handover is generated and
disappears when the customer signs. The bookings list attaches the
handoverAwaitingSignature flag via one batched query per page; status
heuristics (COMPLETED / TRUCK_ASSIGNED+arrived) are gone.

- generate the arrival handover for ANY self-haul truck: portal-assigned OR
  walk-in registered at the gate (isSelfHaulBooking: assigned_at set, or no
  EDR last-mile leg). Same rule now guards the exit paper.
- remind every 5 minutes (in-app + SMS + email) until the handover is signed
  (@Cron in HandoverService; one reminder per booking per tick)
- Truck Leaving no longer opens blank: the import queue mapper now carries
  inv.notes, so the saved arrival renders read-only with only gate-out time
  and gross weight editable
- container bookings get "Weigh truck? Yes/No": No skips tare/gross and the
  container weight match (weighingSkipped on ReleaseOrderDto, decision made at
  arrival sticks for the exit via the Weighing: SKIPPED note). Bulk always
  weighs, unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 15:37:06 +00:00
Hagernesh
33956d07dc Fix customer_truck_containers status 2026-07-08 13:56:56 +00:00
Hagernesh
80904eeeb2 Handover SIGN notification, resending until signed no exit before sign 2026-07-08 09:33:19 +00:00
Hagernesh
3f6b9ac974 Container truck assignment on customer portal for import 2026-07-08 04:36:03 +00:00
Hagernesh
fe9503638b separte handover edr lastmile and customer last mile flow 2026-07-06 12:27:58 +00:00
hagiye
ad9f9de7a8 Truck Assign by customer plus Handover signature on portal 2026-07-02 12:32:18 +03:00
hagiye
129448e437 frist mile receive to warehouse and last mile truck arrival integration 2026-07-02 01:08:37 +03:00
hagiye
14a00af341 train gate pass, Telebirr and Wafi 2026-07-01 16:23:52 +03:00
hagiye
9f5c22c1ee Goods recieved notes and Booking delivery 2026-06-30 07:19:12 +03:00
hagiye
d55f9312bf Marshaling document Receive Export and import handover to customer 2026-06-29 12:24:14 +03:00
hagiye
d726927453 Notification for demurrage and invoice fee 2026-06-27 05:33:58 +03:00
hagiye
c69dd3c238 Release Order plus Storage fee 2026-06-24 15:23:50 +03:00
hagiye
8ee31789c6 merge conflict fix 2026-06-24 12:31:59 +03:00
hagiye
0255adffe6 changes 2026-06-24 09:56:12 +03:00
Nathnael
d66ccc5363 refactor: migrated of the customer hooks for warehouse data fetching 2026-06-22 12:25:20 +00:00
Hagernesh
e40318c847 Dashboard enhancement 2026-06-19 11:29:05 +00:00
natib21
b4ed7d492d fix vehicle 2026-06-19 06:56:07 +00:00