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.
This commit is contained in:
Hagernesh
2026-08-20 12:35:19 +00:00
parent 8e2bab27cf
commit 0ceb595714
12 changed files with 622 additions and 1 deletions

View File

@@ -1330,6 +1330,30 @@ export const PORT_TERMINAL_PERMISSIONS: FreightPermissionSeed[] = [
),
];
// E. Additional charges — ad-hoc finance charges raised against a booking
export const ADDITIONAL_CHARGE_PERMISSIONS: FreightPermissionSeed[] = [
perm(
"f2e00001-0001-4000-8000-000000000001",
"edr_freight_app:additional_charges:view",
"View additional charges",
),
perm(
"f2e00001-0001-4000-8000-000000000002",
"edr_freight_app:additional_charges:create",
"Create additional charge",
),
perm(
"f2e00001-0001-4000-8000-000000000003",
"edr_freight_app:additional_charges:send",
"Send additional charge to customer",
),
perm(
"f2e00001-0001-4000-8000-000000000004",
"edr_freight_app:additional_charges:cancel",
"Cancel additional charge",
),
];
// E'. Train-scheduling finer actions (augment existing view/manage)
export const SCHEDULING_EXTRA_PERMISSIONS: FreightPermissionSeed[] = [
perm(
@@ -1713,6 +1737,11 @@ export const NOTIFICATION_PERMISSIONS: FreightPermissionSeed[] = [
"edr_freight_app:warehouse_fee_invoices:get_notification",
"Receive warehouse fee accrual notifications",
),
perm(
"f3a00001-0001-4000-8000-000000000009",
"edr_freight_app:additional_charges:get_notification",
"Receive additional charge notifications",
),
];
export const ADVANCED_BACKOFFICE_PERMISSIONS: FreightPermissionSeed[] = [
@@ -1726,6 +1755,7 @@ export const ADVANCED_BACKOFFICE_PERMISSIONS: FreightPermissionSeed[] = [
...FLEET_ROAD_PERMISSIONS,
...WAREHOUSE_PERMISSIONS,
...PORT_TERMINAL_PERMISSIONS,
...ADDITIONAL_CHARGE_PERMISSIONS,
...SCHEDULING_EXTRA_PERMISSIONS,
...CONFIG_SETTINGS_PERMISSIONS,
...STAFF_IAM_PERMISSIONS,
@@ -2170,6 +2200,14 @@ export const FREIGHT_PERMS = {
// Notification selector, not a route guard — see NOTIFICATION_PERMISSIONS.
getNotification: "edr_freight_app:warehouse_fee_invoices:get_notification",
},
additionalCharges: {
view: "edr_freight_app:additional_charges:view",
create: "edr_freight_app:additional_charges:create",
send: "edr_freight_app:additional_charges:send",
cancel: "edr_freight_app:additional_charges:cancel",
// Notification selector, not a route guard — see NOTIFICATION_PERMISSIONS.
getNotification: "edr_freight_app:additional_charges:get_notification",
},
settings: {
fileUpload: {
view: "edr_freight_app:settings:file_upload:view",
@@ -2345,6 +2383,9 @@ export const NOTIFICATION_PERMISSION_ANCHORS: Record<string, string[]> = {
[FREIGHT_PERMS.warehouseFeeInvoices.getNotification]: [
FREIGHT_PERMS.warehouseFeeInvoices.view,
],
[FREIGHT_PERMS.additionalCharges.getNotification]: [
FREIGHT_PERMS.additionalCharges.view,
],
};
/** Both arms of a freight-type-split permission (for one-of route guards). */