@autologix-engineering/shared 1.2.386 → 1.2.388

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autologix-engineering/shared",
3
- "version": "1.2.386",
3
+ "version": "1.2.388",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0"
6
6
  },
@@ -17,7 +17,8 @@ export declare enum LTRPayoutField {
17
17
  SignOffMethod = "signOffMethod",
18
18
  SignOffTimestamp = "signOffTimestamp",
19
19
  SignatureImageUrl = "signatureImageUrl",
20
- LockedReason = "lockedReason"
20
+ LockedReason = "lockedReason",
21
+ DirectEntry = "directEntry"
21
22
  }
22
23
  export interface ILTRPayout {
23
24
  [LTRPayoutField.LTRPayoutId]: string;
@@ -37,6 +38,24 @@ export interface ILTRPayout {
37
38
  [LTRPayoutField.SignatureImageUrl]?: string;
38
39
  /** Set only while `Status` is `LTRPayoutStatus.Locked`. */
39
40
  [LTRPayoutField.LockedReason]?: LTRPayoutLockedReason;
41
+ /**
42
+ * These rows are one month typed as a summary, not a day-wise log.
43
+ * (AD-3279)
44
+ *
45
+ * Written on every submit, true or false, so the flag describes the rows the
46
+ * payout holds NOW rather than how the booking was once closed — a day-wise
47
+ * submit over a direct-entry month clears it.
48
+ *
49
+ * The booking's activity log already records that a closure happened and by
50
+ * what means, but a log row cannot be read by the screens that need this
51
+ * answer while they are drawing. Direct entry produces exactly one synthetic
52
+ * row, and without this flag the day-wise tab drew that row as though a
53
+ * driver had logged a single day, the chooser offered "use the driver app's
54
+ * logs" for a month no driver had touched, and the replace-the-driver's-
55
+ * record warning fired on a month that never had one. (QA run 3, items 10,
56
+ * 11 and 18)
57
+ */
58
+ [LTRPayoutField.DirectEntry]?: boolean;
40
59
  }
41
60
  export interface ILTRBillingSummary {
42
61
  lineItems: INumberedInvoiceLineItem[];
@@ -15,6 +15,7 @@ export var LTRPayoutField;
15
15
  LTRPayoutField["SignOffTimestamp"] = "signOffTimestamp";
16
16
  LTRPayoutField["SignatureImageUrl"] = "signatureImageUrl";
17
17
  LTRPayoutField["LockedReason"] = "lockedReason";
18
+ LTRPayoutField["DirectEntry"] = "directEntry";
18
19
  })(LTRPayoutField || (LTRPayoutField = {}));
19
20
  export var LTRPayoutRowField;
20
21
  (function (LTRPayoutRowField) {
@@ -1 +1 @@
1
- {"version":3,"file":"ltr.payout.model.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/models/src/ltr.payout.model.ts"],"names":[],"mappings":"AASA,MAAM,CAAN,IAAY,cAgBX;AAhBD,WAAY,cAAc;IACzB,6CAA2B,CAAA;IAC3B,iDAA+B,CAAA;IAC/B,qCAAmB,CAAA;IACnB,yCAAuB,CAAA;IACvB,yCAAuB,CAAA;IACvB,mDAAiC,CAAA;IACjC,qDAAmC,CAAA;IACnC,uCAAqB,CAAA;IACrB,qCAAmB,CAAA;IACnB,mDAAiC,CAAA;IACjC,mCAAiB,CAAA;IACjB,iDAA+B,CAAA;IAC/B,uDAAqC,CAAA;IACrC,yDAAuC,CAAA;IACvC,+CAA6B,CAAA;AAC9B,CAAC,EAhBW,cAAc,KAAd,cAAc,QAgBzB;AAsCD,MAAM,CAAN,IAAY,iBA2FX;AA3FD,WAAY,iBAAiB;IAC5B,oCAAe,CAAA;IACf,iEAA4C,CAAA;IAC5C,6DAAwC,CAAA;IACxC,iDAA4B,CAAA;IAC5B,yCAAoB,CAAA;IACpB,qCAAgB,CAAA;IAChB,wCAAmB,CAAA;IACnB,kCAAa,CAAA;IACb,wCAAmB,CAAA;IACnB,sCAAiB,CAAA;IACjB,+CAA0B,CAAA;IAC1B,wCAAmB,CAAA;IACnB,2CAAsB,CAAA;IACtB,iDAA4B,CAAA;IAC5B,yDAAoC,CAAA;IACpC,iDAA4B,CAAA;IAC5B,0EAAqD,CAAA;IACrD,uEAAkD,CAAA;IAClD,2CAAsB,CAAA;IACtB,8FAAyE,CAAA;IACzE,6GAAwF,CAAA;IACxF,qDAAgC,CAAA;IAChC,mDAA8B,CAAA;IAC9B,uDAAkC,CAAA;IAClC,6CAAwB,CAAA;IACxB;;;;;;;OAOG;IACH,wDAAmC,CAAA;IACnC,4DAAuC,CAAA;IACvC,qDAAgC,CAAA;IAChC,gEAA2C,CAAA;IAC3C,oEAA+C,CAAA;IAC/C,yDAAoC,CAAA;IACpC,oEAA+C,CAAA;IAC/C,wEAAmD,CAAA;IACnD,+CAA0B,CAAA;IAC1B,iDAA4B,CAAA;IAC5B,uDAAkC,CAAA;IAClC,yDAAoC,CAAA;IACpC,qDAAgC,CAAA;IAChC,yDAAoC,CAAA;IACpC,sDAAiC,CAAA;IACjC,iDAA4B,CAAA;IAC5B,qEAAgD,CAAA;IAChD,uEAAkD,CAAA;IAClD,0DAAqC,CAAA;IACrC,0DAAqC,CAAA;IACrC,sDAAiC,CAAA;IACjC,sDAAiC,CAAA;IACjC,kDAA6B,CAAA;IAC7B,kDAA6B,CAAA;IAC7B,4DAAuC,CAAA;IACvC,4DAAuC,CAAA;IACvC,sDAAiC,CAAA;IACjC,wDAAmC,CAAA;IACnC,4CAAuB,CAAA;IACvB;;;;;;;;;OASG;IACH,kDAA6B,CAAA;IAC7B,4CAA4C;IAC5C,oDAA+B,CAAA;IAC/B,gDAA2B,CAAA;IAC3B,iEAA4C,CAAA;IAC5C,mEAA8C,CAAA;IAC9C;;;;;;;;;;OAUG;IACH,wCAAmB,CAAA;AACpB,CAAC,EA3FW,iBAAiB,KAAjB,iBAAiB,QA2F5B"}
1
+ {"version":3,"file":"ltr.payout.model.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/models/src/ltr.payout.model.ts"],"names":[],"mappings":"AASA,MAAM,CAAN,IAAY,cAiBX;AAjBD,WAAY,cAAc;IACzB,6CAA2B,CAAA;IAC3B,iDAA+B,CAAA;IAC/B,qCAAmB,CAAA;IACnB,yCAAuB,CAAA;IACvB,yCAAuB,CAAA;IACvB,mDAAiC,CAAA;IACjC,qDAAmC,CAAA;IACnC,uCAAqB,CAAA;IACrB,qCAAmB,CAAA;IACnB,mDAAiC,CAAA;IACjC,mCAAiB,CAAA;IACjB,iDAA+B,CAAA;IAC/B,uDAAqC,CAAA;IACrC,yDAAuC,CAAA;IACvC,+CAA6B,CAAA;IAC7B,6CAA2B,CAAA;AAC5B,CAAC,EAjBW,cAAc,KAAd,cAAc,QAiBzB;AAwDD,MAAM,CAAN,IAAY,iBA2FX;AA3FD,WAAY,iBAAiB;IAC5B,oCAAe,CAAA;IACf,iEAA4C,CAAA;IAC5C,6DAAwC,CAAA;IACxC,iDAA4B,CAAA;IAC5B,yCAAoB,CAAA;IACpB,qCAAgB,CAAA;IAChB,wCAAmB,CAAA;IACnB,kCAAa,CAAA;IACb,wCAAmB,CAAA;IACnB,sCAAiB,CAAA;IACjB,+CAA0B,CAAA;IAC1B,wCAAmB,CAAA;IACnB,2CAAsB,CAAA;IACtB,iDAA4B,CAAA;IAC5B,yDAAoC,CAAA;IACpC,iDAA4B,CAAA;IAC5B,0EAAqD,CAAA;IACrD,uEAAkD,CAAA;IAClD,2CAAsB,CAAA;IACtB,8FAAyE,CAAA;IACzE,6GAAwF,CAAA;IACxF,qDAAgC,CAAA;IAChC,mDAA8B,CAAA;IAC9B,uDAAkC,CAAA;IAClC,6CAAwB,CAAA;IACxB;;;;;;;OAOG;IACH,wDAAmC,CAAA;IACnC,4DAAuC,CAAA;IACvC,qDAAgC,CAAA;IAChC,gEAA2C,CAAA;IAC3C,oEAA+C,CAAA;IAC/C,yDAAoC,CAAA;IACpC,oEAA+C,CAAA;IAC/C,wEAAmD,CAAA;IACnD,+CAA0B,CAAA;IAC1B,iDAA4B,CAAA;IAC5B,uDAAkC,CAAA;IAClC,yDAAoC,CAAA;IACpC,qDAAgC,CAAA;IAChC,yDAAoC,CAAA;IACpC,sDAAiC,CAAA;IACjC,iDAA4B,CAAA;IAC5B,qEAAgD,CAAA;IAChD,uEAAkD,CAAA;IAClD,0DAAqC,CAAA;IACrC,0DAAqC,CAAA;IACrC,sDAAiC,CAAA;IACjC,sDAAiC,CAAA;IACjC,kDAA6B,CAAA;IAC7B,kDAA6B,CAAA;IAC7B,4DAAuC,CAAA;IACvC,4DAAuC,CAAA;IACvC,sDAAiC,CAAA;IACjC,wDAAmC,CAAA;IACnC,4CAAuB,CAAA;IACvB;;;;;;;;;OASG;IACH,kDAA6B,CAAA;IAC7B,4CAA4C;IAC5C,oDAA+B,CAAA;IAC/B,gDAA2B,CAAA;IAC3B,iEAA4C,CAAA;IAC5C,mEAA8C,CAAA;IAC9C;;;;;;;;;;OAUG;IACH,wCAAmB,CAAA;AACpB,CAAC,EA3FW,iBAAiB,KAAjB,iBAAiB,QA2F5B"}
@@ -77,9 +77,21 @@ export declare enum NumberedInvoiceField {
77
77
  ConsolidatedTaxInvoiceId = "consolidatedTaxInvId",
78
78
  LTRKey = "ltrKey",
79
79
  LTRDataKey = "ltrDataKey",
80
+ LTRCoverageSnapshot = "ltrCovSnap",
80
81
  VendorTaxAddress = "vendorTaxAddress",
81
82
  VendorTaxAddressId = "vendorTaxAddressId"
82
83
  }
84
+ /**
85
+ * The LTR vehicle master's LastInvoiceDateByGroup entries an LTR invoice moved
86
+ * when it was generated: `before` is each group's value going in (null when
87
+ * the group had never billed), `after` the value the invoice wrote. Cancelling
88
+ * the invoice restores `before`, so the months it billed become billable again.
89
+ */
90
+ export interface ILTRCoverageSnapshot {
91
+ vehicleMasterId: string;
92
+ before: Record<string, string | null>;
93
+ after: Record<string, string>;
94
+ }
83
95
  export interface INumberedInvoice extends TypedModel {
84
96
  [NumberedInvoiceField.NumberedInvoiceId]: string;
85
97
  [NumberedInvoiceField.InvoiceNumber]: string;
@@ -139,6 +151,7 @@ export interface INumberedInvoice extends TypedModel {
139
151
  [NumberedInvoiceField.ConsolidatedTaxInvoiceId]?: string;
140
152
  [NumberedInvoiceField.LTRKey]: string;
141
153
  [NumberedInvoiceField.LTRDataKey]: string;
154
+ [NumberedInvoiceField.LTRCoverageSnapshot]?: ILTRCoverageSnapshot | null;
142
155
  [NumberedInvoiceField.VendorTaxAddress]?: ITaxAddress;
143
156
  [NumberedInvoiceField.VendorTaxAddressId]?: string;
144
157
  }
@@ -61,6 +61,7 @@ export var NumberedInvoiceField;
61
61
  NumberedInvoiceField["ConsolidatedTaxInvoiceId"] = "consolidatedTaxInvId";
62
62
  NumberedInvoiceField["LTRKey"] = "ltrKey";
63
63
  NumberedInvoiceField["LTRDataKey"] = "ltrDataKey";
64
+ NumberedInvoiceField["LTRCoverageSnapshot"] = "ltrCovSnap";
64
65
  NumberedInvoiceField["VendorTaxAddress"] = "vendorTaxAddress";
65
66
  NumberedInvoiceField["VendorTaxAddressId"] = "vendorTaxAddressId";
66
67
  })(NumberedInvoiceField || (NumberedInvoiceField = {}));
@@ -1 +1 @@
1
- {"version":3,"file":"numbered.invoice.model.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/models/src/numbered.invoice.model.ts"],"names":[],"mappings":"AA0BA,MAAM,CAAN,IAAY,oBAsEX;AAtED,WAAY,oBAAoB;IAC/B,+DAAuC,CAAA;IACvC,uDAA+B,CAAA;IAC/B,mDAA2B,CAAA;IAC3B,8DAAsC,CAAA;IACtC,kEAA0C,CAAA;IAC1C,iDAAyB,CAAA;IACzB,qDAA6B,CAAA;IAC7B,6CAAqB,CAAA;IACrB,iDAAyB,CAAA;IACzB,oEAAoE;IACpE,0EAA0E;IAC1E,yEAAyE;IACzE,+DAAuC,CAAA;IACvC,oDAA4B,CAAA;IAC5B,wDAAgC,CAAA;IAChC,2DAAmC,CAAA;IACnC,+DAAuC,CAAA;IACvC,yCAAiB,CAAA;IACjB,uDAA+B,CAAA;IAC/B,2DAAmC,CAAA;IACnC,uDAA+B,CAAA;IAC/B,2DAAmC,CAAA;IACnC,2DAAmC,CAAA;IACnC,iDAAyB,CAAA;IACzB,iDAAyB,CAAA;IACzB,qDAA6B,CAAA;IAE7B,uDAA+B,CAAA;IAC/B,6DAAqC,CAAA;IAErC,+CAAuB,CAAA;IACvB,uCAAe,CAAA;IAEf,mDAA2B,CAAA;IAC3B,uDAA+B,CAAA;IAE/B,2DAAmC,CAAA;IACnC,+DAAuC,CAAA;IAEvC,yDAAiC,CAAA;IAEjC,0DAAkC,CAAA;IAClC,uDAA+B,CAAA;IAC/B,uDAA+B,CAAA;IAC/B,mDAA2B,CAAA;IAC3B,uDAA+B,CAAA;IAC/B,mCAAW,CAAA;IACX,qDAA6B,CAAA;IAC7B,yDAAiC,CAAA;IACjC,uEAA+C,CAAA;IAC/C,6CAAqB,CAAA;IACrB,+CAAuB,CAAA;IACvB,mDAA2B,CAAA;IAC3B,mDAA2B,CAAA;IAC3B,6CAAqB,CAAA;IACrB,yCAAiB,CAAA;IACjB,6CAAqB,CAAA;IACrB,+CAAuB,CAAA;IACvB,mDAA2B,CAAA;IAC3B,iEAAyC,CAAA;IACzC,qEAA6C,CAAA;IAC7C,gDAAwB,CAAA;IACxB,6CAAqB,CAAA;IACrB,qEAA6C,CAAA;IAC7C,yEAAiD,CAAA;IACjD,yCAAiB,CAAA;IACjB,iDAAyB,CAAA;IACzB,6DAAqC,CAAA;IACrC,iEAAyC,CAAA;AAC1C,CAAC,EAtEW,oBAAoB,KAApB,oBAAoB,QAsE/B"}
1
+ {"version":3,"file":"numbered.invoice.model.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/models/src/numbered.invoice.model.ts"],"names":[],"mappings":"AA0BA,MAAM,CAAN,IAAY,oBAuEX;AAvED,WAAY,oBAAoB;IAC/B,+DAAuC,CAAA;IACvC,uDAA+B,CAAA;IAC/B,mDAA2B,CAAA;IAC3B,8DAAsC,CAAA;IACtC,kEAA0C,CAAA;IAC1C,iDAAyB,CAAA;IACzB,qDAA6B,CAAA;IAC7B,6CAAqB,CAAA;IACrB,iDAAyB,CAAA;IACzB,oEAAoE;IACpE,0EAA0E;IAC1E,yEAAyE;IACzE,+DAAuC,CAAA;IACvC,oDAA4B,CAAA;IAC5B,wDAAgC,CAAA;IAChC,2DAAmC,CAAA;IACnC,+DAAuC,CAAA;IACvC,yCAAiB,CAAA;IACjB,uDAA+B,CAAA;IAC/B,2DAAmC,CAAA;IACnC,uDAA+B,CAAA;IAC/B,2DAAmC,CAAA;IACnC,2DAAmC,CAAA;IACnC,iDAAyB,CAAA;IACzB,iDAAyB,CAAA;IACzB,qDAA6B,CAAA;IAE7B,uDAA+B,CAAA;IAC/B,6DAAqC,CAAA;IAErC,+CAAuB,CAAA;IACvB,uCAAe,CAAA;IAEf,mDAA2B,CAAA;IAC3B,uDAA+B,CAAA;IAE/B,2DAAmC,CAAA;IACnC,+DAAuC,CAAA;IAEvC,yDAAiC,CAAA;IAEjC,0DAAkC,CAAA;IAClC,uDAA+B,CAAA;IAC/B,uDAA+B,CAAA;IAC/B,mDAA2B,CAAA;IAC3B,uDAA+B,CAAA;IAC/B,mCAAW,CAAA;IACX,qDAA6B,CAAA;IAC7B,yDAAiC,CAAA;IACjC,uEAA+C,CAAA;IAC/C,6CAAqB,CAAA;IACrB,+CAAuB,CAAA;IACvB,mDAA2B,CAAA;IAC3B,mDAA2B,CAAA;IAC3B,6CAAqB,CAAA;IACrB,yCAAiB,CAAA;IACjB,6CAAqB,CAAA;IACrB,+CAAuB,CAAA;IACvB,mDAA2B,CAAA;IAC3B,iEAAyC,CAAA;IACzC,qEAA6C,CAAA;IAC7C,gDAAwB,CAAA;IACxB,6CAAqB,CAAA;IACrB,qEAA6C,CAAA;IAC7C,yEAAiD,CAAA;IACjD,yCAAiB,CAAA;IACjB,iDAAyB,CAAA;IACzB,0DAAkC,CAAA;IAClC,6DAAqC,CAAA;IACrC,iEAAyC,CAAA;AAC1C,CAAC,EAvEW,oBAAoB,KAApB,oBAAoB,QAuE/B"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Allocating the contract code for an EXTENDED BA contract — AD-3416.
3
+ *
4
+ * A BA contract's base code comes from a per-context `SeqMetadata` counter,
5
+ * read and incremented under a `pessimistic_write` lock
6
+ * (create.ba.contract.controller.ts). Every base code in a context is
7
+ * therefore distinct, and distinct even under concurrent creates.
8
+ *
9
+ * Extending a contract did not go anywhere near that. It derived the new code
10
+ * from the old one by string arithmetic alone — `1065` -> `1065E1`,
11
+ * `1065E1` -> `1065E2` — with no idea what already existed. And the block
12
+ * that would have retired the extended contract's parent is commented out in
13
+ * extend.ba.contract.ts, so the parent stays extendable: extend `1065`, let
14
+ * `1065E1` be surrendered or cancelled, extend `1065` again, and the second
15
+ * extension is minted as `1065E1` as well. Two distinct contract rows, one
16
+ * code.
17
+ *
18
+ * That matters because the BA Payout template emits one row per contract row
19
+ * while the upload validator, the payout calculator and the save path all key
20
+ * contracts by CODE. Both rows then validate against whichever duplicate the
21
+ * in-memory map kept last, and the application's own unedited template is
22
+ * rejected on upload (AD-3416; first reported as ISSUE-4 on AD-3288). On
23
+ * staging this had happened ten times, most recently on 25/09/2026, where
24
+ * extending `1073` twice produced two `1073E1` rows ninety seconds apart.
25
+ *
26
+ * `selectBAPayoutContracts` softens the symptom by collapsing records that
27
+ * share (BA, code, vehicle) to the most recently edited one, but that is a
28
+ * read-side tie-break for records keyed in twice, not a fix: applied to two
29
+ * genuinely different contracts it silently drops one of them from the
30
+ * payout. The ambiguity has to be prevented where it is created.
31
+ *
32
+ * So this module answers the allocation question instead of guessing it:
33
+ * given the code being extended and the codes already in use, what is the
34
+ * first extension suffix nobody has taken? The caller supplies the in-use set
35
+ * — everything in the same business context, which is the scope base codes
36
+ * are numbered in (on staging, no code is shared by two BAs inside one
37
+ * context) — and holds a lock while it does, so two simultaneous extensions
38
+ * cannot both read the same set.
39
+ */
40
+ /** `1065E2` -> base `1065`, extension 2. A code with no suffix is extension 0. */
41
+ export interface BAContractCodeParts {
42
+ base: string;
43
+ extension: number;
44
+ }
45
+ /**
46
+ * Split a contract code into the part that identifies the contract family and
47
+ * the extension number.
48
+ *
49
+ * The pattern is the one the old generator used, kept deliberately: `(.+)E(\d+)`
50
+ * anchored at the end. Base codes are plain integers from the sequence
51
+ * counter, so the only `E` in a well-formed code is the extension marker.
52
+ */
53
+ export declare function splitBAContractCode(code: unknown): BAContractCodeParts;
54
+ /**
55
+ * The first extension code of `oldContractCode` that is not already in use.
56
+ *
57
+ * `usedCodes` is every contract code already allocated in the scope the
58
+ * caller is protecting — for extend.ba.contract.ts, every code in the
59
+ * business context, whatever its status. Cancelled and Surrendered rows are
60
+ * deliberately included: their codes are still printed on payout statements,
61
+ * still stored on `BAPayoutRow.contractNo`, and still what the upload
62
+ * validator looks up, so reusing one recreates exactly the ambiguity this
63
+ * exists to stop.
64
+ *
65
+ * Codes are compared after `normalizeBAContractCode` (trim + upper), the same
66
+ * normalization `resolveBAPayoutContract` uses to decide that an uploaded row
67
+ * names a given contract. The two answers cannot disagree.
68
+ *
69
+ * Note that this does NOT guarantee the returned suffix is the old one plus
70
+ * one. Extending `1065` when `1065E1` is taken yields `1065E2`, which is the
71
+ * point: the code names a row, not a position in a chain, and nothing in the
72
+ * codebase parses it to find a parent (the parent is a foreign key).
73
+ */
74
+ export declare function nextExtendedContractCode(oldContractCode: unknown, usedCodes: Iterable<unknown> | null | undefined): string;
@@ -0,0 +1,69 @@
1
+ import { normalizeBAContractCode } from './ba.payout.contract.selection';
2
+ /**
3
+ * Split a contract code into the part that identifies the contract family and
4
+ * the extension number.
5
+ *
6
+ * The pattern is the one the old generator used, kept deliberately: `(.+)E(\d+)`
7
+ * anchored at the end. Base codes are plain integers from the sequence
8
+ * counter, so the only `E` in a well-formed code is the extension marker.
9
+ */
10
+ export function splitBAContractCode(code) {
11
+ const normalized = normalizeBAContractCode(code);
12
+ const match = normalized.match(/^(.+)E(\d+)$/);
13
+ if (!match)
14
+ return { base: normalized, extension: 0 };
15
+ const extension = parseInt(match[2], 10);
16
+ // `E0`, or a suffix so long it does not survive parseInt, is not something
17
+ // this codebase mints; treat the whole string as the family rather than
18
+ // inventing an extension number from it.
19
+ if (!Number.isFinite(extension) || extension < 1) {
20
+ return { base: normalized, extension: 0 };
21
+ }
22
+ return { base: match[1], extension };
23
+ }
24
+ /**
25
+ * How far the walk will go before giving up. A context would need this many
26
+ * extensions of one contract to reach it; hitting it means the in-use set is
27
+ * wrong, and an error naming the code is far more useful than a silent
28
+ * duplicate or a hung request.
29
+ */
30
+ const MAX_EXTENSION_SEARCH = 1000;
31
+ /**
32
+ * The first extension code of `oldContractCode` that is not already in use.
33
+ *
34
+ * `usedCodes` is every contract code already allocated in the scope the
35
+ * caller is protecting — for extend.ba.contract.ts, every code in the
36
+ * business context, whatever its status. Cancelled and Surrendered rows are
37
+ * deliberately included: their codes are still printed on payout statements,
38
+ * still stored on `BAPayoutRow.contractNo`, and still what the upload
39
+ * validator looks up, so reusing one recreates exactly the ambiguity this
40
+ * exists to stop.
41
+ *
42
+ * Codes are compared after `normalizeBAContractCode` (trim + upper), the same
43
+ * normalization `resolveBAPayoutContract` uses to decide that an uploaded row
44
+ * names a given contract. The two answers cannot disagree.
45
+ *
46
+ * Note that this does NOT guarantee the returned suffix is the old one plus
47
+ * one. Extending `1065` when `1065E1` is taken yields `1065E2`, which is the
48
+ * point: the code names a row, not a position in a chain, and nothing in the
49
+ * codebase parses it to find a parent (the parent is a foreign key).
50
+ */
51
+ export function nextExtendedContractCode(oldContractCode, usedCodes) {
52
+ const { base, extension } = splitBAContractCode(oldContractCode);
53
+ if (!base) {
54
+ throw new Error('Cannot allocate an extended contract code: the contract being extended has no code');
55
+ }
56
+ const taken = new Set();
57
+ for (const code of usedCodes || []) {
58
+ const normalized = normalizeBAContractCode(code);
59
+ if (normalized)
60
+ taken.add(normalized);
61
+ }
62
+ for (let next = extension + 1; next <= extension + MAX_EXTENSION_SEARCH; next++) {
63
+ const candidate = `${base}E${next}`;
64
+ if (!taken.has(candidate))
65
+ return candidate;
66
+ }
67
+ throw new Error(`Cannot allocate an extended contract code for ${base}: ${MAX_EXTENSION_SEARCH} consecutive suffixes from E${extension + 1} are already in use`);
68
+ }
69
+ //# sourceMappingURL=ba.contract.extension.code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ba.contract.extension.code.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/ba.contract.extension.code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAgDzE;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAChD,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAEtD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,2EAA2E;IAC3E,wEAAwE;IACxE,yCAAyC;IACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,wBAAwB,CACvC,eAAwB,EACxB,SAA+C;IAE/C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjE,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACd,oFAAoF,CACpF,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,UAAU;YAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,KACC,IAAI,IAAI,GAAG,SAAS,GAAG,CAAC,EACxB,IAAI,IAAI,SAAS,GAAG,oBAAoB,EACxC,IAAI,EAAE,EACL,CAAC;QACF,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,KAAK,CACd,iDAAiD,IAAI,KAAK,oBAAoB,+BAA+B,SAAS,GAAG,CAAC,qBAAqB,CAC/I,CAAC;AACH,CAAC"}
@@ -1,38 +1,4 @@
1
1
  import { IBAContract } from '../../models/src/index';
2
- /**
3
- * Which BA contract a BA Payout row belongs to — AD-3098 QA re-open.
4
- *
5
- * The BA Payout template and the upload validator disagreed about contracts,
6
- * and the disagreement made a whole month's payout unuploadable:
7
- *
8
- * • The template emitted one row per contract overlapping the period with no
9
- * status filter at all, so a Cancelled contract got a row.
10
- * • The validator hashed contracts into `Map<contractCode, contract>` —
11
- * last write wins. `baContractCode` is NOT unique: an older extend flow
12
- * minted duplicate `E<n>` codes (AD-3227, AD-3097), and a contract that is
13
- * cancelled and re-raised keeps its code. On staging, `1004E1` exists twice
14
- * for BA1002 — one Cancelled, one Surrendered — so the validator compared
15
- * the template's Cancelled row against the Surrendered record and reported
16
- * "Contract Start Date mismatch. Expected: 01/12/2025, Found: 02/05/2026".
17
- * Nothing the user could type would satisfy it.
18
- *
19
- * The rule here is the single answer both sides now use, so they cannot drift:
20
- *
21
- * 1. Cancelled contracts are not payable and are dropped outright. This is
22
- * the same predicate `loadReportContracts` applies to the RM and SD
23
- * schedules and `findBAContractForBooking` applies to bookings, so the
24
- * payout, the schedules and the booking attribution agree about which
25
- * contracts exist.
26
- * 2. The same contract keyed in twice — same BA, same code, same vehicle —
27
- * is ONE contract, collapsed to its most recently edited record. That is
28
- * the tie-break `groupDuplicateContracts` already uses in the report
29
- * builders. Without it the template would print the row twice and the
30
- * payout would collect the RM twice.
31
- * 3. The same code on DIFFERENT vehicles stays as separate contracts (BA1000
32
- * has six rows coded '1000' on six vehicles). Those are resolved by the
33
- * vehicle registration carried on the uploaded row, which is the column
34
- * that actually distinguishes them.
35
- */
36
2
  export declare const normalizeBAContractCode: (raw: unknown) => string;
37
3
  /**
38
4
  * Registrations are compared without spaces or punctuation: the template
@@ -77,3 +43,120 @@ export declare function selectBAPayoutContracts(contracts: IBAContract[] | undef
77
43
  export declare function resolveBAPayoutContract(candidates: IBAContract[] | undefined | null, criteria?: {
78
44
  vehicleRegistration?: unknown;
79
45
  }): IBAContract | null;
46
+ /**
47
+ * Does this contract overlap the payout period?
48
+ *
49
+ * `periodStartIST` / `periodEndIST` are the period bounds already shifted into
50
+ * IST. A contract with no end date is open-ended and extends past the period.
51
+ * A contract with no *start* date cannot be judged and is kept, so that the
52
+ * template and the upload guard make the same call about it rather than one of
53
+ * them silently dropping it.
54
+ */
55
+ export declare function isBAPayoutContractInPeriod(contract: IBAContract, periodStartIST: Date, periodEndIST: Date): boolean;
56
+ /**
57
+ * The BA contracts that get a row in one payout period's template — and,
58
+ * therefore, exactly the rows the upload's completeness guard may demand back.
59
+ *
60
+ * AD-3098 QA re-open, second round. PR #3951 taught the template generator to
61
+ * run its contracts through `selectBAPayoutContracts` (dropping Cancelled
62
+ * records) but left the "rows were deleted" guard in
63
+ * `process.business.associate.payout.upload.controller.ts` building its
64
+ * expected set straight from `ba.contractDetails` with no status filter. The
65
+ * template then omitted a Cancelled contract and the guard immediately
66
+ * rejected the file the application had just produced:
67
+ *
68
+ * "Some BA rows are missing from the uploaded Excel (it looks like rows were
69
+ * deleted). Please re-download the template ... Missing: BA1061
70
+ * (PARTHASARTHY YN) - 1022E2"
71
+ *
72
+ * Re-downloading omitted the row again, so there was no way through at all —
73
+ * 21 (context, period) combinations on staging were blocked outright.
74
+ *
75
+ * Both halves now call THIS function, which is the only place the question
76
+ * "which contracts does this period have?" is answered. Duplicating the
77
+ * status filter and the period filter is what let them drift; there is now
78
+ * nothing to keep in step by hand.
79
+ *
80
+ * Period bounds are already IST-shifted; pass null/undefined for either to
81
+ * select without a period filter.
82
+ */
83
+ export declare function selectBAPayoutContractsForPeriod(contracts: IBAContract[] | undefined | null, periodStartIST?: Date | null, periodEndIST?: Date | null): IBAContract[];
84
+ /** A stored contract date as its IST calendar day, `YYYY-MM-DD`. */
85
+ export declare const istDayKey: (value: unknown) => string | null;
86
+ /**
87
+ * A date as it arrives from an uploaded payout sheet, as `YYYY-MM-DD`.
88
+ *
89
+ * The template writes `DD/MM/YYYY`, but a cell a user retyped — or one Excel
90
+ * re-serialised — routinely comes back as `YYYY-MM-DD`, with or without a time
91
+ * part. Both are accepted; anything else is `null` and simply does not match.
92
+ */
93
+ export declare const parseUploadedDayKey: (raw: unknown) => string | null;
94
+ /**
95
+ * Does this uploaded row actually describe a CANCELLED record of its Contract
96
+ * ID, rather than the live record it was resolved to?
97
+ *
98
+ * AD-3098, Jahnavi's original report. `baContractCode` is not unique: on
99
+ * staging `1004E1` exists twice for BA1002 — Surrendered 2025-12-01 - 2026-05-01
100
+ * and Cancelled 2026-05-02 - 2027-03-02, on the same BA and the same vehicle.
101
+ * `resolveBAPayoutContract` deliberately drops the Cancelled record, so a row
102
+ * carrying the Cancelled record's dates was compared against the Surrendered
103
+ * sibling and the user was told
104
+ *
105
+ * "Contract Start Date mismatch. Expected: 01/12/2025, Found: 2026-05-02"
106
+ *
107
+ * which names a contract the row was never about and cannot be satisfied by
108
+ * any edit to the sheet. When the row's own Contract Start Date identifies a
109
+ * Cancelled record instead, the honest message is that the contract is
110
+ * cancelled.
111
+ *
112
+ * The Contract Start Date is the discriminator on purpose: it is the field
113
+ * that differs between records sharing a code, and the only one a hand-built
114
+ * row reliably carries verbatim. But a start date alone does NOT identify a
115
+ * contract, and this check used to rely on it alone — the bug AD-3098's review
116
+ * caught. `candidates` is whatever the caller keyed under the row's Contract
117
+ * ID, and the upload validator keys its map by contract code across the WHOLE
118
+ * context: every BA, every vehicle. So the check could fire on a Cancelled
119
+ * record belonging to some unrelated BA or vehicle that merely started on the
120
+ * same day.
121
+ *
122
+ * That matters because firing is destructive to the rest of the report: the
123
+ * caller then treats the row as having no contract at all and skips the checks
124
+ * for BA linkage, vehicle, city, garage, end date, closure date and working
125
+ * days. A row whose real problem is a wrong BA ID or a wrong vehicle would have
126
+ * been told only "this contract is cancelled" — true of some other BA's
127
+ * contract, and no help at all.
128
+ *
129
+ * So the row must identify the contract on all three parts of its identity —
130
+ * BA ID, Contract ID, vehicle — before a Cancelled record's date match is
131
+ * treated as conclusive. That triple is exactly `selectBAPayoutContracts`'
132
+ * collapse key (`baId|code|vaId`) and exactly what the template emits per row.
133
+ * The comparison is against the row's OWN BA ID and Vehicle columns, not the
134
+ * resolved record's: the whole point is that a row naming the wrong BA or the
135
+ * wrong vehicle must fall through to that error instead of being absorbed here.
136
+ *
137
+ * A row missing either column returns false and is reported as "Missing BA ID"
138
+ * / "Missing Vehicle" — messages the user can act on — rather than being
139
+ * guessed at.
140
+ *
141
+ * What is left is genuinely narrow: it fires only when the row's start date
142
+ * does NOT match the record it resolved to (so only on rows that were going to
143
+ * be reported anyway) and DOES match, exactly, a Cancelled record on the same
144
+ * BA and the same vehicle. It can still displace the date-mismatch messages for
145
+ * such a row, which is the intent; it can no longer displace anything else.
146
+ */
147
+ export interface BAPayoutContractCandidate {
148
+ contract: IBAContract;
149
+ /**
150
+ * The BA ID as the sheet spells it (the BA code sequence, e.g. "BA1002").
151
+ * The contract entity carries only the BA's internal uuid, so the caller
152
+ * that built the code -> contracts map supplies the sheet-level id.
153
+ */
154
+ baId?: unknown;
155
+ }
156
+ /** The three columns that identify which contract an uploaded row is about. */
157
+ export interface BAPayoutUploadedRowIdentity {
158
+ baId?: unknown;
159
+ vehicleRegistration?: unknown;
160
+ contractStartDate?: unknown;
161
+ }
162
+ export declare function uploadedRowNamesCancelledRecord(candidates: readonly BAPayoutContractCandidate[] | undefined | null, resolved: IBAContract | null | undefined, row: BAPayoutUploadedRowIdentity): boolean;
@@ -30,12 +30,27 @@ import { BAContractStatus } from '../../enums/src/index';
30
30
  * the tie-break `groupDuplicateContracts` already uses in the report
31
31
  * builders. Without it the template would print the row twice and the
32
32
  * payout would collect the RM twice.
33
- * 3. The same code on DIFFERENT vehicles stays as separate contracts (BA1000
34
- * has six rows coded '1000' on six vehicles). Those are resolved by the
35
- * vehicle registration carried on the uploaded row, which is the column
36
- * that actually distinguishes them.
33
+ * 3. The same code on DIFFERENT vehicles stays as separate contracts. Those
34
+ * are resolved by the vehicle registration carried on the uploaded row,
35
+ * which is the column that actually distinguishes them.
36
+ *
37
+ * On the scope of the identity: a code bucket here is per business context —
38
+ * the validator builds its map from one context's BAs. Code '1000' exists eight
39
+ * times on staging, but in eight different contexts, one BA and one vehicle
40
+ * each; within any single context no code is currently shared across two BAs or
41
+ * two vehicles (measured 2026-09-28, read-only). The reuse that DOES exist
42
+ * inside a context is AD-3416's: `generateExtendedContractCode()` re-mints the
43
+ * same `E<n>` code on the same BA and the same vehicle. So BA and vehicle are
44
+ * checked defensively, not because the collision is common — but a check that
45
+ * suppresses other checks must not be able to fire on a contract the row is not
46
+ * about. See `uploadedRowNamesCancelledRecord`.
47
+ */
48
+ /**
49
+ * An identifier as a sheet spells it — trimmed and upper-cased. Contract codes
50
+ * and BA IDs are both short, human-typed keys and are compared the same way.
37
51
  */
38
- export const normalizeBAContractCode = (raw) => raw == null ? '' : String(raw).trim().toUpperCase();
52
+ const normalizeSheetIdentifier = (raw) => raw == null ? '' : String(raw).trim().toUpperCase();
53
+ export const normalizeBAContractCode = normalizeSheetIdentifier;
39
54
  /**
40
55
  * Registrations are compared without spaces or punctuation: the template
41
56
  * writes the stored value verbatim, but a user who retypes a cell may enter
@@ -134,4 +149,132 @@ export function resolveBAPayoutContract(candidates, criteria) {
134
149
  : eligible;
135
150
  return pool.reduce((best, c) => (isNewerRecord(c, best) ? c : best));
136
151
  }
152
+ /** IST is UTC+5:30. The BA payout period bounds are stored as the UTC instants
153
+ * of IST month boundaries, so every comparison here is done on the IST shift of
154
+ * both sides — the same arithmetic the payout template, the upload validator
155
+ * and the row calculator have always used. */
156
+ const IST_OFFSET_MS = 5.5 * 60 * 60 * 1000;
157
+ const toIST = (value) => {
158
+ if (value === null || value === undefined || value === '')
159
+ return null;
160
+ const ms = new Date(value).getTime();
161
+ return Number.isNaN(ms) ? null : new Date(ms + IST_OFFSET_MS);
162
+ };
163
+ /**
164
+ * Does this contract overlap the payout period?
165
+ *
166
+ * `periodStartIST` / `periodEndIST` are the period bounds already shifted into
167
+ * IST. A contract with no end date is open-ended and extends past the period.
168
+ * A contract with no *start* date cannot be judged and is kept, so that the
169
+ * template and the upload guard make the same call about it rather than one of
170
+ * them silently dropping it.
171
+ */
172
+ export function isBAPayoutContractInPeriod(contract, periodStartIST, periodEndIST) {
173
+ const startIST = toIST(contract?.[BAContractField.ContractStartDate]);
174
+ if (!startIST)
175
+ return true;
176
+ const endIST = toIST(contract[BAContractField.ContractEndDate]);
177
+ const surrenderIST = toIST(contract[BAContractField.SurrenderEffectiveDate]);
178
+ // Ended, or surrendered, before the period even started.
179
+ if (endIST && endIST < periodStartIST)
180
+ return false;
181
+ if (surrenderIST && surrenderIST < periodStartIST)
182
+ return false;
183
+ // Effective end: the surrender date when it lands inside the period,
184
+ // otherwise the contract end (null = open-ended, still matches).
185
+ const effectiveEnd = surrenderIST && surrenderIST <= periodEndIST ? surrenderIST : endIST;
186
+ return (startIST <= periodEndIST &&
187
+ (effectiveEnd === null || effectiveEnd >= periodStartIST));
188
+ }
189
+ /**
190
+ * The BA contracts that get a row in one payout period's template — and,
191
+ * therefore, exactly the rows the upload's completeness guard may demand back.
192
+ *
193
+ * AD-3098 QA re-open, second round. PR #3951 taught the template generator to
194
+ * run its contracts through `selectBAPayoutContracts` (dropping Cancelled
195
+ * records) but left the "rows were deleted" guard in
196
+ * `process.business.associate.payout.upload.controller.ts` building its
197
+ * expected set straight from `ba.contractDetails` with no status filter. The
198
+ * template then omitted a Cancelled contract and the guard immediately
199
+ * rejected the file the application had just produced:
200
+ *
201
+ * "Some BA rows are missing from the uploaded Excel (it looks like rows were
202
+ * deleted). Please re-download the template ... Missing: BA1061
203
+ * (PARTHASARTHY YN) - 1022E2"
204
+ *
205
+ * Re-downloading omitted the row again, so there was no way through at all —
206
+ * 21 (context, period) combinations on staging were blocked outright.
207
+ *
208
+ * Both halves now call THIS function, which is the only place the question
209
+ * "which contracts does this period have?" is answered. Duplicating the
210
+ * status filter and the period filter is what let them drift; there is now
211
+ * nothing to keep in step by hand.
212
+ *
213
+ * Period bounds are already IST-shifted; pass null/undefined for either to
214
+ * select without a period filter.
215
+ */
216
+ export function selectBAPayoutContractsForPeriod(contracts, periodStartIST, periodEndIST) {
217
+ const eligible = selectBAPayoutContracts(contracts);
218
+ if (!periodStartIST || !periodEndIST)
219
+ return eligible;
220
+ return eligible.filter((contract) => isBAPayoutContractInPeriod(contract, periodStartIST, periodEndIST));
221
+ }
222
+ /** A stored contract date as its IST calendar day, `YYYY-MM-DD`. */
223
+ export const istDayKey = (value) => {
224
+ const ist = toIST(value);
225
+ if (!ist)
226
+ return null;
227
+ const y = ist.getUTCFullYear();
228
+ const m = String(ist.getUTCMonth() + 1).padStart(2, '0');
229
+ const d = String(ist.getUTCDate()).padStart(2, '0');
230
+ return `${y}-${m}-${d}`;
231
+ };
232
+ /**
233
+ * A date as it arrives from an uploaded payout sheet, as `YYYY-MM-DD`.
234
+ *
235
+ * The template writes `DD/MM/YYYY`, but a cell a user retyped — or one Excel
236
+ * re-serialised — routinely comes back as `YYYY-MM-DD`, with or without a time
237
+ * part. Both are accepted; anything else is `null` and simply does not match.
238
+ */
239
+ export const parseUploadedDayKey = (raw) => {
240
+ if (raw === null || raw === undefined)
241
+ return null;
242
+ if (raw instanceof Date)
243
+ return istDayKey(raw);
244
+ const text = String(raw).trim();
245
+ if (!text)
246
+ return null;
247
+ const iso = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[T\s].*)?$/.exec(text);
248
+ if (iso) {
249
+ return `${iso[1]}-${iso[2].padStart(2, '0')}-${iso[3].padStart(2, '0')}`;
250
+ }
251
+ const dmy = /^(\d{1,2})[/-](\d{1,2})[/-](\d{4})$/.exec(text);
252
+ if (dmy) {
253
+ return `${dmy[3]}-${dmy[2].padStart(2, '0')}-${dmy[1].padStart(2, '0')}`;
254
+ }
255
+ return null;
256
+ };
257
+ export function uploadedRowNamesCancelledRecord(candidates, resolved, row) {
258
+ if (!candidates?.length || !resolved)
259
+ return false;
260
+ const rowStart = parseUploadedDayKey(row?.contractStartDate);
261
+ if (!rowStart)
262
+ return false;
263
+ // Only rows the resolved record already contradicts.
264
+ const resolvedStart = istDayKey(resolved[BAContractField.ContractStartDate]);
265
+ if (resolvedStart === null || resolvedStart === rowStart)
266
+ return false;
267
+ // The row has to say WHICH contract it means. Without both identity
268
+ // columns there is nothing to scope against, and guessing is how this
269
+ // check would suppress the very errors that name the missing column.
270
+ const rowBaId = normalizeSheetIdentifier(row?.baId);
271
+ const rowRegistration = normalizeVehicleRegistration(row?.vehicleRegistration);
272
+ if (!rowBaId || !rowRegistration)
273
+ return false;
274
+ return candidates.some(({ contract, baId }) => !!contract &&
275
+ !isBAPayoutEligibleContract(contract) &&
276
+ normalizeSheetIdentifier(baId) === rowBaId &&
277
+ registrationOf(contract) === rowRegistration &&
278
+ istDayKey(contract[BAContractField.ContractStartDate]) === rowStart);
279
+ }
137
280
  //# sourceMappingURL=ba.payout.contract.selection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ba.payout.contract.selection.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/ba.payout.contract.selection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ba.payout.contract.selection.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/ba.payout.contract.selection.ts"],"names":[],"mappings":"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"}
@@ -50,4 +50,5 @@ export * from './financial.year';
50
50
  export * from './vendor.operations.log';
51
51
  export * from './booking.selected.package.gate';
52
52
  export * from './ba.payout.contract.selection';
53
+ export * from './ba.contract.extension.code';
53
54
  export * from './ba.contract.rm.refund';
@@ -50,5 +50,6 @@ export * from './financial.year';
50
50
  export * from './vendor.operations.log';
51
51
  export * from './booking.selected.package.gate';
52
52
  export * from './ba.payout.contract.selection';
53
+ export * from './ba.contract.extension.code';
53
54
  export * from './ba.contract.rm.refund';
54
55
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,OAAO,CAAC;AACtB,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,sBAAsB,CAAC;AACrC,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uCAAuC,CAAC;AACtD,cAAc,mBAAmB,CAAC;AAClC,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,OAAO,CAAC;AACtB,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,sBAAsB,CAAC;AACrC,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uCAAuC,CAAC;AACtD,cAAc,mBAAmB,CAAC;AAClC,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Normalises a raw phone value to E.164 (+91XXXXXXXXXX) format.
2
+ * Normalises a raw phone value to E.164 (`+<country><subscriber>`) format.
3
3
  * Returns null for blank, non-numeric, or out-of-range inputs.
4
- * Default country code is +91 (India).
4
+ * Default country code is +91 (India) — applied only to numbers that do *not*
5
+ * already carry one of their own.
5
6
  *
6
7
  * **Every number handed to the SMS gateway must come through here.** The
7
8
  * gateway refuses anything that is not exactly 13 characters with `91` in
@@ -10,6 +11,16 @@
10
11
  * as a failed SMS log, so the caller is told the message went out and nothing
11
12
  * arrives.
12
13
  *
14
+ * A leading `+` (or the `00` international trunk prefix) is the operator saying
15
+ * "this number already carries its own country code", and is honoured as such.
16
+ * It has to be: every digit-only rule below is length-based, and for a good
17
+ * many countries the country code plus the subscriber number comes to exactly
18
+ * ten digits — Singapore (+65), Australia (+61), Denmark (+45), Norway (+47),
19
+ * New Zealand (+64) among them. Dropping the `+` made `+65-83663164` look like
20
+ * a bare Indian ten-digit number, so it went out as `+916583663164`: a number
21
+ * that does not belong to the guest and may well belong to somebody else
22
+ * (ZD-71141).
23
+ *
13
24
  * Lives in the shared package rather than beside the alert handlers because the
14
25
  * gatekeeper's OTP paths need it too, and a second copy over there is how the
15
26
  * two would drift apart on which shapes they accept.
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Normalises a raw phone value to E.164 (+91XXXXXXXXXX) format.
2
+ * Normalises a raw phone value to E.164 (`+<country><subscriber>`) format.
3
3
  * Returns null for blank, non-numeric, or out-of-range inputs.
4
- * Default country code is +91 (India).
4
+ * Default country code is +91 (India) — applied only to numbers that do *not*
5
+ * already carry one of their own.
5
6
  *
6
7
  * **Every number handed to the SMS gateway must come through here.** The
7
8
  * gateway refuses anything that is not exactly 13 characters with `91` in
@@ -10,10 +11,23 @@
10
11
  * as a failed SMS log, so the caller is told the message went out and nothing
11
12
  * arrives.
12
13
  *
14
+ * A leading `+` (or the `00` international trunk prefix) is the operator saying
15
+ * "this number already carries its own country code", and is honoured as such.
16
+ * It has to be: every digit-only rule below is length-based, and for a good
17
+ * many countries the country code plus the subscriber number comes to exactly
18
+ * ten digits — Singapore (+65), Australia (+61), Denmark (+45), Norway (+47),
19
+ * New Zealand (+64) among them. Dropping the `+` made `+65-83663164` look like
20
+ * a bare Indian ten-digit number, so it went out as `+916583663164`: a number
21
+ * that does not belong to the guest and may well belong to somebody else
22
+ * (ZD-71141).
23
+ *
13
24
  * Lives in the shared package rather than beside the alert handlers because the
14
25
  * gatekeeper's OTP paths need it too, and a second copy over there is how the
15
26
  * two would drift apart on which shapes they accept.
16
27
  */
28
+ /** Longest and shortest digit strings E.164 allows. */
29
+ const MIN_E164_DIGITS = 10;
30
+ const MAX_E164_DIGITS = 15;
17
31
  export function normalizePhoneNumber(phone, countryCode = '+91') {
18
32
  if (phone === null || phone === undefined) {
19
33
  return null;
@@ -27,6 +41,19 @@ export function normalizePhoneNumber(phone, countryCode = '+91') {
27
41
  if (!digits) {
28
42
  return null;
29
43
  }
44
+ // Brackets, spaces and hyphens are decoration; the `+` is not. Strip the
45
+ // decoration first so `(+91) 1234567890` is recognised as carrying a code.
46
+ const marker = raw.replace(/[^\d+]/g, '');
47
+ const carriesOwnCountryCode = marker.startsWith('+') || /^00[1-9]/.test(marker);
48
+ if (carriesOwnCountryCode) {
49
+ // `+` and `00` are alternative spellings of the same thing, and no
50
+ // country code starts with a zero, so any leading zeros are prefix.
51
+ const international = digits.replace(/^0+/, '');
52
+ return international.length >= MIN_E164_DIGITS &&
53
+ international.length <= MAX_E164_DIGITS
54
+ ? `+${international}`
55
+ : null;
56
+ }
30
57
  if (digits.length === 10) {
31
58
  return `+${ccDigits}${digits}`;
32
59
  }
@@ -37,7 +64,7 @@ export function normalizePhoneNumber(phone, countryCode = '+91') {
37
64
  if (noLeadingZero.length === 10) {
38
65
  return `+${ccDigits}${noLeadingZero}`;
39
66
  }
40
- if (digits.length >= 10 && digits.length <= 15) {
67
+ if (digits.length >= MIN_E164_DIGITS && digits.length <= MAX_E164_DIGITS) {
41
68
  return `+${digits}`;
42
69
  }
43
70
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.phone.number.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/normalize.phone.number.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CACnC,KAAyC,EACzC,cAAsB,KAAK;IAE3B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,OAAO,IAAI,QAAQ,GAAG,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,MAAM,EAAE,CAAC;IACrB,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,aAAa,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACjC,OAAO,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAChD,OAAO,IAAI,MAAM,EAAE,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"normalize.phone.number.js","sourceRoot":"","sources":["../../../../../../../libs/shared/src/lib/utilities/src/normalize.phone.number.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,uDAAuD;AACvD,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,MAAM,UAAU,oBAAoB,CACnC,KAAyC,EACzC,cAAsB,KAAK;IAE3B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACb,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,qBAAqB,GAC1B,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEnD,IAAI,qBAAqB,EAAE,CAAC;QAC3B,mEAAmE;QACnE,oEAAoE;QACpE,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChD,OAAO,aAAa,CAAC,MAAM,IAAI,eAAe;YAC7C,aAAa,CAAC,MAAM,IAAI,eAAe;YACvC,CAAC,CAAC,IAAI,aAAa,EAAE;YACrB,CAAC,CAAC,IAAI,CAAC;IACT,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,OAAO,IAAI,QAAQ,GAAG,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,MAAM,EAAE,CAAC;IACrB,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,aAAa,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACjC,OAAO,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,EAAE,CAAC;QAC1E,OAAO,IAAI,MAAM,EAAE,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}