mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 03:40:56 +00:00
[200~feat: add CustomsPaymentsCard and PaymentsTab components for handling customs payments and payment summaries
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Per-schedule wagon yard plan — where THIS departure expects each consist
|
||||
* wagon to board, independent of where the wagon physically stands today.
|
||||
*
|
||||
* `wagons.current_yard_id` is one physical fact shared by every schedule of a
|
||||
* built train, so a train standing in Mojo could not be sold from Dire for a
|
||||
* departure next week. The plan is a sparse jsonb map `{ wagonId: yardId }`
|
||||
* on the schedule: a wagon missing from the map boards from its physical yard.
|
||||
* Booking capacity, fleet availability and wagon pinning all read the plan;
|
||||
* dispatch refuses to leave until the plan and the physical yards agree.
|
||||
*/
|
||||
export class SchedulePlannedWagonYards3620000000000 implements MigrationInterface {
|
||||
name = 'SchedulePlannedWagonYards3620000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.train_schedules
|
||||
ADD COLUMN IF NOT EXISTS planned_wagon_yards jsonb
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.train_schedules DROP COLUMN IF EXISTS planned_wagon_yards
|
||||
`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* The customer now approves a clearance charge before it becomes an invoice:
|
||||
* GL describes the price, SENDs it, the customer ACCEPTs (invoice issued, charge
|
||||
* locked) or REJECTs with a note (GL revises and re-sends). Charges that were
|
||||
* already sent as invoices under the old flow are carried over as ACCEPTED so
|
||||
* their invoices stay payable.
|
||||
*/
|
||||
export class ClearanceChargeCustomerDecision3630000000000
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'ClearanceChargeCustomerDecision3630000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "freight"."booking_clearance_charge"
|
||||
ADD COLUMN IF NOT EXISTS "description" text,
|
||||
ADD COLUMN IF NOT EXISTS "customer_note" text,
|
||||
ADD COLUMN IF NOT EXISTS "customer_decided_at" timestamptz,
|
||||
ADD COLUMN IF NOT EXISTS "customer_decided_by" uuid
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
UPDATE "freight"."booking_clearance_charge"
|
||||
SET "status" = 'ACCEPTED'
|
||||
WHERE "status" = 'SENT' AND "invoice_id" IS NOT NULL
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
UPDATE "freight"."booking_clearance_charge"
|
||||
SET "status" = 'SENT'
|
||||
WHERE "status" = 'ACCEPTED'
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
UPDATE "freight"."booking_clearance_charge"
|
||||
SET "status" = 'BILLED'
|
||||
WHERE "status" = 'REJECTED'
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "freight"."booking_clearance_charge"
|
||||
DROP COLUMN IF EXISTS "description",
|
||||
DROP COLUMN IF EXISTS "customer_note",
|
||||
DROP COLUMN IF EXISTS "customer_decided_at",
|
||||
DROP COLUMN IF EXISTS "customer_decided_by"
|
||||
`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Ethiopian-side-only customs clearance:
|
||||
*
|
||||
* - service_types.includes_ethiopian_customs_only marks a customs service that
|
||||
* EDR clears on the Ethiopian side only. Same clearance flow; only the fee
|
||||
* differs — pricing looks up the ETHIOPIAN_CUSTOMS_CLEARANCE rate instead of
|
||||
* CUSTOMS_CLEARANCE.
|
||||
* - rates.trigger widens to 30 chars to fit the new trigger value.
|
||||
* - CK_rates_yard_scope gains ETHIOPIAN_CUSTOMS_CLEARANCE in its yard-carrying
|
||||
* branch: it is priced per origin → destination leg like customs clearance.
|
||||
*/
|
||||
export class EthiopianCustomsClearance3640000000000 implements MigrationInterface {
|
||||
name = 'EthiopianCustomsClearance3640000000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.service_types
|
||||
ADD COLUMN IF NOT EXISTS includes_ethiopian_customs_only boolean NOT NULL DEFAULT false
|
||||
`);
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE freight.rates ALTER COLUMN trigger TYPE varchar(30)`,
|
||||
);
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE freight.rates DROP CONSTRAINT IF EXISTS "CK_rates_yard_scope"`,
|
||||
);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.rates ADD CONSTRAINT "CK_rates_yard_scope" CHECK (
|
||||
deleted_at IS NOT NULL OR status = 'SUPERSEDED' OR
|
||||
CASE
|
||||
WHEN (trigger = 'ALWAYS' AND applies_to IN ('BULK', 'CONTAINER', 'INTERCITY'))
|
||||
OR trigger IN ('CUSTOMS_CLEARANCE', 'ETHIOPIAN_CUSTOMS_CLEARANCE', 'WITH_RETURN', 'FUEL')
|
||||
THEN origin_yard_id IS NOT NULL AND destination_yard_id IS NOT NULL
|
||||
ELSE origin_yard_id IS NULL AND destination_yard_id IS NULL
|
||||
END
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE freight.rates DROP CONSTRAINT IF EXISTS "CK_rates_yard_scope"`,
|
||||
);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.rates ADD CONSTRAINT "CK_rates_yard_scope" CHECK (
|
||||
deleted_at IS NOT NULL OR status = 'SUPERSEDED' OR
|
||||
CASE
|
||||
WHEN (trigger = 'ALWAYS' AND applies_to IN ('BULK', 'CONTAINER', 'INTERCITY'))
|
||||
OR trigger IN ('CUSTOMS_CLEARANCE', 'WITH_RETURN', 'FUEL')
|
||||
THEN origin_yard_id IS NOT NULL AND destination_yard_id IS NOT NULL
|
||||
ELSE origin_yard_id IS NULL AND destination_yard_id IS NULL
|
||||
END
|
||||
)
|
||||
`);
|
||||
// Rows on the new trigger would not fit varchar(20) — drop them first.
|
||||
await queryRunner.query(
|
||||
`DELETE FROM freight.rates WHERE trigger = 'ETHIOPIAN_CUSTOMS_CLEARANCE'`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE freight.rates ALTER COLUMN trigger TYPE varchar(20)`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE freight.service_types DROP COLUMN IF EXISTS includes_ethiopian_customs_only`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user