@dainamite/cpq 0.6.0 → 0.7.0
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/CHANGELOG.md +16 -0
- package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js +3 -9
- package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js +21 -25
- package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js +48 -47
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js +1 -1
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/shared.js +37 -2
- package/dist/modules/cpq/backend/cpq/inventory/shared.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +154 -178
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js +1 -1
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js +168 -143
- package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/offerings/page.js +36 -34
- package/dist/modules/cpq/backend/cpq/offerings/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +69 -66
- package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/orders/page.js +6 -6
- package/dist/modules/cpq/backend/cpq/orders/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js +41 -36
- package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js +76 -72
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js +1 -1
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/price-rules/page.js +18 -15
- package/dist/modules/cpq/backend/cpq/price-rules/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js +23 -21
- package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js +22 -50
- package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js +74 -52
- package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js +20 -17
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/pricing/page.js +1 -1
- package/dist/modules/cpq/backend/cpq/pricing/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js +115 -123
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js +6 -3
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +129 -94
- package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/quotes/page.js +23 -19
- package/dist/modules/cpq/backend/cpq/quotes/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js +19 -15
- package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js +171 -178
- package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/specifications/page.js +2 -2
- package/dist/modules/cpq/backend/cpq/specifications/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js +60 -50
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js +22 -18
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js.map +2 -2
- package/dist/modules/cpq/backend/cpq/wizards/page.js +1 -1
- package/dist/modules/cpq/backend/cpq/wizards/page.js.map +2 -2
- package/dist/modules/cpq/components/ArcLineDiff.js +2 -2
- package/dist/modules/cpq/components/ArcLineDiff.js.map +2 -2
- package/dist/modules/cpq/components/ChargeBreakdownTable.js +4 -10
- package/dist/modules/cpq/components/ChargeBreakdownTable.js.map +2 -2
- package/dist/modules/cpq/components/PriceWaterfall.js +3 -1
- package/dist/modules/cpq/components/PriceWaterfall.js.map +2 -2
- package/dist/modules/cpq/components/PricingSummaryCard.js +1 -6
- package/dist/modules/cpq/components/PricingSummaryCard.js.map +2 -2
- package/dist/modules/cpq/components/StatusPath.js +5 -3
- package/dist/modules/cpq/components/StatusPath.js.map +2 -2
- package/dist/modules/cpq/components/useCpqRowActions.js +10 -22
- package/dist/modules/cpq/components/useCpqRowActions.js.map +2 -2
- package/dist/modules/cpq/i18n/de.json +1220 -0
- package/dist/modules/cpq/i18n/en.json +1220 -0
- package/dist/modules/cpq/i18n/es.json +1220 -0
- package/dist/modules/cpq/i18n/pl.json +1220 -0
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js +39 -31
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js.map +2 -2
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js +13 -5
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js.map +2 -2
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js +41 -21
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js.map +2 -2
- package/dist/modules/cpq/widgets/injection-table.js +2 -2
- package/dist/modules/cpq/widgets/injection-table.js.map +2 -2
- package/dist/modules/cpq/workflows/WizardRunner.js +10 -8
- package/dist/modules/cpq/workflows/WizardRunner.js.map +2 -2
- package/dist/modules/cpq/workflows/WizardTrigger.js +15 -9
- package/dist/modules/cpq/workflows/WizardTrigger.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js +9 -7
- package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/InventorySelectStep.js +9 -4
- package/dist/modules/cpq/workflows/steps/InventorySelectStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/ItemListStep.js +16 -19
- package/dist/modules/cpq/workflows/steps/ItemListStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js +19 -32
- package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js +8 -6
- package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/ReviewStep.js +32 -30
- package/dist/modules/cpq/workflows/steps/ReviewStep.js.map +2 -2
- package/dist/modules/cpq/workflows/steps/index.js +12 -0
- package/dist/modules/cpq/workflows/steps/index.js.map +2 -2
- package/package.json +1 -1
- package/src/modules/cpq/__tests__/i18n/dictionaries.test.ts +62 -0
- package/src/modules/cpq/__tests__/i18n/hardcodedStrings.test.ts +35 -0
- package/src/modules/cpq/__tests__/i18n/sourceScan.ts +109 -0
- package/src/modules/cpq/backend/cpq/inventory/AssetsTable.tsx +3 -9
- package/src/modules/cpq/backend/cpq/inventory/SubscriptionsTable.tsx +22 -26
- package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.ts +1 -1
- package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.tsx +43 -46
- package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +2 -2
- package/src/modules/cpq/backend/cpq/inventory/shared.tsx +37 -1
- package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.ts +1 -1
- package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +134 -112
- package/src/modules/cpq/backend/cpq/offerings/[id]/page.tsx +169 -130
- package/src/modules/cpq/backend/cpq/offerings/page.tsx +34 -24
- package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +66 -43
- package/src/modules/cpq/backend/cpq/orders/page.tsx +6 -6
- package/src/modules/cpq/backend/cpq/price-rules/PriceRuleForm.tsx +48 -34
- package/src/modules/cpq/backend/cpq/price-rules/[id]/page.meta.ts +1 -1
- package/src/modules/cpq/backend/cpq/price-rules/[id]/page.tsx +76 -70
- package/src/modules/cpq/backend/cpq/price-rules/page.tsx +25 -16
- package/src/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.tsx +24 -18
- package/src/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.tsx +29 -19
- package/src/modules/cpq/backend/cpq/pricing/[id]/page.tsx +95 -47
- package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.ts +23 -15
- package/src/modules/cpq/backend/cpq/pricing/page.tsx +1 -1
- package/src/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.tsx +111 -88
- package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.tsx +3 -3
- package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +134 -89
- package/src/modules/cpq/backend/cpq/quotes/page.tsx +29 -21
- package/src/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.tsx +19 -15
- package/src/modules/cpq/backend/cpq/specifications/[id]/page.tsx +171 -171
- package/src/modules/cpq/backend/cpq/specifications/page.tsx +2 -2
- package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.tsx +51 -41
- package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/page.tsx +17 -13
- package/src/modules/cpq/backend/cpq/wizards/page.tsx +1 -1
- package/src/modules/cpq/components/ArcLineDiff.tsx +2 -2
- package/src/modules/cpq/components/ChargeBreakdownTable.tsx +4 -2
- package/src/modules/cpq/components/PriceWaterfall.tsx +4 -2
- package/src/modules/cpq/components/PricingSummaryCard.tsx +1 -1
- package/src/modules/cpq/components/StatusPath.tsx +7 -4
- package/src/modules/cpq/components/useCpqRowActions.tsx +17 -25
- package/src/modules/cpq/i18n/de.json +1220 -0
- package/src/modules/cpq/i18n/en.json +1220 -0
- package/src/modules/cpq/i18n/es.json +1220 -0
- package/src/modules/cpq/i18n/pl.json +1220 -0
- package/src/modules/cpq/widgets/injection/customer-inventory/widget.client.tsx +38 -31
- package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.client.tsx +7 -5
- package/src/modules/cpq/widgets/injection/quote-configurator/widget.client.tsx +36 -21
- package/src/modules/cpq/widgets/injection-table.ts +8 -2
- package/src/modules/cpq/workflows/WizardRunner.tsx +8 -5
- package/src/modules/cpq/workflows/WizardTrigger.tsx +15 -9
- package/src/modules/cpq/workflows/steps/CustomerSelectStep.tsx +11 -7
- package/src/modules/cpq/workflows/steps/InventorySelectStep.tsx +9 -5
- package/src/modules/cpq/workflows/steps/ItemListStep.tsx +18 -12
- package/src/modules/cpq/workflows/steps/OfferingSelectStep.tsx +20 -16
- package/src/modules/cpq/workflows/steps/ProductConfigureStep.tsx +8 -6
- package/src/modules/cpq/workflows/steps/ReviewStep.tsx +33 -18
- package/src/modules/cpq/workflows/steps/index.ts +12 -0
- package/src/modules/cpq/workflows/types.ts +4 -0
|
@@ -2,25 +2,36 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useRouter, useParams } from "next/navigation";
|
|
5
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
5
6
|
import { Alert } from "@open-mercato/ui/primitives/alert";
|
|
6
7
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
7
8
|
import { Tag } from "@open-mercato/ui/primitives/tag";
|
|
8
9
|
import { FormHeader } from "@open-mercato/ui/backend/forms";
|
|
9
10
|
import {
|
|
10
|
-
formatStatusLabel,
|
|
11
11
|
subscriptionStatusMap
|
|
12
12
|
} from "../../../../../components/statusMaps.js";
|
|
13
13
|
import { StatusPath } from "../../../../../components/StatusPath.js";
|
|
14
14
|
import { DepthBadge, PriceWaterfall } from "../../../../../components/PriceWaterfall.js";
|
|
15
15
|
import { parseStoredCharge } from "../../../../../lib/priceAdjustmentView.js";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
import { buildInventoryStatusLabels, inventoryStatusLabel } from "../../shared.js";
|
|
17
|
+
function changeTypeLabel(t, changeType) {
|
|
18
|
+
switch (changeType) {
|
|
19
|
+
case "created":
|
|
20
|
+
return t("cpq.inventory.subscriptions.detail.changeType.created", "Created");
|
|
21
|
+
case "amend":
|
|
22
|
+
return t("cpq.inventory.subscriptions.detail.changeType.amend", "Amended");
|
|
23
|
+
case "renew":
|
|
24
|
+
return t("cpq.inventory.subscriptions.detail.changeType.renew", "Renewed");
|
|
25
|
+
case "cancel":
|
|
26
|
+
return t("cpq.inventory.subscriptions.detail.changeType.cancel", "Cancelled");
|
|
27
|
+
case "merge-result":
|
|
28
|
+
return t("cpq.inventory.subscriptions.detail.changeType.mergeResult", "Created from merging contracts");
|
|
29
|
+
case "merge-source":
|
|
30
|
+
return t("cpq.inventory.subscriptions.detail.changeType.mergeSource", "Merged into a new contract");
|
|
31
|
+
default:
|
|
32
|
+
return changeType;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
24
35
|
const CHANGE_TYPE_VARIANTS = {
|
|
25
36
|
created: "neutral",
|
|
26
37
|
amend: "info",
|
|
@@ -36,20 +47,16 @@ const ALLOWED_TRANSITIONS = {
|
|
|
36
47
|
terminated: [],
|
|
37
48
|
expired: []
|
|
38
49
|
};
|
|
39
|
-
const
|
|
40
|
-
pending: "Pending",
|
|
41
|
-
active: "Active",
|
|
42
|
-
suspended: "Suspended",
|
|
43
|
-
terminated: "Terminated",
|
|
44
|
-
expired: "Expired"
|
|
45
|
-
};
|
|
50
|
+
const SUBSCRIPTION_STATUSES = ["pending", "active", "suspended", "terminated", "expired"];
|
|
46
51
|
function fmt(amount, currency) {
|
|
47
52
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(Number(amount));
|
|
48
53
|
}
|
|
49
54
|
function StatusBadge({ status }) {
|
|
50
|
-
|
|
55
|
+
const t = useT();
|
|
56
|
+
return /* @__PURE__ */ jsx(Tag, { variant: subscriptionStatusMap[status] ?? "neutral", dot: true, children: inventoryStatusLabel(t, status) });
|
|
51
57
|
}
|
|
52
58
|
function SubscriptionDetailPage(props) {
|
|
59
|
+
const t = useT();
|
|
53
60
|
const router = useRouter();
|
|
54
61
|
const urlParams = useParams();
|
|
55
62
|
const subId = props.params?.id ?? urlParams?.id;
|
|
@@ -84,16 +91,16 @@ function SubscriptionDetailPage(props) {
|
|
|
84
91
|
const body = await res.json().catch(() => ({}));
|
|
85
92
|
if (body.existingQuoteId) {
|
|
86
93
|
const ok = window.confirm(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
t("cpq.inventory.subscriptions.detail.arc.existingQuoteConfirm", "{error}\n\nOpen the existing quote now?", {
|
|
95
|
+
error: body.error ?? t("cpq.inventory.subscriptions.detail.arc.existingQuoteInProgress", "Subscription has another ARC quote in progress.")
|
|
96
|
+
})
|
|
90
97
|
);
|
|
91
98
|
if (ok) {
|
|
92
99
|
router.push(`/backend/cpq/quotes/${body.existingQuoteId}`);
|
|
93
100
|
}
|
|
94
101
|
return;
|
|
95
102
|
}
|
|
96
|
-
alert(
|
|
103
|
+
alert(t("cpq.inventory.subscriptions.detail.arc.startFailed", "Failed to start {type} quote: {error}", { type, error: body.error ?? res.statusText }));
|
|
97
104
|
return;
|
|
98
105
|
}
|
|
99
106
|
const data = await res.json();
|
|
@@ -102,7 +109,7 @@ Open the existing quote now?`
|
|
|
102
109
|
setArcInFlight(null);
|
|
103
110
|
}
|
|
104
111
|
},
|
|
105
|
-
[router, sub]
|
|
112
|
+
[router, sub, t]
|
|
106
113
|
);
|
|
107
114
|
const transitionStatus = async (targetStatus) => {
|
|
108
115
|
if (!sub) return;
|
|
@@ -115,7 +122,7 @@ Open the existing quote now?`
|
|
|
115
122
|
body: JSON.stringify({ id: sub.id, targetStatus })
|
|
116
123
|
});
|
|
117
124
|
const data = await res.json();
|
|
118
|
-
if (!res.ok) throw new Error(data?.error ?? "Status transition failed");
|
|
125
|
+
if (!res.ok) throw new Error(data?.error ?? t("cpq.inventory.subscriptions.detail.error.transitionFailed", "Status transition failed"));
|
|
119
126
|
const [freshSub, freshAssets] = await Promise.all([
|
|
120
127
|
fetch(`/api/cpq/inventory/subscriptions?id=${sub.id}`).then((r) => r.ok ? r.json() : null),
|
|
121
128
|
fetch(`/api/cpq/inventory/assets?subscriptionId=${sub.id}&pageSize=50`).then((r) => r.ok ? r.json() : null).then((r) => r?.items ?? [])
|
|
@@ -175,7 +182,7 @@ Open the existing quote now?`
|
|
|
175
182
|
async function load() {
|
|
176
183
|
try {
|
|
177
184
|
const res = await fetch(`/api/cpq/inventory/subscriptions?id=${subId}`);
|
|
178
|
-
if (!res.ok) throw new Error("Subscription not found");
|
|
185
|
+
if (!res.ok) throw new Error(t("cpq.inventory.subscriptions.detail.error.notFound", "Subscription not found"));
|
|
179
186
|
const data = await res.json();
|
|
180
187
|
if (!cancelled) {
|
|
181
188
|
setSub(data);
|
|
@@ -240,7 +247,7 @@ Open the existing quote now?`
|
|
|
240
247
|
return () => {
|
|
241
248
|
cancelled = true;
|
|
242
249
|
};
|
|
243
|
-
}, [subId]);
|
|
250
|
+
}, [subId, t]);
|
|
244
251
|
const toggleItem = (id) => {
|
|
245
252
|
setExpandedItems((prev) => {
|
|
246
253
|
const n = new Set(prev);
|
|
@@ -251,31 +258,36 @@ Open the existing quote now?`
|
|
|
251
258
|
if (loading) {
|
|
252
259
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 py-12 justify-center text-sm text-muted-foreground", children: [
|
|
253
260
|
/* @__PURE__ */ jsx(Spinner, {}),
|
|
254
|
-
"
|
|
261
|
+
" ",
|
|
262
|
+
t("cpq.inventory.subscriptions.detail.loading", "Loading\u2026")
|
|
255
263
|
] });
|
|
256
264
|
}
|
|
257
265
|
if (!sub) {
|
|
258
266
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
259
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ jsxs("button", { onClick: () => router.push("/backend/cpq/inventory"), className: "text-sm text-muted-foreground hover:text-foreground", children: [
|
|
268
|
+
"\u2190 ",
|
|
269
|
+
t("cpq.common.back", "Back")
|
|
270
|
+
] }),
|
|
260
271
|
error && /* @__PURE__ */ jsx(ErrorBanner, { message: error }),
|
|
261
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground", children: "Subscription not found." })
|
|
272
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.notFound", "Subscription not found.") })
|
|
262
273
|
] });
|
|
263
274
|
}
|
|
264
275
|
const currency = sub.currencyCode || "USD";
|
|
265
276
|
const flatItems = flattenItems(sub.items);
|
|
266
277
|
const canArc = sub.status === "active" || sub.status === "suspended";
|
|
267
278
|
const statusTransitions = ALLOWED_TRANSITIONS[sub.status] ?? [];
|
|
279
|
+
const statusLabels = buildInventoryStatusLabels(t, SUBSCRIPTION_STATUSES);
|
|
268
280
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
269
281
|
/* @__PURE__ */ jsx(
|
|
270
282
|
FormHeader,
|
|
271
283
|
{
|
|
272
284
|
mode: "detail",
|
|
273
285
|
backHref: "/backend/cpq/inventory",
|
|
274
|
-
backLabel: "Back to Customer Inventory",
|
|
275
|
-
entityTypeLabel: "Subscription",
|
|
286
|
+
backLabel: t("cpq.inventory.detail.backToInventory", "Back to Customer Inventory"),
|
|
287
|
+
entityTypeLabel: t("cpq.inventory.subscriptions.detail.entityType", "Subscription"),
|
|
276
288
|
title: sub.name,
|
|
277
289
|
statusBadge: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 pt-1", children: [
|
|
278
|
-
/* @__PURE__ */ jsx(Tag, { variant: subscriptionStatusMap[sub.status] ?? "neutral", dot: true, children:
|
|
290
|
+
/* @__PURE__ */ jsx(Tag, { variant: subscriptionStatusMap[sub.status] ?? "neutral", dot: true, children: inventoryStatusLabel(t, sub.status) }),
|
|
279
291
|
/* @__PURE__ */ jsx(Tag, { variant: "neutral", className: "capitalize", children: sub.billingCycle }),
|
|
280
292
|
transitioning && /* @__PURE__ */ jsx(Spinner, {})
|
|
281
293
|
] }),
|
|
@@ -287,7 +299,7 @@ Open the existing quote now?`
|
|
|
287
299
|
variant: "outline",
|
|
288
300
|
disabled: arcInFlight !== null,
|
|
289
301
|
onClick: () => startArcQuote("amend"),
|
|
290
|
-
children: "Amend"
|
|
302
|
+
children: t("cpq.inventory.subscriptions.detail.arc.amend", "Amend")
|
|
291
303
|
}
|
|
292
304
|
),
|
|
293
305
|
/* @__PURE__ */ jsx(
|
|
@@ -297,7 +309,7 @@ Open the existing quote now?`
|
|
|
297
309
|
variant: "outline",
|
|
298
310
|
disabled: arcInFlight !== null,
|
|
299
311
|
onClick: () => startArcQuote("renew"),
|
|
300
|
-
children: "Renew"
|
|
312
|
+
children: t("cpq.inventory.subscriptions.detail.arc.renew", "Renew")
|
|
301
313
|
}
|
|
302
314
|
),
|
|
303
315
|
/* @__PURE__ */ jsx(
|
|
@@ -307,7 +319,7 @@ Open the existing quote now?`
|
|
|
307
319
|
variant: "destructive-outline",
|
|
308
320
|
disabled: arcInFlight !== null,
|
|
309
321
|
onClick: () => startArcQuote("cancel"),
|
|
310
|
-
children: "Cancel"
|
|
322
|
+
children: t("cpq.inventory.subscriptions.detail.arc.cancel", "Cancel")
|
|
311
323
|
}
|
|
312
324
|
)
|
|
313
325
|
] }) : null
|
|
@@ -320,52 +332,52 @@ Open the existing quote now?`
|
|
|
320
332
|
path: ["pending", "active"],
|
|
321
333
|
terminals: ["suspended", "terminated", "expired"],
|
|
322
334
|
statusMap: subscriptionStatusMap,
|
|
323
|
-
labels:
|
|
335
|
+
labels: statusLabels,
|
|
324
336
|
onTransition: transitionStatus,
|
|
325
337
|
allowedTransitions: statusTransitions,
|
|
326
338
|
disabled: transitioning,
|
|
327
|
-
ariaLabel: "Subscription status path"
|
|
339
|
+
ariaLabel: t("cpq.inventory.subscriptions.detail.statusPath", "Subscription status path")
|
|
328
340
|
}
|
|
329
341
|
) }),
|
|
330
342
|
error && /* @__PURE__ */ jsx(ErrorBanner, { message: error }),
|
|
331
343
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
332
344
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4 space-y-3", children: [
|
|
333
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Subscription Details" }),
|
|
345
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: t("cpq.inventory.subscriptions.detail.sections.details", "Subscription Details") }),
|
|
334
346
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-4 gap-y-2", children: [
|
|
335
|
-
/* @__PURE__ */ jsx(Field, { label: "Code", value: sub.code, mono: true }),
|
|
336
|
-
/* @__PURE__ */ jsx(Field, { label: "Status", value: sub.status }),
|
|
337
|
-
/* @__PURE__ */ jsx(Field, { label: "Billing Cycle", value: sub.billingCycle }),
|
|
338
|
-
/* @__PURE__ */ jsx(Field, { label: "Currency", value: currency }),
|
|
339
|
-
/* @__PURE__ */ jsx(Field, { label: "Auto-Renew", value: sub.autoRenew ? "Yes" : "No" }),
|
|
340
|
-
sub.termMonths != null && /* @__PURE__ */ jsx(Field, { label: "Term", value:
|
|
341
|
-
sub.startDate && /* @__PURE__ */ jsx(Field, { label: "Start Date", value: new Date(sub.startDate).toLocaleDateString() }),
|
|
342
|
-
sub.currentTermEnd && /* @__PURE__ */ jsx(Field, { label: "Term End", value: new Date(sub.currentTermEnd).toLocaleDateString() }),
|
|
343
|
-
sub.activatedAt && /* @__PURE__ */ jsx(Field, { label: "Activated", value: new Date(sub.activatedAt).toLocaleString() }),
|
|
344
|
-
sub.suspendedAt && /* @__PURE__ */ jsx(Field, { label: "Suspended", value: new Date(sub.suspendedAt).toLocaleString() }),
|
|
345
|
-
sub.terminatedAt && /* @__PURE__ */ jsx(Field, { label: "Terminated", value: new Date(sub.terminatedAt).toLocaleString() })
|
|
347
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.code", "Code"), value: sub.code, mono: true }),
|
|
348
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.status", "Status"), value: sub.status }),
|
|
349
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.billingCycle", "Billing Cycle"), value: sub.billingCycle }),
|
|
350
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.currency", "Currency"), value: currency }),
|
|
351
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.autoRenew", "Auto-Renew"), value: sub.autoRenew ? t("cpq.common.yes", "Yes") : t("cpq.common.no", "No") }),
|
|
352
|
+
sub.termMonths != null && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.term", "Term"), value: t("cpq.inventory.subscriptions.detail.fields.termMonths", "{count} months", { count: sub.termMonths }) }),
|
|
353
|
+
sub.startDate && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.startDate", "Start Date"), value: new Date(sub.startDate).toLocaleDateString() }),
|
|
354
|
+
sub.currentTermEnd && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.termEnd", "Term End"), value: new Date(sub.currentTermEnd).toLocaleDateString() }),
|
|
355
|
+
sub.activatedAt && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.activated", "Activated"), value: new Date(sub.activatedAt).toLocaleString() }),
|
|
356
|
+
sub.suspendedAt && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.suspended", "Suspended"), value: new Date(sub.suspendedAt).toLocaleString() }),
|
|
357
|
+
sub.terminatedAt && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.terminated", "Terminated"), value: new Date(sub.terminatedAt).toLocaleString() })
|
|
346
358
|
] }),
|
|
347
359
|
sub.description && /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
|
|
348
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Description" }),
|
|
360
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.fields.description", "Description") }),
|
|
349
361
|
/* @__PURE__ */ jsx("p", { className: "text-sm", children: sub.description })
|
|
350
362
|
] })
|
|
351
363
|
] }),
|
|
352
364
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4 space-y-3", children: [
|
|
353
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Pricing & References" }),
|
|
365
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: t("cpq.inventory.subscriptions.detail.sections.pricing", "Pricing & References") }),
|
|
354
366
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
355
367
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
356
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Monthly Recurring (MRC)" }),
|
|
368
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.fields.mrc", "Monthly Recurring (MRC)") }),
|
|
357
369
|
/* @__PURE__ */ jsx("p", { className: "text-lg font-semibold font-mono", children: fmt(sub.mrcAmount, currency) })
|
|
358
370
|
] }),
|
|
359
371
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
360
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Non-Recurring (NRC)" }),
|
|
372
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.fields.nrc", "Non-Recurring (NRC)") }),
|
|
361
373
|
/* @__PURE__ */ jsx("p", { className: "text-lg font-semibold font-mono", children: fmt(sub.nrcAmount, currency) })
|
|
362
374
|
] })
|
|
363
375
|
] }),
|
|
364
376
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-4 gap-y-2 pt-1", children: [
|
|
365
|
-
/* @__PURE__ */ jsx(Field, { label: "Customer", value: customerName ?? sub.customerId.slice(0, 12) + "\u2026" }),
|
|
366
|
-
/* @__PURE__ */ jsx(Field, { label: "Created", value: new Date(sub.createdAt).toLocaleString() }),
|
|
377
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.customer", "Customer"), value: customerName ?? sub.customerId.slice(0, 12) + "\u2026" }),
|
|
378
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.created", "Created"), value: new Date(sub.createdAt).toLocaleString() }),
|
|
367
379
|
sub.sourceQuoteId && /* @__PURE__ */ jsxs("div", { children: [
|
|
368
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Source Quote" }),
|
|
380
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.fields.sourceQuote", "Source Quote") }),
|
|
369
381
|
/* @__PURE__ */ jsx(
|
|
370
382
|
"button",
|
|
371
383
|
{
|
|
@@ -376,7 +388,7 @@ Open the existing quote now?`
|
|
|
376
388
|
)
|
|
377
389
|
] }),
|
|
378
390
|
sub.sourceOrderId && /* @__PURE__ */ jsxs("div", { children: [
|
|
379
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Source Order" }),
|
|
391
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.fields.sourceOrder", "Source Order") }),
|
|
380
392
|
/* @__PURE__ */ jsx(
|
|
381
393
|
"button",
|
|
382
394
|
{
|
|
@@ -390,7 +402,7 @@ Open the existing quote now?`
|
|
|
390
402
|
] })
|
|
391
403
|
] }),
|
|
392
404
|
sub.metadata && Object.keys(sub.metadata).length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4", children: [
|
|
393
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-2", children: "Metadata" }),
|
|
405
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-2", children: t("cpq.inventory.subscriptions.detail.sections.metadata", "Metadata") }),
|
|
394
406
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-x-4 gap-y-1", children: Object.entries(sub.metadata).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
395
407
|
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
396
408
|
key,
|
|
@@ -400,12 +412,8 @@ Open the existing quote now?`
|
|
|
400
412
|
] }, key)) })
|
|
401
413
|
] }),
|
|
402
414
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
|
|
405
|
-
flatItems.length,
|
|
406
|
-
")"
|
|
407
|
-
] }),
|
|
408
|
-
flatItems.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground", children: "No items." }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card divide-y", children: flatItems.map((item) => {
|
|
415
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-2 px-1", children: t("cpq.inventory.subscriptions.detail.items.title", "Subscription Items ({count})", { count: flatItems.length }) }),
|
|
416
|
+
flatItems.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.items.empty", "No items.") }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card divide-y", children: flatItems.map((item) => {
|
|
409
417
|
const isExpanded = expandedItems.has(item.id);
|
|
410
418
|
const indent = item._depth ?? 0;
|
|
411
419
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -427,11 +435,17 @@ Open the existing quote now?`
|
|
|
427
435
|
] }) }),
|
|
428
436
|
/* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right text-xs space-y-0.5", children: [
|
|
429
437
|
Number(item.mrcAmount) > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
430
|
-
/* @__PURE__ */
|
|
438
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
439
|
+
t("cpq.inventory.subscriptions.detail.items.mrc", "MRC"),
|
|
440
|
+
" "
|
|
441
|
+
] }),
|
|
431
442
|
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium", children: fmt(item.mrcAmount, item.currencyCode || currency) })
|
|
432
443
|
] }),
|
|
433
444
|
Number(item.nrcAmount) > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
434
|
-
/* @__PURE__ */
|
|
445
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
446
|
+
t("cpq.inventory.subscriptions.detail.items.nrc", "NRC"),
|
|
447
|
+
" "
|
|
448
|
+
] }),
|
|
435
449
|
/* @__PURE__ */ jsx("span", { className: "font-mono font-medium", children: fmt(item.nrcAmount, item.currencyCode || currency) })
|
|
436
450
|
] })
|
|
437
451
|
] })
|
|
@@ -443,7 +457,7 @@ Open the existing quote now?`
|
|
|
443
457
|
item.offeringId && /* @__PURE__ */ jsx(
|
|
444
458
|
RefField,
|
|
445
459
|
{
|
|
446
|
-
label: "Offering",
|
|
460
|
+
label: t("cpq.inventory.subscriptions.detail.fields.offering", "Offering"),
|
|
447
461
|
name: offeringNames[item.offeringId],
|
|
448
462
|
fallback: item.offeringId,
|
|
449
463
|
onClick: () => router.push(`/backend/cpq/offerings/${item.offeringId}`)
|
|
@@ -452,7 +466,7 @@ Open the existing quote now?`
|
|
|
452
466
|
item.specId && /* @__PURE__ */ jsx(
|
|
453
467
|
RefField,
|
|
454
468
|
{
|
|
455
|
-
label: "Specification",
|
|
469
|
+
label: t("cpq.inventory.subscriptions.detail.fields.specification", "Specification"),
|
|
456
470
|
name: specNames[item.specId],
|
|
457
471
|
fallback: item.specId,
|
|
458
472
|
onClick: () => router.push(`/backend/cpq/specifications/${item.specId}`)
|
|
@@ -461,18 +475,18 @@ Open the existing quote now?`
|
|
|
461
475
|
item.productId && /* @__PURE__ */ jsx(
|
|
462
476
|
RefField,
|
|
463
477
|
{
|
|
464
|
-
label: "Product",
|
|
478
|
+
label: t("cpq.inventory.subscriptions.detail.fields.product", "Product"),
|
|
465
479
|
name: productNames[item.productId],
|
|
466
480
|
fallback: item.productId,
|
|
467
481
|
onClick: () => router.push(`/backend/catalog/products/${item.productId}`)
|
|
468
482
|
}
|
|
469
483
|
),
|
|
470
|
-
/* @__PURE__ */ jsx(Field, { label: "Currency", value: item.currencyCode || currency }),
|
|
471
|
-
/* @__PURE__ */ jsx(Field, { label: "Quantity", value: String(item.quantity) }),
|
|
472
|
-
item.capacityTotal && /* @__PURE__ */ jsx(Field, { label: "Capacity", value: `${item.capacityUsed ?? "0"} / ${item.capacityTotal} ${item.capacityUnit ?? ""}` })
|
|
484
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.currency", "Currency"), value: item.currencyCode || currency }),
|
|
485
|
+
/* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.quantity", "Quantity"), value: String(item.quantity) }),
|
|
486
|
+
item.capacityTotal && /* @__PURE__ */ jsx(Field, { label: t("cpq.inventory.subscriptions.detail.fields.capacity", "Capacity"), value: `${item.capacityUsed ?? "0"} / ${item.capacityTotal} ${item.capacityUnit ?? ""}` })
|
|
473
487
|
] }),
|
|
474
488
|
item.configuration && Object.keys(item.configuration).length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
475
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Configuration" }),
|
|
489
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: t("cpq.inventory.subscriptions.detail.items.configuration", "Configuration") }),
|
|
476
490
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-x-4 gap-y-1", children: Object.entries(item.configuration).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
477
491
|
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
478
492
|
key,
|
|
@@ -482,15 +496,15 @@ Open the existing quote now?`
|
|
|
482
496
|
] }, key)) })
|
|
483
497
|
] }),
|
|
484
498
|
item.charges && item.charges.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
485
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Charges" }),
|
|
499
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: t("cpq.inventory.subscriptions.detail.items.charges", "Charges") }),
|
|
486
500
|
/* @__PURE__ */ jsxs("table", { className: "w-full text-xs", children: [
|
|
487
501
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "text-muted-foreground", children: [
|
|
488
|
-
/* @__PURE__ */ jsx("th", { className: "text-left py-1 font-medium", children: "Charge" }),
|
|
489
|
-
/* @__PURE__ */ jsx("th", { className: "text-left py-1 font-medium", children: "Type" }),
|
|
490
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: "List" }),
|
|
491
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: "Offer" }),
|
|
492
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: "Qty" }),
|
|
493
|
-
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: "Total" })
|
|
502
|
+
/* @__PURE__ */ jsx("th", { className: "text-left py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.charge", "Charge") }),
|
|
503
|
+
/* @__PURE__ */ jsx("th", { className: "text-left py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.type", "Type") }),
|
|
504
|
+
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.list", "List") }),
|
|
505
|
+
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.offer", "Offer") }),
|
|
506
|
+
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.qty", "Qty") }),
|
|
507
|
+
/* @__PURE__ */ jsx("th", { className: "text-right py-1 font-medium", children: t("cpq.inventory.subscriptions.detail.charges.total", "Total") })
|
|
494
508
|
] }) }),
|
|
495
509
|
/* @__PURE__ */ jsx("tbody", { children: item.charges.map((raw, i) => {
|
|
496
510
|
const c = parseStoredCharge(raw);
|
|
@@ -513,7 +527,7 @@ Open the existing quote now?`
|
|
|
513
527
|
] })
|
|
514
528
|
] }),
|
|
515
529
|
item.metadata && Object.keys(item.metadata).length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
516
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Metadata" }),
|
|
530
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: t("cpq.inventory.subscriptions.detail.items.metadata", "Metadata") }),
|
|
517
531
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-x-4 gap-y-1", children: Object.entries(item.metadata).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "text-xs", children: [
|
|
518
532
|
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
519
533
|
key,
|
|
@@ -523,107 +537,68 @@ Open the existing quote now?`
|
|
|
523
537
|
] }, key)) })
|
|
524
538
|
] }),
|
|
525
539
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-4 text-xs text-muted-foreground", children: [
|
|
526
|
-
/* @__PURE__ */
|
|
527
|
-
|
|
528
|
-
new Date(item.createdAt).toLocaleString()
|
|
529
|
-
] }),
|
|
530
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
531
|
-
"Updated: ",
|
|
532
|
-
new Date(item.updatedAt).toLocaleString()
|
|
533
|
-
] })
|
|
540
|
+
/* @__PURE__ */ jsx("span", { children: t("cpq.inventory.subscriptions.detail.items.createdAt", "Created: {date}", { date: new Date(item.createdAt).toLocaleString() }) }),
|
|
541
|
+
/* @__PURE__ */ jsx("span", { children: t("cpq.inventory.subscriptions.detail.items.updatedAt", "Updated: {date}", { date: new Date(item.updatedAt).toLocaleString() }) })
|
|
534
542
|
] })
|
|
535
543
|
] })
|
|
536
544
|
] }, item.id);
|
|
537
545
|
}) })
|
|
538
546
|
] }),
|
|
539
547
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
540
|
-
/* @__PURE__ */
|
|
541
|
-
|
|
542
|
-
changeLog.length,
|
|
543
|
-
")"
|
|
544
|
-
] }),
|
|
545
|
-
changeLogLoading ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-6 text-center text-sm text-muted-foreground", children: "Loading\u2026" }) : changeLog.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-6 text-center text-sm text-muted-foreground", children: "No ARC changes yet." }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card divide-y", children: changeLog.map((row) => /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 space-y-1", children: [
|
|
548
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-2 px-1", children: t("cpq.inventory.subscriptions.detail.changeLog.title", "Change History ({count})", { count: changeLog.length }) }),
|
|
549
|
+
changeLogLoading ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-6 text-center text-sm text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.loading", "Loading\u2026") }) : changeLog.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-6 text-center text-sm text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.empty", "No ARC changes yet.") }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card divide-y", children: changeLog.map((row) => /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 space-y-1", children: [
|
|
546
550
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
547
|
-
/* @__PURE__ */ jsx(Tag, { variant: CHANGE_TYPE_VARIANTS[row.changeType] ?? "neutral", children:
|
|
551
|
+
/* @__PURE__ */ jsx(Tag, { variant: CHANGE_TYPE_VARIANTS[row.changeType] ?? "neutral", children: changeTypeLabel(t, row.changeType) }),
|
|
548
552
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: new Date(row.effectiveAt).toLocaleString() }),
|
|
549
|
-
row.sourceQuoteId && /* @__PURE__ */
|
|
553
|
+
row.sourceQuoteId && /* @__PURE__ */ jsx(
|
|
550
554
|
"button",
|
|
551
555
|
{
|
|
552
556
|
onClick: () => router.push(`/backend/cpq/quotes/${row.sourceQuoteId}`),
|
|
553
557
|
className: "text-xs text-primary hover:underline",
|
|
554
|
-
children: [
|
|
555
|
-
"Quote ",
|
|
556
|
-
logQuoteNumbers[row.sourceQuoteId] ?? `${row.sourceQuoteId.slice(0, 8)}\u2026`
|
|
557
|
-
]
|
|
558
|
+
children: t("cpq.inventory.subscriptions.detail.changeLog.quote", "Quote {number}", { number: logQuoteNumbers[row.sourceQuoteId] ?? `${row.sourceQuoteId.slice(0, 8)}\u2026` })
|
|
558
559
|
}
|
|
559
560
|
),
|
|
560
|
-
row.sourceOrderId && /* @__PURE__ */
|
|
561
|
+
row.sourceOrderId && /* @__PURE__ */ jsx(
|
|
561
562
|
"button",
|
|
562
563
|
{
|
|
563
564
|
onClick: () => router.push(`/backend/cpq/orders/${row.sourceOrderId}`),
|
|
564
565
|
className: "text-xs text-primary hover:underline",
|
|
565
|
-
children: [
|
|
566
|
-
"Order ",
|
|
567
|
-
logOrderNumbers[row.sourceOrderId] ?? `${row.sourceOrderId.slice(0, 8)}\u2026`
|
|
568
|
-
]
|
|
566
|
+
children: t("cpq.inventory.subscriptions.detail.changeLog.order", "Order {number}", { number: logOrderNumbers[row.sourceOrderId] ?? `${row.sourceOrderId.slice(0, 8)}\u2026` })
|
|
569
567
|
}
|
|
570
568
|
)
|
|
571
569
|
] }),
|
|
572
570
|
/* @__PURE__ */ jsx(ChangeLogLineDetails, { row, currency }),
|
|
573
|
-
row.termChange && /* @__PURE__ */
|
|
574
|
-
|
|
575
|
-
String(row.termChange.
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
row.reasonCode && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
580
|
-
"Reason: ",
|
|
581
|
-
row.reasonCode,
|
|
582
|
-
row.reasonText ? ` \u2014 ${row.reasonText}` : ""
|
|
583
|
-
] }),
|
|
584
|
-
row.etfAmount && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
585
|
-
"ETF: ",
|
|
586
|
-
row.etfAmount,
|
|
587
|
-
" ",
|
|
588
|
-
row.etfCurrency ?? ""
|
|
589
|
-
] }),
|
|
571
|
+
row.termChange && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.term", "Term: {from} \u2192 {to}", {
|
|
572
|
+
from: String(row.termChange.oldTermEnd ?? "\u2014"),
|
|
573
|
+
to: String(row.termChange.newTermEnd ?? "\u2014")
|
|
574
|
+
}) }),
|
|
575
|
+
row.reasonCode && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: row.reasonText ? t("cpq.inventory.subscriptions.detail.changeLog.reasonWithText", "Reason: {code} \u2014 {text}", { code: row.reasonCode, text: row.reasonText }) : t("cpq.inventory.subscriptions.detail.changeLog.reason", "Reason: {code}", { code: row.reasonCode }) }),
|
|
576
|
+
row.etfAmount && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.etf", "ETF: {amount} {currency}", { amount: row.etfAmount, currency: row.etfCurrency ?? "" }) }),
|
|
590
577
|
row.mergedIntoSubscriptionId && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
591
|
-
"Merged into",
|
|
578
|
+
t("cpq.inventory.subscriptions.detail.changeLog.mergedInto", "Merged into"),
|
|
592
579
|
" ",
|
|
593
|
-
/* @__PURE__ */
|
|
580
|
+
/* @__PURE__ */ jsx(
|
|
594
581
|
"button",
|
|
595
582
|
{
|
|
596
583
|
onClick: () => router.push(`/backend/cpq/inventory/subscriptions/${row.mergedIntoSubscriptionId}`),
|
|
597
584
|
className: "text-primary hover:underline",
|
|
598
|
-
children:
|
|
599
|
-
"subscription ",
|
|
600
|
-
row.mergedIntoSubscriptionId.slice(0, 8),
|
|
601
|
-
"\u2026"
|
|
602
|
-
]
|
|
585
|
+
children: t("cpq.inventory.subscriptions.detail.changeLog.mergedIntoSubscription", "subscription {id}\u2026", { id: row.mergedIntoSubscriptionId.slice(0, 8) })
|
|
603
586
|
}
|
|
604
587
|
)
|
|
605
588
|
] }),
|
|
606
|
-
row.mergedFromSubscriptionIds && row.mergedFromSubscriptionIds.length > 0 && /* @__PURE__ */
|
|
607
|
-
"Merged from ",
|
|
608
|
-
row.mergedFromSubscriptionIds.length,
|
|
609
|
-
" subscriptions"
|
|
610
|
-
] })
|
|
589
|
+
row.mergedFromSubscriptionIds && row.mergedFromSubscriptionIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.mergedFrom", "Merged from {count} subscriptions", { count: row.mergedFromSubscriptionIds.length }) })
|
|
611
590
|
] }, row.id)) })
|
|
612
591
|
] }),
|
|
613
592
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
614
|
-
/* @__PURE__ */
|
|
615
|
-
|
|
616
|
-
assets.length,
|
|
617
|
-
")"
|
|
618
|
-
] }),
|
|
619
|
-
assets.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground", children: "No assets linked to this subscription." }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
593
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium mb-2 px-1", children: t("cpq.inventory.subscriptions.detail.assets.title", "Linked Assets ({count})", { count: assets.length }) }),
|
|
594
|
+
assets.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.assets.empty", "No assets linked to this subscription.") }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
620
595
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
|
|
621
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: "Code" }),
|
|
622
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: "Name" }),
|
|
623
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: "Type" }),
|
|
624
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: "Status" }),
|
|
625
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-right font-medium", children: "Price" }),
|
|
626
|
-
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-right font-medium", children: "Qty" })
|
|
596
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.code", "Code") }),
|
|
597
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.name", "Name") }),
|
|
598
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.type", "Type") }),
|
|
599
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.status", "Status") }),
|
|
600
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-right font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.price", "Price") }),
|
|
601
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-right font-medium", children: t("cpq.inventory.subscriptions.detail.assets.table.qty", "Qty") })
|
|
627
602
|
] }) }),
|
|
628
603
|
/* @__PURE__ */ jsx("tbody", { children: assets.map((a) => /* @__PURE__ */ jsxs("tr", { onClick: () => router.push(`/backend/cpq/inventory/assets/${a.id}`), className: "border-b cursor-pointer hover:bg-muted/30 transition-colors", children: [
|
|
629
604
|
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-muted-foreground", children: a.code }),
|
|
@@ -683,6 +658,8 @@ function ErrorBanner({ message }) {
|
|
|
683
658
|
return /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: message });
|
|
684
659
|
}
|
|
685
660
|
function ChangeLogLineDetails({ row, currency }) {
|
|
661
|
+
const t = useT();
|
|
662
|
+
const itemFallback = t("cpq.inventory.subscriptions.detail.changeLog.item", "Item");
|
|
686
663
|
const beforeItems = new Map(
|
|
687
664
|
(row.beforeSnapshot?.items ?? []).map((it) => [it.id, it])
|
|
688
665
|
);
|
|
@@ -704,7 +681,7 @@ function ChangeLogLineDetails({ row, currency }) {
|
|
|
704
681
|
derived.push({
|
|
705
682
|
key: `${itemId}-${i}`,
|
|
706
683
|
action: lc.action,
|
|
707
|
-
name: item?.name ?? (lc.action === "add" ? "New item" :
|
|
684
|
+
name: item?.name ?? (lc.action === "add" ? t("cpq.inventory.subscriptions.detail.changeLog.newItem", "New item") : itemFallback),
|
|
708
685
|
beforeMrc,
|
|
709
686
|
afterMrc: lc.action === "add" && afterMrc == null && lc.mrcAmount != null ? Number(lc.mrcAmount) : afterMrc,
|
|
710
687
|
delta: explicitDelta ?? computedDelta
|
|
@@ -716,7 +693,7 @@ function ChangeLogLineDetails({ row, currency }) {
|
|
|
716
693
|
derived.push({
|
|
717
694
|
key: it.id,
|
|
718
695
|
action: "cancel",
|
|
719
|
-
name: it.name ??
|
|
696
|
+
name: it.name ?? itemFallback,
|
|
720
697
|
beforeMrc: mrc,
|
|
721
698
|
afterMrc: 0,
|
|
722
699
|
delta: -mrc
|
|
@@ -728,7 +705,7 @@ function ChangeLogLineDetails({ row, currency }) {
|
|
|
728
705
|
derived.push({
|
|
729
706
|
key: it.id,
|
|
730
707
|
action: "add",
|
|
731
|
-
name: it.name ??
|
|
708
|
+
name: it.name ?? itemFallback,
|
|
732
709
|
beforeMrc: null,
|
|
733
710
|
afterMrc: mrc,
|
|
734
711
|
delta: null
|
|
@@ -740,7 +717,7 @@ function ChangeLogLineDetails({ row, currency }) {
|
|
|
740
717
|
derived.push({
|
|
741
718
|
key: it.id,
|
|
742
719
|
action: "cancel",
|
|
743
|
-
name: it.name ??
|
|
720
|
+
name: it.name ?? itemFallback,
|
|
744
721
|
beforeMrc: mrc,
|
|
745
722
|
afterMrc: 0,
|
|
746
723
|
delta: -mrc
|
|
@@ -749,57 +726,56 @@ function ChangeLogLineDetails({ row, currency }) {
|
|
|
749
726
|
}
|
|
750
727
|
if (derived.length === 0) {
|
|
751
728
|
if (row.changeType === "amend" || row.changeType === "renew") {
|
|
752
|
-
return /* @__PURE__ */ jsx("div", { className: "mt-1.5 text-xs text-muted-foreground italic", children: "No item-level changes recorded." });
|
|
729
|
+
return /* @__PURE__ */ jsx("div", { className: "mt-1.5 text-xs text-muted-foreground italic", children: t("cpq.inventory.subscriptions.detail.changeLog.noItemChanges", "No item-level changes recorded.") });
|
|
753
730
|
}
|
|
754
731
|
return null;
|
|
755
732
|
}
|
|
756
733
|
return /* @__PURE__ */ jsx("div", { className: "mt-1.5 rounded border bg-muted/20 px-3 py-2 space-y-1", children: derived.map((d) => /* @__PURE__ */ jsx(ChangeLogLineRow, { change: d, currency }, d.key)) });
|
|
757
734
|
}
|
|
758
735
|
const ACTION_GLYPH = {
|
|
759
|
-
add: { sign: "+", color: "text-status-success-text"
|
|
760
|
-
modify: { sign: "~", color: "text-status-info-text"
|
|
761
|
-
cancel: { sign: "\u2212", color: "text-destructive"
|
|
736
|
+
add: { sign: "+", color: "text-status-success-text" },
|
|
737
|
+
modify: { sign: "~", color: "text-status-info-text" },
|
|
738
|
+
cancel: { sign: "\u2212", color: "text-destructive" }
|
|
762
739
|
};
|
|
740
|
+
function actionGlyphLabel(t, action) {
|
|
741
|
+
switch (action) {
|
|
742
|
+
case "add":
|
|
743
|
+
return t("cpq.inventory.subscriptions.detail.changeLog.action.add", "added");
|
|
744
|
+
case "modify":
|
|
745
|
+
return t("cpq.inventory.subscriptions.detail.changeLog.action.modify", "modified");
|
|
746
|
+
case "cancel":
|
|
747
|
+
return t("cpq.inventory.subscriptions.detail.changeLog.action.cancel", "removed");
|
|
748
|
+
}
|
|
749
|
+
}
|
|
763
750
|
function ChangeLogLineRow({
|
|
764
751
|
change,
|
|
765
752
|
currency
|
|
766
753
|
}) {
|
|
754
|
+
const t = useT();
|
|
767
755
|
const glyph = ACTION_GLYPH[change.action];
|
|
768
756
|
const showPriceChange = change.action === "modify" && change.beforeMrc != null && change.afterMrc != null && change.beforeMrc !== change.afterMrc;
|
|
769
757
|
const showSinglePrice = !showPriceChange && (change.action === "add" && change.afterMrc != null && change.afterMrc > 0 || change.action === "cancel" && change.beforeMrc != null && change.beforeMrc > 0);
|
|
770
758
|
const showDelta = change.delta != null && change.delta !== 0;
|
|
771
759
|
const isNoopModify = change.action === "modify" && !showPriceChange && !showDelta;
|
|
772
760
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs", children: [
|
|
773
|
-
/* @__PURE__ */ jsx("span", { className: `font-bold w-3 text-center ${glyph.color}`, title:
|
|
761
|
+
/* @__PURE__ */ jsx("span", { className: `font-bold w-3 text-center ${glyph.color}`, title: actionGlyphLabel(t, change.action), children: glyph.sign }),
|
|
774
762
|
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: change.name }),
|
|
775
|
-
showPriceChange && /* @__PURE__ */
|
|
776
|
-
fmt(change.beforeMrc, currency),
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
fmt(change.afterMrc, currency),
|
|
783
|
-
"/mo"
|
|
784
|
-
] }),
|
|
785
|
-
showSinglePrice && change.action === "cancel" && /* @__PURE__ */ jsxs("span", { className: "font-mono text-muted-foreground", children: [
|
|
786
|
-
"was ",
|
|
787
|
-
fmt(change.beforeMrc, currency),
|
|
788
|
-
"/mo"
|
|
789
|
-
] }),
|
|
790
|
-
showDelta && /* @__PURE__ */ jsxs(
|
|
763
|
+
showPriceChange && /* @__PURE__ */ jsx("span", { className: "font-mono text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.priceChangePerMonth", "{before} \u2192 {after}/mo", {
|
|
764
|
+
before: fmt(change.beforeMrc, currency),
|
|
765
|
+
after: fmt(change.afterMrc, currency)
|
|
766
|
+
}) }),
|
|
767
|
+
showSinglePrice && change.action === "add" && /* @__PURE__ */ jsx("span", { className: "font-mono text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.pricePerMonth", "{price}/mo", { price: fmt(change.afterMrc, currency) }) }),
|
|
768
|
+
showSinglePrice && change.action === "cancel" && /* @__PURE__ */ jsx("span", { className: "font-mono text-muted-foreground", children: t("cpq.inventory.subscriptions.detail.changeLog.wasPricePerMonth", "was {price}/mo", { price: fmt(change.beforeMrc, currency) }) }),
|
|
769
|
+
showDelta && /* @__PURE__ */ jsx(
|
|
791
770
|
"span",
|
|
792
771
|
{
|
|
793
772
|
className: `font-mono font-medium ${change.delta > 0 ? "text-status-success-text" : "text-destructive"}`,
|
|
794
|
-
children:
|
|
795
|
-
"(
|
|
796
|
-
|
|
797
|
-
fmt(change.delta, currency),
|
|
798
|
-
"/mo)"
|
|
799
|
-
]
|
|
773
|
+
children: t("cpq.inventory.subscriptions.detail.changeLog.deltaPerMonth", "({delta}/mo)", {
|
|
774
|
+
delta: `${change.delta > 0 ? "+" : ""}${fmt(change.delta, currency)}`
|
|
775
|
+
})
|
|
800
776
|
}
|
|
801
777
|
),
|
|
802
|
-
isNoopModify && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic", children: "no price change" })
|
|
778
|
+
isNoopModify && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic", children: t("cpq.inventory.subscriptions.detail.changeLog.noPriceChange", "no price change") })
|
|
803
779
|
] });
|
|
804
780
|
}
|
|
805
781
|
export {
|