add custom contrat templates

This commit is contained in:
Marshal
2026-08-04 09:48:49 +00:00
parent aac1175964
commit 7c78a815eb
10 changed files with 366 additions and 58 deletions

View File

@@ -2,17 +2,30 @@ import { BaseEntity } from "@edr/api-common";
import { Column, Entity, Index } from "typeorm";
/**
* The six canonical contract document templates, one per
* (trade direction × freight type) combination. Contracts store DOMESTIC for
* intercity movements; the template layer labels those INTERCITY to match the
* commercial vocabulary used on the printed documents.
* The ten canonical contract document templates. Import and export split by
* customs clearing (× freight type = 8); intercity does not, because it is a
* purely domestic Ethiopian movement that crosses no border and therefore has
* no customs leg at all (× freight type = 2).
*
* Contracts store DOMESTIC for intercity movements; the template layer labels
* those INTERCITY to match the commercial vocabulary used on the printed
* documents.
*
* The `_CUSTOMS` variant is issued when the contract has customs clearing
* enabled (the Service Provider clears in Djibouti/Ethiopia on the Client's
* behalf); `_NO_CUSTOMS` is the transport-only paper, where the Client handles
* its own declarations.
*/
export const CONTRACT_TEMPLATE_CODES = [
"IMPORT_BULK",
"EXPORT_BULK",
"IMPORT_BULK_CUSTOMS",
"IMPORT_BULK_NO_CUSTOMS",
"EXPORT_BULK_CUSTOMS",
"EXPORT_BULK_NO_CUSTOMS",
"INTERCITY_BULK",
"IMPORT_CONTAINER",
"EXPORT_CONTAINER",
"IMPORT_CONTAINER_CUSTOMS",
"IMPORT_CONTAINER_NO_CUSTOMS",
"EXPORT_CONTAINER_CUSTOMS",
"EXPORT_CONTAINER_NO_CUSTOMS",
"INTERCITY_CONTAINER",
] as const;
@@ -33,10 +46,19 @@ export interface ContractTemplateArticle {
order: number;
}
/** Map a contract's stored direction/freight pair onto a template code. */
/**
* Map a contract's stored direction/freight/customs triple onto a template
* code. `customsClearingEnabled` is treated as false when absent so an older
* contract row with a null flag still resolves to a real template rather than
* falling through to the generic layout.
*
* Intercity is domestic and has no customs leg, so it resolves to a single
* unsuffixed code regardless of the flag.
*/
export function contractTemplateCodeFor(
tradeDirection?: string | null,
freightType?: string | null,
customsClearingEnabled?: boolean | null,
): ContractTemplateCode {
const direction =
tradeDirection === "IMPORT"
@@ -46,7 +68,11 @@ export function contractTemplateCodeFor(
: "INTERCITY";
const freight =
(freightType ?? "").toUpperCase().includes("BULK") ? "BULK" : "CONTAINER";
return `${direction}_${freight}` as ContractTemplateCode;
if (direction === "INTERCITY") {
return `INTERCITY_${freight}` as ContractTemplateCode;
}
const customs = customsClearingEnabled ? "CUSTOMS" : "NO_CUSTOMS";
return `${direction}_${freight}_${customs}` as ContractTemplateCode;
}
@Entity({ schema: "freight", name: "contract_templates" })