mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
- Add migration for consolidation approvals table and status enum - Create ConsolidationApprovalService to handle approval logic - Implement repository for managing consolidation approvals - Add entity for consolidation approval with necessary fields - Develop frontend components for displaying and managing consolidation approvals - Create tests for consolidation approval service to ensure correct behavior
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { ForbiddenException } from '@nestjs/common';
|
|
|
|
import { ContractBookingService } from './contract-booking.service';
|
|
import { Contract } from './entities/contract.entity';
|
|
|
|
/**
|
|
* Who may open a shipment instance on a customs (Path B) contract. The customer
|
|
* initiates his own ONE_TIME customs booking and uploads the GL-input documents
|
|
* on it; GL still clears it and completes it with cargo and price. GENERAL
|
|
* customs instances come from a shipment request, and completing/creating a
|
|
* customs booking outright stays GL-only.
|
|
*/
|
|
describe('ContractBookingService — customs booking gate', () => {
|
|
function makeService() {
|
|
return new ContractBookingService(
|
|
{} as never, // contractsRepository
|
|
{} as never, // bookingsRepository
|
|
{} as never, // bookingPricingService
|
|
{} as never, // consolidationService
|
|
{} as never, // containerTypesService
|
|
{} as never, // ruleEngineService
|
|
{} as never, // milestoneService
|
|
{} as never, // invoiceService
|
|
{} as never, // bookingNotifier
|
|
{} as never, // dataSource
|
|
{} as never, // trainSchedulingService
|
|
{} as never, // bookingBatchService
|
|
{} as never, // bookingTransitionService
|
|
{} as never, // consolidationApprovalService
|
|
);
|
|
}
|
|
|
|
type WithPrivate = {
|
|
assertGate: (
|
|
c: Contract,
|
|
isGlActor: boolean,
|
|
isInitiate?: boolean,
|
|
) => Promise<string>;
|
|
};
|
|
|
|
const customsContract = (contractKind: 'ONE_TIME' | 'GENERAL'): Contract =>
|
|
({
|
|
id: 'c-1',
|
|
contractKind,
|
|
status: 'FULLY_EXECUTED',
|
|
customsClearingEnabled: true,
|
|
}) as Contract;
|
|
|
|
const gate = (c: Contract, isGl: boolean, isInitiate?: boolean) =>
|
|
(makeService() as never as WithPrivate).assertGate(c, isGl, isInitiate);
|
|
|
|
it('lets the customer initiate a ONE_TIME customs shipment', async () => {
|
|
await expect(gate(customsContract('ONE_TIME'), false, true)).resolves.toBe(
|
|
'CUSTOMER',
|
|
);
|
|
});
|
|
|
|
it('still lets GL initiate on the customer behalf', async () => {
|
|
await expect(gate(customsContract('ONE_TIME'), true, true)).resolves.toBe(
|
|
'GL_ET',
|
|
);
|
|
});
|
|
|
|
it('rejects a customer creating a customs booking outright (cargo + day)', async () => {
|
|
await expect(gate(customsContract('ONE_TIME'), false)).rejects.toBeInstanceOf(
|
|
ForbiddenException,
|
|
);
|
|
});
|
|
|
|
it('rejects a customer initiating a GENERAL customs shipment (request only)', async () => {
|
|
await expect(
|
|
gate(customsContract('GENERAL'), false, true),
|
|
).rejects.toBeInstanceOf(ForbiddenException);
|
|
});
|
|
});
|