@open-mercato/core 0.9.1-develop.7467.1.3b2bb92d47 → 0.9.1-develop.7468.1.7ea720142b

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.
@@ -0,0 +1,51 @@
1
+ import { rebuildDocumentResult } from "./calculations.js";
2
+ const FEE_KINDS = /* @__PURE__ */ new Set(["shipping", "surcharge"]);
3
+ function parseStoredAmount(value) {
4
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
5
+ if (typeof value === "string" && value.trim().length) {
6
+ const parsed = Number(value);
7
+ return Number.isFinite(parsed) ? parsed : null;
8
+ }
9
+ return null;
10
+ }
11
+ function readSnapshotAmount(totalsSnapshot, key) {
12
+ if (!totalsSnapshot || typeof totalsSnapshot !== "object" || Array.isArray(totalsSnapshot)) return null;
13
+ const value = totalsSnapshot[key];
14
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
15
+ }
16
+ function isOrderScopedFee(adjustment) {
17
+ return FEE_KINDS.has(adjustment.kind) && (!adjustment.scope || adjustment.scope === "order");
18
+ }
19
+ function toFeeDraft(adjustment) {
20
+ return {
21
+ scope: "order",
22
+ kind: adjustment.kind,
23
+ amountNet: parseStoredAmount(adjustment.amountNet),
24
+ amountGross: parseStoredAmount(adjustment.amountGross),
25
+ position: adjustment.position ?? 0
26
+ };
27
+ }
28
+ function resolveConvertedOrderFeeTotals(params) {
29
+ const derived = rebuildDocumentResult({
30
+ documentKind: "order",
31
+ currencyCode: params.currencyCode,
32
+ lines: [],
33
+ adjustments: params.adjustments.filter(isOrderScopedFee).map(toFeeDraft)
34
+ }).totals;
35
+ const snapshotShippingNet = readSnapshotAmount(params.totalsSnapshot, "shippingNetAmount");
36
+ const snapshotShippingGross = readSnapshotAmount(params.totalsSnapshot, "shippingGrossAmount");
37
+ const snapshotSurcharge = readSnapshotAmount(params.totalsSnapshot, "surchargeTotalAmount");
38
+ const shippingFromSnapshot = snapshotShippingNet !== null && snapshotShippingGross !== null;
39
+ const shippingNet = shippingFromSnapshot ? snapshotShippingNet : derived.shippingNetAmount ?? 0;
40
+ const shippingGross = shippingFromSnapshot ? snapshotShippingGross : derived.shippingGrossAmount ?? 0;
41
+ const surcharge = snapshotSurcharge ?? derived.surchargeTotalAmount ?? 0;
42
+ return {
43
+ shippingNetAmount: shippingNet.toString(),
44
+ shippingGrossAmount: shippingGross.toString(),
45
+ surchargeTotalAmount: surcharge.toString()
46
+ };
47
+ }
48
+ export {
49
+ resolveConvertedOrderFeeTotals
50
+ };
51
+ //# sourceMappingURL=convertedOrderTotals.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/sales/lib/convertedOrderTotals.ts"],
4
+ "sourcesContent": ["import { rebuildDocumentResult } from './calculations'\nimport type { SalesAdjustmentDraft } from './types'\n\nexport type ConvertedOrderFeeTotals = {\n shippingNetAmount: string\n shippingGrossAmount: string\n surchargeTotalAmount: string\n}\n\ntype ConvertedOrderFeeAdjustment = {\n scope?: string | null\n kind: string\n amountNet?: unknown\n amountGross?: unknown\n position?: number | null\n}\n\nconst FEE_KINDS = new Set(['shipping', 'surcharge'])\n\nfunction parseStoredAmount(value: unknown): number | null {\n if (typeof value === 'number') return Number.isFinite(value) ? value : null\n if (typeof value === 'string' && value.trim().length) {\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : null\n }\n return null\n}\n\nfunction readSnapshotAmount(totalsSnapshot: unknown, key: keyof ConvertedOrderFeeTotals): number | null {\n if (!totalsSnapshot || typeof totalsSnapshot !== 'object' || Array.isArray(totalsSnapshot)) return null\n const value = (totalsSnapshot as Record<string, unknown>)[key]\n return typeof value === 'number' && Number.isFinite(value) ? value : null\n}\n\nfunction isOrderScopedFee(adjustment: ConvertedOrderFeeAdjustment): boolean {\n return FEE_KINDS.has(adjustment.kind) && (!adjustment.scope || adjustment.scope === 'order')\n}\n\nfunction toFeeDraft(adjustment: ConvertedOrderFeeAdjustment): SalesAdjustmentDraft {\n return {\n scope: 'order',\n kind: adjustment.kind,\n amountNet: parseStoredAmount(adjustment.amountNet),\n amountGross: parseStoredAmount(adjustment.amountGross),\n position: adjustment.position ?? 0,\n }\n}\n\n/**\n * A quote has no shipping / surcharge columns: those buckets live only in its\n * `totalsSnapshot`, written by the same calculation as the grand total the\n * conversion copies. The order does have the columns, so read them from the\n * snapshot, and fall back to the engine's own bucketing of the copied\n * adjustment rows when the snapshot carries no number for them.\n */\nexport function resolveConvertedOrderFeeTotals(params: {\n totalsSnapshot: unknown\n currencyCode: string\n adjustments: ReadonlyArray<ConvertedOrderFeeAdjustment>\n}): ConvertedOrderFeeTotals {\n const derived = rebuildDocumentResult({\n documentKind: 'order',\n currencyCode: params.currencyCode,\n lines: [],\n adjustments: params.adjustments.filter(isOrderScopedFee).map(toFeeDraft),\n }).totals\n const snapshotShippingNet = readSnapshotAmount(params.totalsSnapshot, 'shippingNetAmount')\n const snapshotShippingGross = readSnapshotAmount(params.totalsSnapshot, 'shippingGrossAmount')\n const snapshotSurcharge = readSnapshotAmount(params.totalsSnapshot, 'surchargeTotalAmount')\n const shippingFromSnapshot = snapshotShippingNet !== null && snapshotShippingGross !== null\n const shippingNet = shippingFromSnapshot ? snapshotShippingNet : derived.shippingNetAmount ?? 0\n const shippingGross = shippingFromSnapshot ? snapshotShippingGross : derived.shippingGrossAmount ?? 0\n const surcharge = snapshotSurcharge ?? derived.surchargeTotalAmount ?? 0\n return {\n shippingNetAmount: shippingNet.toString(),\n shippingGrossAmount: shippingGross.toString(),\n surchargeTotalAmount: surcharge.toString(),\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,6BAA6B;AAiBtC,MAAM,YAAY,oBAAI,IAAI,CAAC,YAAY,WAAW,CAAC;AAEnD,SAAS,kBAAkB,OAA+B;AACxD,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,QAAQ;AACpD,UAAM,SAAS,OAAO,KAAK;AAC3B,WAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAAA,EAC5C;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,gBAAyB,KAAmD;AACtG,MAAI,CAAC,kBAAkB,OAAO,mBAAmB,YAAY,MAAM,QAAQ,cAAc,EAAG,QAAO;AACnG,QAAM,QAAS,eAA2C,GAAG;AAC7D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAEA,SAAS,iBAAiB,YAAkD;AAC1E,SAAO,UAAU,IAAI,WAAW,IAAI,MAAM,CAAC,WAAW,SAAS,WAAW,UAAU;AACtF;AAEA,SAAS,WAAW,YAA+D;AACjF,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,WAAW;AAAA,IACjB,WAAW,kBAAkB,WAAW,SAAS;AAAA,IACjD,aAAa,kBAAkB,WAAW,WAAW;AAAA,IACrD,UAAU,WAAW,YAAY;AAAA,EACnC;AACF;AASO,SAAS,+BAA+B,QAInB;AAC1B,QAAM,UAAU,sBAAsB;AAAA,IACpC,cAAc;AAAA,IACd,cAAc,OAAO;AAAA,IACrB,OAAO,CAAC;AAAA,IACR,aAAa,OAAO,YAAY,OAAO,gBAAgB,EAAE,IAAI,UAAU;AAAA,EACzE,CAAC,EAAE;AACH,QAAM,sBAAsB,mBAAmB,OAAO,gBAAgB,mBAAmB;AACzF,QAAM,wBAAwB,mBAAmB,OAAO,gBAAgB,qBAAqB;AAC7F,QAAM,oBAAoB,mBAAmB,OAAO,gBAAgB,sBAAsB;AAC1F,QAAM,uBAAuB,wBAAwB,QAAQ,0BAA0B;AACvF,QAAM,cAAc,uBAAuB,sBAAsB,QAAQ,qBAAqB;AAC9F,QAAM,gBAAgB,uBAAuB,wBAAwB,QAAQ,uBAAuB;AACpG,QAAM,YAAY,qBAAqB,QAAQ,wBAAwB;AACvE,SAAO;AAAA,IACL,mBAAmB,YAAY,SAAS;AAAA,IACxC,qBAAqB,cAAc,SAAS;AAAA,IAC5C,sBAAsB,UAAU,SAAS;AAAA,EAC3C;AACF;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.9.1-develop.7467.1.3b2bb92d47",
3
+ "version": "0.9.1-develop.7468.1.7ea720142b",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -264,16 +264,16 @@
264
264
  "zod": "^4.4.3"
265
265
  },
266
266
  "peerDependencies": {
267
- "@open-mercato/ai-assistant": "0.9.1-develop.7467.1.3b2bb92d47",
268
- "@open-mercato/shared": "0.9.1-develop.7467.1.3b2bb92d47",
269
- "@open-mercato/ui": "0.9.1-develop.7467.1.3b2bb92d47",
267
+ "@open-mercato/ai-assistant": "0.9.1-develop.7468.1.7ea720142b",
268
+ "@open-mercato/shared": "0.9.1-develop.7468.1.7ea720142b",
269
+ "@open-mercato/ui": "0.9.1-develop.7468.1.7ea720142b",
270
270
  "react": "^19.0.0",
271
271
  "react-dom": "^19.0.0"
272
272
  },
273
273
  "devDependencies": {
274
- "@open-mercato/ai-assistant": "0.9.1-develop.7467.1.3b2bb92d47",
275
- "@open-mercato/shared": "0.9.1-develop.7467.1.3b2bb92d47",
276
- "@open-mercato/ui": "0.9.1-develop.7467.1.3b2bb92d47",
274
+ "@open-mercato/ai-assistant": "0.9.1-develop.7468.1.7ea720142b",
275
+ "@open-mercato/shared": "0.9.1-develop.7468.1.7ea720142b",
276
+ "@open-mercato/ui": "0.9.1-develop.7468.1.7ea720142b",
277
277
  "@testing-library/dom": "^10.4.1",
278
278
  "@testing-library/jest-dom": "^7.0.1",
279
279
  "@testing-library/react": "^16.3.3",
@@ -122,6 +122,7 @@ import {
122
122
  restorePaymentSnapshot,
123
123
  type PaymentSnapshot,
124
124
  } from "./payments";
125
+ import { resolveConvertedOrderFeeTotals } from "../lib/convertedOrderTotals";
125
126
  import type { SalesCalculationService } from "../services/salesCalculationService";
126
127
  import type { TaxCalculationService } from "../services/taxCalculationService";
127
128
  import type {
@@ -6871,9 +6872,11 @@ const convertQuoteToOrderCommand: CommandHandler<
6871
6872
  subtotalGrossAmount: snapshot.quote.subtotalGrossAmount,
6872
6873
  discountTotalAmount: snapshot.quote.discountTotalAmount,
6873
6874
  taxTotalAmount: snapshot.quote.taxTotalAmount,
6874
- shippingNetAmount: "0",
6875
- shippingGrossAmount: "0",
6876
- surchargeTotalAmount: "0",
6875
+ ...resolveConvertedOrderFeeTotals({
6876
+ totalsSnapshot: snapshot.quote.totalsSnapshot,
6877
+ currencyCode: snapshot.quote.currencyCode,
6878
+ adjustments: snapshot.adjustments,
6879
+ }),
6877
6880
  grandTotalNetAmount: snapshot.quote.grandTotalNetAmount,
6878
6881
  grandTotalGrossAmount: snapshot.quote.grandTotalGrossAmount,
6879
6882
  paidTotalAmount: "0",
@@ -0,0 +1,79 @@
1
+ import { rebuildDocumentResult } from './calculations'
2
+ import type { SalesAdjustmentDraft } from './types'
3
+
4
+ export type ConvertedOrderFeeTotals = {
5
+ shippingNetAmount: string
6
+ shippingGrossAmount: string
7
+ surchargeTotalAmount: string
8
+ }
9
+
10
+ type ConvertedOrderFeeAdjustment = {
11
+ scope?: string | null
12
+ kind: string
13
+ amountNet?: unknown
14
+ amountGross?: unknown
15
+ position?: number | null
16
+ }
17
+
18
+ const FEE_KINDS = new Set(['shipping', 'surcharge'])
19
+
20
+ function parseStoredAmount(value: unknown): number | null {
21
+ if (typeof value === 'number') return Number.isFinite(value) ? value : null
22
+ if (typeof value === 'string' && value.trim().length) {
23
+ const parsed = Number(value)
24
+ return Number.isFinite(parsed) ? parsed : null
25
+ }
26
+ return null
27
+ }
28
+
29
+ function readSnapshotAmount(totalsSnapshot: unknown, key: keyof ConvertedOrderFeeTotals): number | null {
30
+ if (!totalsSnapshot || typeof totalsSnapshot !== 'object' || Array.isArray(totalsSnapshot)) return null
31
+ const value = (totalsSnapshot as Record<string, unknown>)[key]
32
+ return typeof value === 'number' && Number.isFinite(value) ? value : null
33
+ }
34
+
35
+ function isOrderScopedFee(adjustment: ConvertedOrderFeeAdjustment): boolean {
36
+ return FEE_KINDS.has(adjustment.kind) && (!adjustment.scope || adjustment.scope === 'order')
37
+ }
38
+
39
+ function toFeeDraft(adjustment: ConvertedOrderFeeAdjustment): SalesAdjustmentDraft {
40
+ return {
41
+ scope: 'order',
42
+ kind: adjustment.kind,
43
+ amountNet: parseStoredAmount(adjustment.amountNet),
44
+ amountGross: parseStoredAmount(adjustment.amountGross),
45
+ position: adjustment.position ?? 0,
46
+ }
47
+ }
48
+
49
+ /**
50
+ * A quote has no shipping / surcharge columns: those buckets live only in its
51
+ * `totalsSnapshot`, written by the same calculation as the grand total the
52
+ * conversion copies. The order does have the columns, so read them from the
53
+ * snapshot, and fall back to the engine's own bucketing of the copied
54
+ * adjustment rows when the snapshot carries no number for them.
55
+ */
56
+ export function resolveConvertedOrderFeeTotals(params: {
57
+ totalsSnapshot: unknown
58
+ currencyCode: string
59
+ adjustments: ReadonlyArray<ConvertedOrderFeeAdjustment>
60
+ }): ConvertedOrderFeeTotals {
61
+ const derived = rebuildDocumentResult({
62
+ documentKind: 'order',
63
+ currencyCode: params.currencyCode,
64
+ lines: [],
65
+ adjustments: params.adjustments.filter(isOrderScopedFee).map(toFeeDraft),
66
+ }).totals
67
+ const snapshotShippingNet = readSnapshotAmount(params.totalsSnapshot, 'shippingNetAmount')
68
+ const snapshotShippingGross = readSnapshotAmount(params.totalsSnapshot, 'shippingGrossAmount')
69
+ const snapshotSurcharge = readSnapshotAmount(params.totalsSnapshot, 'surchargeTotalAmount')
70
+ const shippingFromSnapshot = snapshotShippingNet !== null && snapshotShippingGross !== null
71
+ const shippingNet = shippingFromSnapshot ? snapshotShippingNet : derived.shippingNetAmount ?? 0
72
+ const shippingGross = shippingFromSnapshot ? snapshotShippingGross : derived.shippingGrossAmount ?? 0
73
+ const surcharge = snapshotSurcharge ?? derived.surchargeTotalAmount ?? 0
74
+ return {
75
+ shippingNetAmount: shippingNet.toString(),
76
+ shippingGrossAmount: shippingGross.toString(),
77
+ surchargeTotalAmount: surcharge.toString(),
78
+ }
79
+ }