@open-mercato/core 0.9.1-develop.7466.1.2b0cea0016 → 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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/sales/commands/documents.js +6 -3
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/lib/convertedOrderTotals.js +51 -0
- package/dist/modules/sales/lib/convertedOrderTotals.js.map +7 -0
- package/package.json +7 -7
- package/src/modules/sales/commands/documents.ts +6 -3
- package/src/modules/sales/lib/convertedOrderTotals.ts +79 -0
|
@@ -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.
|
|
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.
|
|
268
|
-
"@open-mercato/shared": "0.9.1-develop.
|
|
269
|
-
"@open-mercato/ui": "0.9.1-develop.
|
|
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.
|
|
275
|
-
"@open-mercato/shared": "0.9.1-develop.
|
|
276
|
-
"@open-mercato/ui": "0.9.1-develop.
|
|
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
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
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
|
+
}
|