Commit Graph

4946 Commits

Author SHA1 Message Date
Hagernesh Tadesse
cde346af57 Merge pull request #1410 from Tria-plc/credit-invoice
feat(eims): derive sales receipt fields from recorded invoice payment
2026-08-24 16:21:38 +03:00
Hagernesh
565265af79 feat(eims): derive sales receipt fields from recorded invoice payment 2026-08-24 13:04:03 +00:00
marshal
6da8adc6e9 Merge pull request #1409 from Tria-plc/freight_feature/usermanagement
fix issue -> consolidation
2026-08-24 15:51:12 +03:00
Marshal
2a107e8ba3 fix issue -> consolidation 2026-08-24 12:24:23 +00:00
Hagernesh Tadesse
377ab136a5 Merge pull request #1408 from Tria-plc/credit-invoice
feat(eims): import MoR location master and fix importer arg parsing
2026-08-24 12:12:56 +03:00
Hagernesh
c9a68570e4 feat(eims): import MoR location master and fix importer arg parsing 2026-08-24 09:08:34 +00:00
Nathnael Wondisha
f579438483 Merge pull request #1407 from Tria-plc/freight/nati-2
Freight/nati 2
2026-08-24 12:04:30 +03:00
Nathnael
2286135228 feat(reports): add port warehouse operations summary
Reproduces the monthly count sheet a port warehouse publishes: trains,
containers by size and laden state, wagons, TEU and bulk wagons per cargo
type, each split into export and import beside an overall total.

Two departures from the spreadsheet it replaces:

- Wagons are counted distinctly from the marshalling record rather than
  derived as 20ft/2 + 40ft + bulk wagons, which overstates whenever a wagon
  ran part-loaded.
- Total is counted over everything rather than summed across the direction
  columns — a train carrying both an import and an export booking belongs to
  both and would otherwise count twice.

Demurrage is billed on invoice lines and is left to Revenue by Category.

Adds a station filter matching either end of the corridor, so one warehouse
can report the trains it worked in both directions.
2026-08-24 08:58:58 +00:00
Nathnael
ee2caa332c Merge branch 'dev' into freight/nati-2 2026-08-24 08:38:37 +00:00
Nathnael
eba09c73ae fix: locomotive filtering 2026-08-24 08:21:29 +00:00
Nathnael
2e5dadeee9 fix(reports): apply the trade scope to six unscoped reports
These reports resolved ctx.directions and never read it, so a user restricted
to one trade direction saw every row, and a user with no trade access — where
directions is [] and the rule is show nothing — saw all of them.

first-last-mile-bookings scopes on the booking's own direction; the other five
scope on ts.direction. global-logistics-wagons uses the fragment form so a log
row whose schedule is gone stays visible, which is the rule the other ledgers
apply to rows carrying no direction.

Also adds the missing soft-delete guards: b.deleted_at on the first/last mile
booking join, ts.deleted_at on the wagon-teu-utilization and
global-logistics-wagons schedule joins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 08:01:20 +00:00
Nathnael
b7f8a436fb fix(reports): filter the plan side of plan-versus-actual reports
The cargo filter was applied only to the operated and attainment subqueries.
The plan side selected targets by metric and dimension alone, and the FULL
OUTER JOIN put every filtered-out key back as a row of zeros —
?categories=FERTILIZER returned all ten planned categories.

planKeyFilter restricts targets to the selected categories (or container
classes), reading ot.cargo_category for a station plan and ot.dimension_key
otherwise. Values are whitelisted against the vocabulary and inlined, because
the fragment is assembled into raw CTE text and the runner does not validate
multiselect values.

Two related grain leaks close with it:

- planCountryFilter narrows a station plan to the chosen country. All seven
  station targets are Ethiopian, so the Djibouti view was listing 33 Ethiopian
  targets as stations that moved nothing.
- planGrainFilter drops the plan entirely when origin, destination, train
  number or direction is set. No target carries a route, so the plan there was
  the whole corridor's target sitting beside one slice of its work, and the
  implement rate read as a miss that never happened.

Fixes cargo-volume-performance, cargo-volume-by-station, trainset-performance
and teu-performance together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 08:01:12 +00:00
Nathnael
de407c0014 feat(reports): clamp report descriptions with a show more toggle
Report descriptions run to a paragraph. ReportDescription wraps Mantine's
Spoiler to clamp them to two lines, and the toggle only renders when the
text actually overflows.

PageHeader kept its subtitle on a hard truncate class, which would have
pinned the spoiler to one line, so a ReactNode subtitle now renders as-is
and owns its own layout. A string subtitle still truncates as before.
2026-08-24 07:54:36 +00:00
marshal
27b4191afe Merge pull request #1406 from Tria-plc/freight_feature/usermanagement
feat: enhance booking cancellation logic for consolidated pairs with …
2026-08-24 10:15:36 +03:00
Marshal
979f024869 feat: enhance booking cancellation logic for consolidated pairs with one paid side 2026-08-24 07:13:50 +00:00
Nathnael
baef14c847 style(reports): reformat revenue transactions with prettier
Whole-file requote to double quotes plus wrapped column literals. No
behaviour change.

Kept as its own commit because it is out of step with the rest of
reports/definitions, which is single-quoted: bare prettier ignores
@edr/prettier-config, so running it on one file requotes that file alone.
Drop this commit if the directory should stay consistent.
2026-08-24 07:12:51 +00:00
Nathnael
e8f46675dc feat(reports): add a total wagons column to charged vs actual volume
Loaded and empty wagons were both shown but never summed, so the train's
actual consist had to be added up by hand on every row. MAX() on the empty
count for the same reason the distance uses it: the value is constant within
a group that includes ts.id and the leg.
2026-08-24 07:12:40 +00:00
Nathnael
a3f06597cc feat(reports): break charged vs actual volume down by leg
The report priced every departure against its planned origin-to-destination
corridor, so a train that worked several station-to-station moves showed one
row and one distance. Ton/Km and Vehicle-Km were then computed against that
single corridor and understated the work actually done.

The row grain is now the leg: consecutive checkpoint events at different
yards, read with lead() over each schedule. DISTINCT because a train that
works the same pair twice in one departure is still one leg — without it the
join fans the cargo out and doubles every SUM in the group. Both ends fall
back to the schedule's own corridor, so a departure with no checkpoints
logged keeps exactly the single row it had before.

Only query() joins the legs. The KPIs stay corridor-level and would count the
same cargo once per leg if they had that join.
2026-08-24 07:12:32 +00:00
Nathnael
cdb2f234c3 feat(reports): drop the raw booking ID from revenue transactions
The bare UUID column sat next to the booking reference it duplicates, and a
reference is what anyone reading or exporting this report actually quotes. The
report is the audit trail for an export, so a column nobody can act on is
weight in every downloaded file.
2026-08-24 07:12:17 +00:00
Nathnael
2be1876460 feat(reports): carry time of day on report date columns
Eleven report columns bucketed their timestamp to a bare day with to_char,
which is wrong for anything a user reads as an event rather than a period:
two departures on the same date, or a wagon request fulfilled hours after it
was raised, were indistinguishable in the output.

The renderer only shows the time when the value actually has one, keyed off
the string rather than a per-column flag — a genuine day bucket would
otherwise render as 12:00 AM, which reads as data rather than as absence.
2026-08-24 07:12:08 +00:00
Hagernesh Tadesse
ccc16f8f0a Merge pull request #1405 from Tria-plc/credit-invoice
feat(eims): resolve buyer geography from the MoR location master
2026-08-24 10:09:19 +03:00
Nathnael
c3894462e7 feat(billing): search invoices by PNR and transaction ref
Both are numbers a customer or a provider support desk quotes back, so they
belong in the free-text box rather than behind a filter pill.

The transaction id and merchant order id are plain ORs — the payment alias is
already joined by every caller of applyInvoiceFilters. The PNR folds into the
existing booking EXISTS block instead of adding a second subquery, so it
inherits that block's correlation and also matches warehouse-, first-mile-
and last-mile-sourced invoices, not just booking-sourced ones.

bk is promoted to alwaysJoin now that the export's scope() references it.
2026-08-24 07:03:08 +00:00
Nathnael
3da00e1f06 feat(billing): show the booking PNR on an invoice
The PNR is the CBE_BILL reference the customer actually pays against, but it
is stamped onto the booking at payment-initiation time — it is a column on
neither the invoice nor the payment. Both surfaces read it back by source id,
the same lookup the sealed invoice PDF already did, so screen, export and
document now agree.

The export's join casts bk.id::text rather than i.source_id::uuid: source_id
is a bare varchar pointer that is not always a UUID (EIMS self-test rows
carry a slug), and casting that direction throws on those rows.
2026-08-24 07:02:46 +00:00
Nathnael
018505d6fa feat(billing): filter, show and export invoice payment method
The settled method is split across two stores: a gateway settlement records
the real provider on the linked freight.payments row (cbe-bill, telebirr)
while the invoice's own payments ledger only writes a flat "GATEWAY"; a
manual settlement has no payments row at all and the ledger is the only
source (BANK_TRANSFER, OFFLINE, or whatever PayInvoiceDto.method carried).

invoicePaymentMethodExpr folds both into one UPPER_SNAKE vocabulary —
provider first, newest ledger entry as the fallback — and the list filter,
the export field and the export filter all use that same expression, so the
screen and the file can never disagree.

The paymentMethods param is deliberately not validated against a fixed list:
the manual pay endpoint takes a free-form method, so an IsIn would silently
drop real values.
2026-08-24 07:02:27 +00:00
Hagernesh
c937290019 feat(eims): resolve buyer geography from the MoR location master
BuyerDetails Country/Region/City/Wereda now resolve from the Ministry's own
EIMS_COUNTRY_REGION_VW master instead of the EIMS_BUYER_*_CODES env maps and
the ethiopia-geo-codes table. Both invented their codes and looked names up
globally, so KERSA/GORO/BABILE/BURE — each present in several zones with
different LOCALITY_NOs — could be filed against the wrong jurisdiction.

Resolution is hierarchical and refuses to guess: an unknown or ambiguous
address raises a local validation error naming the level that failed, and
never selects the first matching row. Spelling differences between EDR and
MoR live in a reviewed, parent-scoped alias layer; the dataset itself stays
verbatim so it remains traceable to the Ministry sheet.

Resolution now runs before the counter reservation in both the single and
bulk paths, so a bad company address no longer burns an EIMS sequence number.

Adds eims:import-locations to regenerate the dataset from a future workbook,
reporting duplicate rows and same-hierarchy code conflicts.
2026-08-24 06:59:50 +00:00
marshal
d285006114 Merge pull request #1402 from Tria-plc/freight_feature/usermanagement
add draft declaration
2026-08-23 22:03:22 +03:00
Marshal
31fa313c66 add draft declaration 2026-08-23 19:02:33 +00:00
marshal
74bca8bb5e Merge pull request #1400 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-23 08:01:23 +03:00
Marshal
58f88b74f8 add contract link 2026-08-23 05:00:43 +00:00
Marshal
716444e60a 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:51:34 +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
105879b531 Merge pull request #1399 from Tria-plc/freight_feature/usermanagement
feat(train-scheduling): mid-route consist changes, audit history, saf…
2026-08-23 06:59:27 +03: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
Hagernesh Tadesse
36b24a3a1b Merge pull request #1398 from Tria-plc/credit-invoice
Permission guard Load Unload
2026-08-22 12:24:13 +03:00
Hagernesh
7f5e8349da Intercity andd import export gating 2026-08-22 09:17:28 +00:00
Hagernesh
e426e0c16e feat(train-scheduling): dedicated load/unload permissions
Carves cargo load/unload confirmation out of the coarse
trainScheduling.update permission into its own guard
(TrainSchedulingLoad/TrainSchedulingUnload), covering import, export,
and intercity — the generic per-booking route already serves all
directions, and the intercity-specific route gets the same two keys.
Adds the catalog entries and grants them to operationsOfficer/director
alongside the existing .update grant so current access is unchanged.
2026-08-22 09:17:28 +00:00
Stephanos A.
50f442a414 Merge pull request #1397 from Tria-plc/alpha
Alpha
2026-08-22 11:21:04 +03:00
Stephanos A
1be2cadf0e Merge branch 'alpha' of github.com:Tria-plc/edr-platform into alpha 2026-08-22 11:18:30 +03:00
Stephanos A
81f7c0f0cd feat: coach utilization report with schedule filtering and export functionality 2026-08-22 11:17:58 +03:00
Abubeker Yasin
c6c4fcf0cf Merge pull request #1396 from Tria-plc/alpha
fix: ( passenger-portal ) fix payment amount on booking confirmation
2026-08-22 10:49:51 +03:00
Abubeker Yasin
3d741ab928 fix: ( passenger-portal ) fix payment amount on booking confirmation 2026-08-22 10:48:34 +03:00
Stephanos A.
9d8cce84a7 Merge pull request #1395 from Tria-plc/alpha
fix: change schedule listing order from ascending to descending by de…
2026-08-22 10:27:04 +03:00
Stephanos A
6ce4e13b4a fix: change schedule listing order from ascending to descending by departure time 2026-08-22 10:22:32 +03:00
marshal
41b8367638 Merge pull request #1394 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-22 09:27:19 +03:00
Marshal
ba89b670c8 fix issue 2026-08-22 06:26:43 +00:00
marshal
12b537ef90 Merge pull request #1392 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-22 09:17:41 +03:00
Marshal
722874203b fix issue 2026-08-22 06:09:36 +00:00
marshal
8923c2416c Merge pull request #1390 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-22 04:31:27 +03:00
Marshal
3455c1b3b4 fix issue 2026-08-22 01:29:44 +00:00
marshal
f4115f658d Merge pull request #1389 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-22 04:24:35 +03:00