Commit Graph

4986 Commits

Author SHA1 Message Date
ghost2023
91c9c3e513 feat(reports): list unbilled categories at zero in revenue-by-category
A category with no invoice lines in a period simply had no row, so a
category going quiet was indistinguishable from one that never existed,
and filtering to a category that was never billed returned an empty table.

The query is now three levels. The aggregate groups as before. A grid
crosses every period that saw revenue with every category the filter
allows, and LEFT JOINs the aggregate onto it so a missing combination
lands at zero. The wrapper does the display rounding and the labelling.

Two things had to move for that to be correct:

- The lag() window is now in the wrapper. A window function only sees the
  rows its own query level produces, so left on the aggregate it would
  skip a category's silent periods — billed in January and March, it
  would read March's prior as January and report flat growth.
- The category filter is off the aggregate and enforced by the grid's
  category list. Filtering the aggregate too would make the period axis
  depend on the selection, which is what left the table empty when the
  selected category had never been billed.

Periods come from the data, not generate_series over the date filter: a
twelve-month range over one billed month would otherwise publish eleven
months of pure zeros, and daily granularity would multiply that by thirty.

The Categories KPI is now "Categories with revenue" — a bare count of live
categories reads as a contradiction next to a table listing all fourteen.

EXPLAIN-validated against the dev database across seven filter shapes,
including the empty-array case (hence unnest(ARRAY[...]) over VALUES,
which is a syntax error when empty).

Claude-Session: https://claude.ai/code/session_01LoY3hNWqcaAC1pYmGPN7jr
2026-08-21 15:51:18 +03:00
ghost2023
3ce58d4c57 refactor(reports): label revenue categories from a key column
CATEGORY_LABEL_EXPR wraps the classifying CASE, so it only works where the
classification happens in the same SELECT. A report that classifies in a
subquery and labels in the wrapper has a plain key column to label instead.

CATEGORY_LABEL_OF takes that key expression; CATEGORY_LABEL_EXPR is now
defined through it, so its three existing callers are unchanged. Mirrors
CATEGORY_LABEL_OF in operations-classification.ts.

Claude-Session: https://claude.ai/code/session_01LoY3hNWqcaAC1pYmGPN7jr
2026-08-21 15:51:05 +03:00
ghost2023
503ea30f58 feat(overview): resolve dashboard layout from permissions, not role keys
role-dashboards.config.ts's ROLE_LAYOUTS was a hand-typed table of ~40
raw role/position keys (including edr_freight_app/xxx ad-hoc
sub-positions), matched against the user's held keys client-side.
Replaced with resolveOverviewLayout(), which just picks the
highest-priority key out of whatever GET /overview/layouts returns —
the same 'server filters by permission, frontend renders what comes
back' shape Reports already uses, so the frontend no longer needs to
know any individual permission key.

Hard cutover: no fallback to the old key table. Positions not covered
by the previous commit's grants (the ad-hoc department sub-positions)
will render the executive layout until granted a layout permission.
2026-08-21 15:43:44 +03:00
ghost2023
17e41aa767 feat(overview): serve GET /overview/layouts filtered by permission
New catalog endpoint, same shape as GET /reports: returns the overview
layouts (key + label) the caller holds the matching
edr_freight_app:overview:<layout>:view permission for, in priority
order. Backend enforcement to go with the permission-based frontend
resolver (next commit) — a caller can no longer land on a layout their
JWT doesn't actually carry the permission for.
2026-08-21 15:43:26 +03:00
ghost2023
b60e361483 feat(iam): add per-layout overview permissions
Adds edr_freight_app:overview:<layout>:view for each of the 6 overview
dashboard layouts (clearance, occ, operation, marketer, finance,
executive), seeded via OVERVIEW_LAYOUT_PERMISSIONS alongside the
existing report permissions.

Granted 1:1 to match today's role-dashboards.config.ts ROLE_LAYOUTS
key table, appended only at the terminal EDR_FREIGHT_ROLES /
EDR_FREIGHT_POSITIONS assembly points (never inside the reusable
ROLE_PERMISSION_PRESETS/POSITION_PERMISSION_PRESETS builders) so
composite positions like chief don't leak multiple layout grants from
the role arrays they spread.

The ~20 ad-hoc edr_freight_app/xxx department sub-positions are not
backfilled here and will fall back to the executive layout until
granted manually via the IAM positions admin screen.

Part of switching overview layout resolution from role/position-key
matching to permission checks, mirroring how reports already work.
2026-08-21 15:42:58 +03:00
marshalyordanos
8ff5e47a3a merge 2026-08-21 15:22:52 +03:00
Nathnael
7a2383f02c fix: revenue by customer 2026-08-21 10:57:42 +00:00
marshal
88762203e7 Merge pull request #1377 from Tria-plc/staging
Staging
2026-08-21 13:27:44 +03:00
marshal
f49adf66fc Merge pull request #1376 from Tria-plc/dev
dev
2026-08-21 13:26:33 +03:00
Nathnael
25d13baa6f chore: reporting and filtering 2026-08-21 09:25:21 +00:00
marshal
bf5e5d8cfd Merge pull request #1375 from Tria-plc/freight_feature/usermanagement
feat(train-scheduling): add showWagonStat prop to control wagon stats…
2026-08-21 12:01:00 +03:00
Marshal
a339ea620e feat(train-scheduling): add showWagonStat prop to control wagon stats visibility 2026-08-21 08:59:44 +00:00
Hagernesh
ca751b50f9 yser guide 2026-08-21 08:59:06 +00:00
Hagernesh
8181834037 Ticket
Empty container returns now generate a downloadable Equipment Interchange Receipt: container number & size, exact return timestamp, depot/location, condition, and the carrier/booking reference. Customers can download it from their booking's Documents tab (own-booking returns only); staff can pull any via the same endpoint.
2026-08-21 08:59:06 +00:00
Marshal
fbb169469f feat(clearance): preview charge documents before and after upload 2026-08-21 08:59:06 +00:00
Marshal
a9c6b85c08 feat(clearance): preview charge documents before and after upload 2026-08-21 08:59:06 +00:00
Marshal
b17a06052b fix issue 2026-08-21 08:59:06 +00:00
Marshal
b3823a4f32 fix issue 2026-08-21 08:59:06 +00:00
Marshal
2f894ba51b changes 2026-08-21 08:58:27 +00:00
Marshal
76bfbe1b17 feat: enhance GlDjiboutiClearanceListPage with tab navigation and improved filtering
- Added tab navigation for All, Import, Export, and On hold shipments.
- Implemented a new LivePill component to show real-time updates.
- Refactored shipment filtering logic to accommodate new tab functionality.
- Improved UI elements including buttons and text inputs for better user experience.
- Updated styles for table cells to allow text wrapping for long company names.
- Adjusted theme to use Space Grotesk font for headings.
2026-08-21 08:58:27 +00:00
Marshal
3a4eeee61b feat: enhance ClearanceChargesSection with file viewing and downloading capabilities 2026-08-21 08:47:47 +00:00
Marshal
c5909b8ec7 [200~feat: add CustomsPaymentsCard and PaymentsTab components for handling customs payments and payment summaries 2026-08-21 08:47:47 +00:00
marshal
8f7d67cbef Merge pull request #1374 from Tria-plc/freight_feature/usermanagement
feat(clearance): preview charge documents before and after upload
2026-08-21 10:11:23 +03:00
Marshal
24f5d94709 feat(clearance): preview charge documents before and after upload 2026-08-21 07:10:50 +00:00
marshal
fd8fb8f172 Merge pull request #1373 from Tria-plc/freight_feature/usermanagement
feat(clearance): preview charge documents before and after upload
2026-08-21 10:05:58 +03:00
Marshal
4c549029fe feat(clearance): preview charge documents before and after upload 2026-08-21 07:04:22 +00:00
marshal
b06e309fa2 Merge pull request #1372 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-20 21:31:03 +03:00
Marshal
ce3fde676e fix issue 2026-08-20 18:30:28 +00:00
marshal
ff7c054b7d Merge pull request #1371 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-20 21:29:28 +03:00
Marshal
0e8e6acb04 fix issue 2026-08-20 18:28:40 +00:00
marshal
8edde1ca76 Merge pull request #1370 from Tria-plc/freight_feature/usermanagement
fix issue
2026-08-20 21:16:37 +03:00
Marshal
a5e6cab248 fix issue 2026-08-20 18:16:03 +00:00
marshal
93373cbe5e Merge pull request #1369 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-20 21:11:10 +03:00
Marshal
d99b294c21 fix issue 2026-08-20 18:10:29 +00:00
Marshal
b72cbab535 changes 2026-08-20 18:06:13 +00:00
Marshal
934ed43ccb feat: enhance GlDjiboutiClearanceListPage with tab navigation and improved filtering
- Added tab navigation for All, Import, Export, and On hold shipments.
- Implemented a new LivePill component to show real-time updates.
- Refactored shipment filtering logic to accommodate new tab functionality.
- Improved UI elements including buttons and text inputs for better user experience.
- Updated styles for table cells to allow text wrapping for long company names.
- Adjusted theme to use Space Grotesk font for headings.
2026-08-20 17:44:52 +00:00
Marshal
0d34b9f5e3 feat: enhance ClearanceChargesSection with file viewing and downloading capabilities 2026-08-20 16:07:16 +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
Hagernesh
2e28b10610 dashboard UI 2026-08-20 13:48:02 +00:00
Hagernesh Tadesse
82c795999e Merge pull request #1367 from Tria-plc/eims-bulk-register
feat(warehouses): make dashboard date range + warehouse filter real
2026-08-20 16:33:11 +03:00
Hagernesh
7f772efcb3 feat(warehouses): make dashboard date range + warehouse filter real
Backs the previously-dead header date-picker and Filters button with
an actual scoped query. getDashboard() takes optional dateFrom/dateTo/
warehouseId: received (renamed from receivedToday) is the only
activity counter and respects the date range, defaulting to today when
omitted; the 10 status-backlog counters respect warehouseId only;
totalWarehouses/emptyContainers/importTrains/exportTrains stay global
since nothing ties them to a specific warehouse in the schema. Adds a
warehouse Select + date-range picker to the dashboard header, with a
caption spelling out what is and isn't scoped.
2026-08-20 13:30:28 +00:00
Hagernesh Tadesse
572b42343f Merge pull request #1366 from Tria-plc/eims-bulk-register
Additional Charges
2026-08-20 16:14:55 +03:00
Hagernesh
d4c19d7e40 finance only permission for Additional charges 2026-08-20 12:59:33 +00:00
Hagernesh
6e6d6329b6 feat(bookings): add Additional Payments tab, add-charge modal, portal pay
Backoffice: new tab on the booking detail page (?tab=additional-charges,
already linked from the row menu) with an Add Charge modal — Save draft or
Send to customer.

Portal: charges panel on the booking detail page, Pay now per charge via
the existing OTP/CBE-bill payment flow.

Also fixes: GET /bookings/:id/additional-charges was returning DRAFT
charges to the customer (hidden client-side only) — now filtered
server-side per caller.
2026-08-20 12:59:33 +00:00
Hagernesh
0ceb595714 feat(bookings): add ad-hoc additional-charge module
New freight.additional_charge table, independent of BookingClearanceCharge
(unbounded per booking, free-text reason). Draft -> send issues an invoice
and notifies the customer in-app/SMS/email; settles via the standard
.invoice.paid event. Adds the Additional charges row-menu entry
next to Cancel booking, permission-gated.

Not included: the Additional Payments tab UI, add-charge modal, portal pay
flow.
2026-08-20 12:59:33 +00:00
Hagernesh Tadesse
8e2bab27cf Merge pull request #1365 from Tria-plc/eims-bulk-register
fix
2026-08-20 15:07:49 +03:00
Marshal
80b7141f30 fix(portal): surface document upload on cleared bookings until payment 2026-08-20 11:58:05 +00:00
Marshal
a1feb21e4f View manual (offline) payment channel settings
Confirm offline (bank transfer) invoice payment
2026-08-20 11:57:58 +00:00
Marshal
e97e874bd1 fix issue 2026-08-20 11:49:57 +00:00
marshal
3604e78fbe Merge pull request #1364 from Tria-plc/freight_feature/usermanagement
Freight feature/usermanagement
2026-08-20 14:49:27 +03:00