@infuro/cms-core 1.0.67 → 1.0.69
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/dist/{OrderTrackPage-W3J6WIG2.js → OrderTrackPage-VBZUVZOU.js} +1 -1
- package/dist/{OrderTrackPage-Z6FCJQYY.cjs → OrderTrackPage-VFIXWJOW.cjs} +4 -4
- package/dist/admin.cjs +121 -12
- package/dist/admin.js +121 -12
- package/dist/api.cjs +57 -54
- package/dist/api.js +24 -21
- package/dist/auth.cjs +62 -62
- package/dist/auth.js +6 -6
- package/dist/{chunk-XJNNOSJR.js → chunk-2BNVRFUQ.js} +1 -1
- package/dist/chunk-2JHGIWH7.cjs +2700 -0
- package/dist/{chunk-3DZRIZOD.cjs → chunk-3ASNJS2H.cjs} +3 -3
- package/dist/{chunk-7NMT3GBR.cjs → chunk-3LQS4ATQ.cjs} +4 -4
- package/dist/{chunk-GWDI752Q.js → chunk-3XCTGADT.js} +1 -1
- package/dist/chunk-47G65M5Q.cjs +18 -0
- package/dist/{chunk-XFDIIVZB.cjs → chunk-4MNVIGVJ.cjs} +11 -11
- package/dist/{chunk-OY2YTBMP.cjs → chunk-4WZNRVEZ.cjs} +3 -3
- package/dist/{chunk-OVTOP42W.js → chunk-53AMBXMM.js} +1 -1
- package/dist/chunk-5BKT4CS5.js +28 -0
- package/dist/chunk-5DSY3GQI.js +16 -0
- package/dist/{chunk-AYERBA7I.js → chunk-5NVGWJSY.js} +1 -1
- package/dist/{chunk-HF3L2GIT.cjs → chunk-5YMKJ3TH.cjs} +16 -16
- package/dist/{chunk-WFMVD567.cjs → chunk-6MM5OMRL.cjs} +11 -11
- package/dist/{chunk-5MZFQRDW.cjs → chunk-747MJJCZ.cjs} +147 -147
- package/dist/{chunk-SYBOCAWB.js → chunk-7QJI56OL.js} +1 -1
- package/dist/{chunk-DBPSJYLZ.js → chunk-BK5XW5XH.js} +1 -1
- package/dist/chunk-BQQMTQ4C.cjs +455 -0
- package/dist/{chunk-6YOQ7G5O.js → chunk-CFUSYGSA.js} +1 -1
- package/dist/{chunk-OOTLNH63.cjs → chunk-CIZZX57T.cjs} +2 -2
- package/dist/{chunk-7L6KWI7S.cjs → chunk-CTTV375J.cjs} +13 -13
- package/dist/{chunk-ZY64VJMS.js → chunk-D4LR3S77.js} +2 -2
- package/dist/{chunk-GLLCLRCQ.js → chunk-DBBYLSQP.js} +179 -49
- package/dist/{chunk-5NOZSG6J.js → chunk-DWNQTFJ5.js} +2 -2
- package/dist/{chunk-2IAXTKQN.cjs → chunk-DZNWS2MM.cjs} +2 -2
- package/dist/chunk-E62LKM6Z.cjs +49 -0
- package/dist/{chunk-CRFV5WJK.js → chunk-ECNYZG6T.js} +1 -1
- package/dist/{chunk-TZEMLHSP.cjs → chunk-EYUBL7YH.cjs} +7 -7
- package/dist/{chunk-WMMZZRDJ.cjs → chunk-HGR4IA7I.cjs} +18 -18
- package/dist/{chunk-TJ2MIQUT.cjs → chunk-JRW3GQD4.cjs} +4 -4
- package/dist/{chunk-3K5AIEIZ.js → chunk-JYRFSFXH.js} +1 -1
- package/dist/chunk-K6RXCLD5.js +45 -0
- package/dist/{chunk-TU23GJPJ.js → chunk-LJ5C4RBF.js} +3 -3
- package/dist/{chunk-O4AFPDQ4.cjs → chunk-LXWF6T7F.cjs} +33 -33
- package/dist/{chunk-EIZKW2PF.js → chunk-LY7CDNC6.js} +1 -1
- package/dist/{chunk-PA6YDMFZ.cjs → chunk-M5QDJOUP.cjs} +12 -12
- package/dist/{chunk-MQBT33IV.js → chunk-MGT4DJ2D.js} +1 -1
- package/dist/{chunk-2ISSXYBZ.js → chunk-MJDNS324.js} +5 -5
- package/dist/{chunk-H3IVLIPR.cjs → chunk-OXFC3DAM.cjs} +4 -4
- package/dist/chunk-PQJIJ4ZX.js +445 -0
- package/dist/{chunk-HY3AXLOI.cjs → chunk-PRXVSSIF.cjs} +13 -13
- package/dist/{chunk-TDV6EJHV.js → chunk-PRZOLCFW.js} +2 -2
- package/dist/{chunk-BVLN75LP.cjs → chunk-QL44NCZC.cjs} +1221 -1091
- package/dist/{chunk-VM6OVUUM.cjs → chunk-QN6PZLAP.cjs} +40 -40
- package/dist/{chunk-OV5TRZET.cjs → chunk-QXAQ3V7R.cjs} +27 -27
- package/dist/{chunk-NV5IRHI3.js → chunk-RBKVMHBH.js} +9 -9
- package/dist/{chunk-UPLVMVRX.cjs → chunk-RQCXRCYM.cjs} +2 -2
- package/dist/{chunk-WUQAOTHA.js → chunk-SERRQ736.js} +1 -1
- package/dist/{chunk-SS3K7OIM.cjs → chunk-SWSTGV4F.cjs} +81 -81
- package/dist/{chunk-RCE5SJBA.js → chunk-T47VP2ZT.js} +3 -3
- package/dist/{chunk-FLUF2GZH.js → chunk-WHMIWJL7.js} +1 -1
- package/dist/{chunk-JC6DLWTE.js → chunk-WQZ4AH2P.js} +1 -1
- package/dist/{chunk-D5FBNKQM.cjs → chunk-WXH3GMCF.cjs} +8 -8
- package/dist/chunk-XHPRD45G.cjs +32 -0
- package/dist/{chunk-THL5JDWJ.cjs → chunk-Y54WDY2O.cjs} +2 -2
- package/dist/{chunk-YRCKEGL2.js → chunk-YDMHG6BA.js} +1 -1
- package/dist/chunk-YHVA5NHI.js +2698 -0
- package/dist/{chunk-JXF23MPG.js → chunk-ZMIMKNSQ.js} +1 -1
- package/dist/cli.cjs +10 -10
- package/dist/cli.js +1 -1
- package/dist/email-queue-BJDH2ID7.cjs +29 -0
- package/dist/email-queue-MWP4R67H.js +8 -0
- package/dist/email-service-6JODEMUA.js +3 -0
- package/dist/email-service-VA4Q4ZRB.cjs +28 -0
- package/dist/emit-order-notification-trigger-X36V4DOH.cjs +16 -0
- package/dist/emit-order-notification-trigger-XKN2TWVF.js +3 -0
- package/dist/erp-config-enabled-32XTHBBT.cjs +11 -0
- package/dist/erp-config-enabled-CASE5YVI.js +2 -0
- package/dist/erp-order-invoice-5O42ZKC5.cjs +28 -0
- package/dist/erp-order-invoice-JEQKFXG4.js +7 -0
- package/dist/{event-order-defaults-DU7V3YND.cjs → event-order-defaults-TR45WAQQ.cjs} +10 -10
- package/dist/{event-order-defaults-H4RT7NMR.js → event-order-defaults-VXYO6NHT.js} +2 -2
- package/dist/generate-local-invoice-pdf-2NCA2WBL.cjs +12 -0
- package/dist/generate-local-invoice-pdf-XUH6GYEJ.js +3 -0
- package/dist/hooks.cjs +24 -24
- package/dist/hooks.js +2 -2
- package/dist/index.cjs +497 -494
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +39 -36
- package/dist/interpolate-KD37IRF2.js +2 -0
- package/dist/interpolate-WP6OSJHN.cjs +11 -0
- package/dist/invoice-templates-2ESQ7K4N.cjs +19 -0
- package/dist/invoice-templates-3AXTXERZ.js +2 -0
- package/dist/middleware.cjs +4 -4
- package/dist/middleware.js +2 -2
- package/dist/{order-assignees-handlers-L3RVKUBS.js → order-assignees-handlers-F7WOZHOG.js} +1 -1
- package/dist/{order-assignees-handlers-KF7RMTV5.cjs → order-assignees-handlers-JEJ5IDID.cjs} +3 -3
- package/dist/{order-completion-otp-handlers-HFGCPC4O.js → order-completion-otp-handlers-FIW7PZ6W.js} +12 -9
- package/dist/{order-completion-otp-handlers-DZAXK4GQ.cjs → order-completion-otp-handlers-LNAZTMTS.cjs} +25 -22
- package/dist/{order-inventory-76V4XIGW.js → order-inventory-R3AU6N4V.js} +2 -2
- package/dist/{order-inventory-2MYRKEPC.cjs → order-inventory-UUFPWLBW.cjs} +10 -10
- package/dist/order-notification-dispatcher-FS54ANAV.js +13 -0
- package/dist/order-notification-dispatcher-GG5C4LKZ.cjs +38 -0
- package/dist/paid-order-erp-GRXR2OG6.js +3 -0
- package/dist/paid-order-erp-X5QHPI23.cjs +12 -0
- package/dist/pg-boss-service-CMW3KQJM.js +2 -0
- package/dist/pg-boss-service-GA6ZVD5G.cjs +15 -0
- package/dist/{razorpay-U23LGY72.cjs → razorpay-GP2DXVP2.cjs} +2 -2
- package/dist/{razorpay-KLO2KNCB.js → razorpay-I3G5LNYH.js} +1 -1
- package/dist/{rbac-debug-db-KWV7D5PQ.cjs → rbac-debug-db-2ZI3XKA4.cjs} +4 -4
- package/dist/{rbac-debug-db-DFZWZ6GV.js → rbac-debug-db-IRKT6G62.js} +2 -2
- package/dist/resolve-invoice-asset-url-64QQUVC3.js +2 -0
- package/dist/resolve-invoice-asset-url-J7WAMD26.cjs +11 -0
- package/dist/retire-soft-deleted-unique-DZALT537.cjs +15 -0
- package/dist/{retire-soft-deleted-unique-NXQIH4BC.js → retire-soft-deleted-unique-F25KZBZK.js} +2 -2
- package/dist/sms-defaults-DSO3M26Y.js +2 -0
- package/dist/{sms-defaults-KCOPKQBA.cjs → sms-defaults-GDFILHHR.cjs} +5 -5
- package/dist/{sms-notification-templates-handlers-SJLO7JGZ.js → sms-notification-templates-handlers-ZGDCVS5Z.js} +1 -1
- package/dist/{sms-notification-templates-handlers-YSB3L2PK.cjs → sms-notification-templates-handlers-ZKLKFRFZ.cjs} +3 -3
- package/dist/{stripe-VU6OEG2D.cjs → stripe-2APRZHKU.cjs} +2 -2
- package/dist/{stripe-4FD27QVJ.js → stripe-7CO2ETTN.js} +1 -1
- package/dist/theme.cjs +10 -10
- package/dist/theme.js +3 -3
- package/dist/vendor-invite-status-45ZCWKCX.js +2 -0
- package/dist/{vendor-invite-status-77O7ZQ3U.cjs → vendor-invite-status-AT2E4FUA.cjs} +5 -5
- package/package.json +2 -1
- package/dist/chunk-GLD263KW.cjs +0 -862
- package/dist/chunk-OPJEV44S.js +0 -847
- package/dist/chunk-SHUYVCID.js +0 -4
- package/dist/chunk-USNT2KNT.cjs +0 -6
- package/dist/email-queue-4OY45JIU.cjs +0 -26
- package/dist/email-queue-HGXB2FIS.js +0 -5
- package/dist/email-service-5O24BSFR.cjs +0 -28
- package/dist/email-service-ADDF52PJ.js +0 -3
- package/dist/emit-order-notification-trigger-EJJZ6XTS.js +0 -3
- package/dist/emit-order-notification-trigger-ZD5YN3JM.cjs +0 -16
- package/dist/erp-config-enabled-CUMQ6N2V.cjs +0 -11
- package/dist/erp-config-enabled-T37X7T34.js +0 -2
- package/dist/erp-order-invoice-H6HCJ7YS.js +0 -4
- package/dist/erp-order-invoice-YUSPZ7CE.cjs +0 -25
- package/dist/interpolate-WAKPN56R.cjs +0 -11
- package/dist/interpolate-WDUWDF3I.js +0 -2
- package/dist/order-notification-dispatcher-ECPFI7CD.js +0 -10
- package/dist/order-notification-dispatcher-LL7ETKLU.cjs +0 -35
- package/dist/paid-order-erp-3USEG6WL.js +0 -3
- package/dist/paid-order-erp-FSQ3GSXE.cjs +0 -12
- package/dist/pg-boss-service-BDGOKM2T.cjs +0 -15
- package/dist/pg-boss-service-WCBJD4JB.js +0 -2
- package/dist/retire-soft-deleted-unique-5VXBA5XX.cjs +0 -15
- package/dist/sms-defaults-2NL24H57.js +0 -2
- package/dist/vendor-invite-status-PWJ3DE76.js +0 -2
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { isErpIntegrationEnabled } from './chunk-WQZ4AH2P.js';
|
|
2
|
+
import { generateLocalInvoicePdf } from './chunk-YHVA5NHI.js';
|
|
3
|
+
import { normalizeInvoiceTemplateId } from './chunk-K6RXCLD5.js';
|
|
4
|
+
import { resolveInvoiceAssetUrl } from './chunk-5DSY3GQI.js';
|
|
5
|
+
import { mergeEmailLayoutCompanyDetails, getCompanyDetailsFromSettings } from './chunk-YDMHG6BA.js';
|
|
6
|
+
import { __name } from './chunk-5BKT4CS5.js';
|
|
7
|
+
|
|
8
|
+
// src/plugins/erp/erp-response-map.ts
|
|
9
|
+
function pickString(o, keys) {
|
|
10
|
+
for (const k of keys) {
|
|
11
|
+
const v = o[k];
|
|
12
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
13
|
+
}
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
__name(pickString, "pickString");
|
|
17
|
+
function unwrapErpReadData(json) {
|
|
18
|
+
if (!json || typeof json !== "object") return null;
|
|
19
|
+
const o = json;
|
|
20
|
+
const d = o.data;
|
|
21
|
+
if (d && typeof d === "object" && !Array.isArray(d)) return d;
|
|
22
|
+
return o;
|
|
23
|
+
}
|
|
24
|
+
__name(unwrapErpReadData, "unwrapErpReadData");
|
|
25
|
+
function firstObject(data, keys) {
|
|
26
|
+
for (const k of keys) {
|
|
27
|
+
const v = data[k];
|
|
28
|
+
if (v && typeof v === "object" && !Array.isArray(v)) return v;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
__name(firstObject, "firstObject");
|
|
33
|
+
function extractEvents(src) {
|
|
34
|
+
const timeline = src.timeline ?? src.events ?? src.history ?? src.trackingEvents;
|
|
35
|
+
if (!Array.isArray(timeline) || !timeline.length) return void 0;
|
|
36
|
+
const events = [];
|
|
37
|
+
for (const row of timeline) {
|
|
38
|
+
if (!row || typeof row !== "object") continue;
|
|
39
|
+
const r = row;
|
|
40
|
+
const at = pickString(r, [
|
|
41
|
+
"at",
|
|
42
|
+
"timestamp",
|
|
43
|
+
"date",
|
|
44
|
+
"occurredAt"
|
|
45
|
+
]) ?? (r.at instanceof Date ? r.at.toISOString() : void 0);
|
|
46
|
+
const label = pickString(r, [
|
|
47
|
+
"label",
|
|
48
|
+
"status",
|
|
49
|
+
"title",
|
|
50
|
+
"message",
|
|
51
|
+
"description"
|
|
52
|
+
]);
|
|
53
|
+
const detail = pickString(r, [
|
|
54
|
+
"detail",
|
|
55
|
+
"notes",
|
|
56
|
+
"description"
|
|
57
|
+
]);
|
|
58
|
+
if (at || label || detail) events.push({
|
|
59
|
+
at,
|
|
60
|
+
label,
|
|
61
|
+
detail
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return events.length ? events : void 0;
|
|
65
|
+
}
|
|
66
|
+
__name(extractEvents, "extractEvents");
|
|
67
|
+
function mapErpPayloadToFulfillment(data) {
|
|
68
|
+
const nested = firstObject(data, [
|
|
69
|
+
"fulfillment",
|
|
70
|
+
"packaging",
|
|
71
|
+
"shipment",
|
|
72
|
+
"shipping",
|
|
73
|
+
"delivery"
|
|
74
|
+
]);
|
|
75
|
+
const src = nested || data;
|
|
76
|
+
const status = pickString(src, [
|
|
77
|
+
"status",
|
|
78
|
+
"fulfillmentStatus",
|
|
79
|
+
"state",
|
|
80
|
+
"label",
|
|
81
|
+
"packagingStatus"
|
|
82
|
+
]);
|
|
83
|
+
const trackingId = pickString(src, [
|
|
84
|
+
"trackingId",
|
|
85
|
+
"tracking_id",
|
|
86
|
+
"trackingNumber",
|
|
87
|
+
"awb",
|
|
88
|
+
"trackingUrl"
|
|
89
|
+
]);
|
|
90
|
+
const events = extractEvents(src);
|
|
91
|
+
if (!status && !trackingId && !(events && events.length)) return void 0;
|
|
92
|
+
return {
|
|
93
|
+
status,
|
|
94
|
+
trackingId,
|
|
95
|
+
events
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
__name(mapErpPayloadToFulfillment, "mapErpPayloadToFulfillment");
|
|
99
|
+
function mapErpPayloadToInvoiceNumber(data) {
|
|
100
|
+
const nested = firstObject(data, [
|
|
101
|
+
"invoice",
|
|
102
|
+
"latestInvoice",
|
|
103
|
+
"postedInvoice"
|
|
104
|
+
]);
|
|
105
|
+
const src = nested || data;
|
|
106
|
+
return pickString(src, [
|
|
107
|
+
"invoiceNumber",
|
|
108
|
+
"invoice_number",
|
|
109
|
+
"number",
|
|
110
|
+
"name",
|
|
111
|
+
"id"
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
__name(mapErpPayloadToInvoiceNumber, "mapErpPayloadToInvoiceNumber");
|
|
115
|
+
function extractChildOrderRefsFromSalePayload(data) {
|
|
116
|
+
const lists = [
|
|
117
|
+
data.returns,
|
|
118
|
+
data.returnOrders,
|
|
119
|
+
data.relatedReturns,
|
|
120
|
+
data.childOrders,
|
|
121
|
+
data.children
|
|
122
|
+
];
|
|
123
|
+
const seen = /* @__PURE__ */ new Set();
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const list of lists) {
|
|
126
|
+
if (!Array.isArray(list)) continue;
|
|
127
|
+
for (const item of list) {
|
|
128
|
+
if (!item || typeof item !== "object") continue;
|
|
129
|
+
const o = item;
|
|
130
|
+
const ref = pickString(o, [
|
|
131
|
+
"platformReturnId",
|
|
132
|
+
"platform_return_id",
|
|
133
|
+
"refId",
|
|
134
|
+
"ref_id"
|
|
135
|
+
]) ?? (typeof o.id === "string" ? o.id : void 0);
|
|
136
|
+
if (!ref || seen.has(ref)) continue;
|
|
137
|
+
seen.add(ref);
|
|
138
|
+
const t = (pickString(o, [
|
|
139
|
+
"kind",
|
|
140
|
+
"type",
|
|
141
|
+
"orderKind"
|
|
142
|
+
]) || "").toLowerCase();
|
|
143
|
+
const orderKind = /replac/.test(t) ? "replacement" : "return";
|
|
144
|
+
out.push({
|
|
145
|
+
ref,
|
|
146
|
+
orderKind
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
__name(extractChildOrderRefsFromSalePayload, "extractChildOrderRefsFromSalePayload");
|
|
153
|
+
|
|
154
|
+
// src/lib/invoice/build-local-invoice-for-order.ts
|
|
155
|
+
async function loadSettingsGroup(ds, entityMap, group) {
|
|
156
|
+
if (!entityMap.configs) return {};
|
|
157
|
+
const rows = await ds.getRepository(entityMap.configs).find({
|
|
158
|
+
where: {
|
|
159
|
+
settings: group,
|
|
160
|
+
deleted: false
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return Object.fromEntries(rows.map((r) => [
|
|
164
|
+
r.key,
|
|
165
|
+
String(r.value ?? "")
|
|
166
|
+
]));
|
|
167
|
+
}
|
|
168
|
+
__name(loadSettingsGroup, "loadSettingsGroup");
|
|
169
|
+
function addrFromRow(row) {
|
|
170
|
+
if (!row || typeof row !== "object") return null;
|
|
171
|
+
const a = row;
|
|
172
|
+
return {
|
|
173
|
+
line1: String(a.line1 ?? "").trim() || void 0,
|
|
174
|
+
line2: a.line2 != null ? String(a.line2).trim() || null : null,
|
|
175
|
+
city: String(a.city ?? "").trim() || void 0,
|
|
176
|
+
state: String(a.state ?? "").trim() || void 0,
|
|
177
|
+
postalCode: String(a.postalCode ?? "").trim() || void 0,
|
|
178
|
+
country: String(a.country ?? "").trim() || void 0
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
__name(addrFromRow, "addrFromRow");
|
|
182
|
+
async function buildLocalInvoicePdfForOrder(ds, entityMap, orderId) {
|
|
183
|
+
if (!entityMap.orders || !entityMap.order_items) {
|
|
184
|
+
return {
|
|
185
|
+
error: "Orders not configured",
|
|
186
|
+
status: 503
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const orderRepo = ds.getRepository(entityMap.orders);
|
|
190
|
+
let order = null;
|
|
191
|
+
try {
|
|
192
|
+
order = await orderRepo.findOne({
|
|
193
|
+
where: {
|
|
194
|
+
id: orderId,
|
|
195
|
+
deleted: false
|
|
196
|
+
},
|
|
197
|
+
relations: [
|
|
198
|
+
"contact",
|
|
199
|
+
"billingAddress",
|
|
200
|
+
"shippingAddress",
|
|
201
|
+
"items",
|
|
202
|
+
"items.product",
|
|
203
|
+
"assignedUser"
|
|
204
|
+
]
|
|
205
|
+
});
|
|
206
|
+
} catch {
|
|
207
|
+
try {
|
|
208
|
+
order = await orderRepo.findOne({
|
|
209
|
+
where: {
|
|
210
|
+
id: orderId,
|
|
211
|
+
deleted: false
|
|
212
|
+
},
|
|
213
|
+
relations: [
|
|
214
|
+
"contact",
|
|
215
|
+
"billingAddress",
|
|
216
|
+
"shippingAddress",
|
|
217
|
+
"items",
|
|
218
|
+
"assignedUser"
|
|
219
|
+
]
|
|
220
|
+
});
|
|
221
|
+
} catch {
|
|
222
|
+
order = await orderRepo.findOne({
|
|
223
|
+
where: {
|
|
224
|
+
id: orderId,
|
|
225
|
+
deleted: false
|
|
226
|
+
},
|
|
227
|
+
relations: [
|
|
228
|
+
"contact",
|
|
229
|
+
"billingAddress",
|
|
230
|
+
"shippingAddress",
|
|
231
|
+
"items"
|
|
232
|
+
]
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (!order) return {
|
|
237
|
+
error: "Not found",
|
|
238
|
+
status: 404
|
|
239
|
+
};
|
|
240
|
+
const o = order;
|
|
241
|
+
const kind = o.orderKind || "sale";
|
|
242
|
+
if (kind !== "sale") return {
|
|
243
|
+
error: "Invoice only for sale orders",
|
|
244
|
+
status: 400
|
|
245
|
+
};
|
|
246
|
+
const [store, branding, email] = await Promise.all([
|
|
247
|
+
loadSettingsGroup(ds, entityMap, "store"),
|
|
248
|
+
loadSettingsGroup(ds, entityMap, "branding"),
|
|
249
|
+
loadSettingsGroup(ds, entityMap, "email")
|
|
250
|
+
]);
|
|
251
|
+
const companyDetails = mergeEmailLayoutCompanyDetails(branding, email, store);
|
|
252
|
+
const fromBranding = getCompanyDetailsFromSettings(branding);
|
|
253
|
+
const rawLogo = store.invoiceLogoUrl || store.companyLogo || store.logo || companyDetails.logoUrl || fromBranding.logoUrl || null;
|
|
254
|
+
const logoUrl = resolveInvoiceAssetUrl(rawLogo);
|
|
255
|
+
const companyName = store.companyName || store.invoiceCompanyName || store.name || companyDetails.companyName || fromBranding.companyName || "Store";
|
|
256
|
+
const supportEmail = store.companyEmail || store.invoiceEmail || store.email || companyDetails.supportEmail || fromBranding.supportEmail;
|
|
257
|
+
const supportPhone = store.companyPhone || store.invoicePhone || store.phone || companyDetails.supportPhone;
|
|
258
|
+
const address = store.companyAddress || store.invoiceAddress || store.address;
|
|
259
|
+
const lineItems = (o.items ?? []).map((it) => {
|
|
260
|
+
const name = it.product?.name && String(it.product.name).trim() || `Product #${it.productId ?? ""}`;
|
|
261
|
+
return {
|
|
262
|
+
name,
|
|
263
|
+
quantity: Math.max(0, Math.floor(Number(it.quantity) || 0)),
|
|
264
|
+
unitPrice: Number(it.unitPrice) || 0,
|
|
265
|
+
tax: Number(it.tax) || 0,
|
|
266
|
+
total: Number(it.total) || 0,
|
|
267
|
+
sku: it.product?.sku ?? null
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
const rawMeta = o.metadata || {};
|
|
271
|
+
const serviceDate = rawMeta.serviceDate || rawMeta.bookingDate || rawMeta.date || null;
|
|
272
|
+
const timeSlot = rawMeta.timeSlot || rawMeta.slot || rawMeta.time || null;
|
|
273
|
+
const assignedTo = o.assignedUser?.name || null;
|
|
274
|
+
const qrToken = o.qrToken || null;
|
|
275
|
+
const baseUrl = process.env.NEXTAUTH_URL || process.env.PUBLIC_APP_URL || "";
|
|
276
|
+
const qrData = qrToken ? baseUrl ? `${baseUrl.replace(/\/$/, "")}/track/${qrToken}` : `/track/${qrToken}` : String(o.orderNumber || orderId);
|
|
277
|
+
const includeQrCode = store.invoice_include_qr === "true" || store.invoiceIncludeQr === "true";
|
|
278
|
+
const bytes = await generateLocalInvoicePdf({
|
|
279
|
+
templateId: normalizeInvoiceTemplateId(store.invoiceTemplate),
|
|
280
|
+
orderNumber: String(o.orderNumber || orderId),
|
|
281
|
+
orderDate: o.createdAt || /* @__PURE__ */ new Date(),
|
|
282
|
+
serviceDate,
|
|
283
|
+
timeSlot,
|
|
284
|
+
assignedTo,
|
|
285
|
+
qrToken,
|
|
286
|
+
qrData,
|
|
287
|
+
includeQrCode,
|
|
288
|
+
currency: String(o.currency || store.currency || "INR"),
|
|
289
|
+
customerName: String(o.contact?.name ?? "").trim() || "Customer",
|
|
290
|
+
customerEmail: o.contact?.email ?? null,
|
|
291
|
+
customerPhone: o.contact?.phone ?? null,
|
|
292
|
+
billingAddress: addrFromRow(o.billingAddress),
|
|
293
|
+
shippingAddress: addrFromRow(o.shippingAddress),
|
|
294
|
+
lineItems,
|
|
295
|
+
subtotal: Number(o.subtotal) || 0,
|
|
296
|
+
tax: Number(o.tax) || 0,
|
|
297
|
+
discount: Number(o.discount) || 0,
|
|
298
|
+
total: Number(o.total) || 0,
|
|
299
|
+
company: {
|
|
300
|
+
name: companyName,
|
|
301
|
+
logoUrl,
|
|
302
|
+
supportEmail,
|
|
303
|
+
supportPhone,
|
|
304
|
+
address
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
bytes,
|
|
309
|
+
filename: `invoice-${String(o.orderNumber || orderId).replace(/[^\w.-]+/g, "_")}.pdf`
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
__name(buildLocalInvoicePdfForOrder, "buildLocalInvoicePdfForOrder");
|
|
313
|
+
|
|
314
|
+
// src/plugins/erp/erp-order-invoice.ts
|
|
315
|
+
function pickInvoiceId(data) {
|
|
316
|
+
const nested = data.invoice && typeof data.invoice === "object" && !Array.isArray(data.invoice) ? data.invoice : null;
|
|
317
|
+
const src = nested || data;
|
|
318
|
+
for (const k of [
|
|
319
|
+
"invoiceId",
|
|
320
|
+
"invoice_id",
|
|
321
|
+
"id"
|
|
322
|
+
]) {
|
|
323
|
+
const v = src[k];
|
|
324
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
325
|
+
}
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
__name(pickInvoiceId, "pickInvoiceId");
|
|
329
|
+
function jsonErr(msg, status) {
|
|
330
|
+
return new Response(JSON.stringify({
|
|
331
|
+
error: msg
|
|
332
|
+
}), {
|
|
333
|
+
status,
|
|
334
|
+
headers: {
|
|
335
|
+
"Content-Type": "application/json"
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
__name(jsonErr, "jsonErr");
|
|
340
|
+
var ORDER_INVOICE_EMAIL_ELIGIBLE_STATUSES = /* @__PURE__ */ new Set([
|
|
341
|
+
"pending",
|
|
342
|
+
"placed",
|
|
343
|
+
"confirmed",
|
|
344
|
+
"processing",
|
|
345
|
+
"completed"
|
|
346
|
+
]);
|
|
347
|
+
function isOrderEligibleForInvoiceEmail(status, orderKind) {
|
|
348
|
+
const kind = (orderKind || "sale").trim().toLowerCase();
|
|
349
|
+
if (kind !== "sale") return false;
|
|
350
|
+
return ORDER_INVOICE_EMAIL_ELIGIBLE_STATUSES.has(String(status ?? "").trim().toLowerCase());
|
|
351
|
+
}
|
|
352
|
+
__name(isOrderEligibleForInvoiceEmail, "isOrderEligibleForInvoiceEmail");
|
|
353
|
+
async function resolveOrderInvoicePdfBytes(cms, dataSource, entityMap, orderId, options = {}) {
|
|
354
|
+
try {
|
|
355
|
+
const orderRepo = dataSource.getRepository(entityMap.orders);
|
|
356
|
+
const order = await orderRepo.findOne({
|
|
357
|
+
where: {
|
|
358
|
+
id: orderId,
|
|
359
|
+
deleted: false
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
if (!order) return {
|
|
363
|
+
error: "Not found",
|
|
364
|
+
status: 404
|
|
365
|
+
};
|
|
366
|
+
const kind = order.orderKind || "sale";
|
|
367
|
+
if (kind !== "sale") return {
|
|
368
|
+
error: "Invoice only for sale orders",
|
|
369
|
+
status: 400
|
|
370
|
+
};
|
|
371
|
+
if (options.ownerContactId != null && order.contactId !== options.ownerContactId) {
|
|
372
|
+
return {
|
|
373
|
+
error: "Not found",
|
|
374
|
+
status: 404
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);
|
|
378
|
+
const erp = cms.getPlugin("erp");
|
|
379
|
+
if (on && erp?.submission) {
|
|
380
|
+
const meta = order.metadata && typeof order.metadata === "object" && !Array.isArray(order.metadata) ? order.metadata : {};
|
|
381
|
+
const inv = meta.invoice && typeof meta.invoice === "object" && !Array.isArray(meta.invoice) ? meta.invoice : {};
|
|
382
|
+
let invoiceId = typeof inv.invoiceId === "string" ? inv.invoiceId.trim() : "";
|
|
383
|
+
if (!invoiceId) {
|
|
384
|
+
const refId = String(order.orderNumber || "");
|
|
385
|
+
try {
|
|
386
|
+
const r = await erp.submission.postErpReadAction("get-invoice", {
|
|
387
|
+
platformOrderId: refId
|
|
388
|
+
});
|
|
389
|
+
const d = r.ok ? unwrapErpReadData(r.json) : null;
|
|
390
|
+
invoiceId = d ? pickInvoiceId(d) || "" : "";
|
|
391
|
+
} catch {
|
|
392
|
+
invoiceId = "";
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (invoiceId) {
|
|
396
|
+
const pdf = await erp.submission.fetchInvoicePdf(invoiceId);
|
|
397
|
+
if (pdf.ok && pdf.buffer) {
|
|
398
|
+
return {
|
|
399
|
+
bytes: new Uint8Array(pdf.buffer),
|
|
400
|
+
filename: `order-invoice-${orderId}.pdf`,
|
|
401
|
+
contentType: pdf.contentType || "application/pdf",
|
|
402
|
+
source: "erp"
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const local = await buildLocalInvoicePdfForOrder(dataSource, entityMap, orderId);
|
|
408
|
+
if ("error" in local) return {
|
|
409
|
+
error: local.error,
|
|
410
|
+
status: local.status
|
|
411
|
+
};
|
|
412
|
+
return {
|
|
413
|
+
bytes: local.bytes,
|
|
414
|
+
filename: local.filename.startsWith("invoice-") ? local.filename.replace(/^invoice-/, "order-invoice-") : local.filename,
|
|
415
|
+
contentType: "application/pdf",
|
|
416
|
+
source: "local"
|
|
417
|
+
};
|
|
418
|
+
} catch (err) {
|
|
419
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
420
|
+
console.error("[invoice] resolveOrderInvoicePdfBytes failed", {
|
|
421
|
+
orderId,
|
|
422
|
+
error: msg
|
|
423
|
+
});
|
|
424
|
+
return {
|
|
425
|
+
error: `Invoice failed: ${msg}`,
|
|
426
|
+
status: 500
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
__name(resolveOrderInvoicePdfBytes, "resolveOrderInvoicePdfBytes");
|
|
431
|
+
async function streamOrderInvoicePdf(cms, dataSource, entityMap, orderId, options) {
|
|
432
|
+
const resolved = await resolveOrderInvoicePdfBytes(cms, dataSource, entityMap, orderId, options);
|
|
433
|
+
if ("error" in resolved) return jsonErr(resolved.error, resolved.status);
|
|
434
|
+
return new Response(Buffer.from(resolved.bytes), {
|
|
435
|
+
status: 200,
|
|
436
|
+
headers: {
|
|
437
|
+
"Content-Type": resolved.contentType,
|
|
438
|
+
"Content-Disposition": `attachment; filename="${resolved.filename}"`,
|
|
439
|
+
"X-Invoice-Source": resolved.source
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
__name(streamOrderInvoicePdf, "streamOrderInvoicePdf");
|
|
444
|
+
|
|
445
|
+
export { ORDER_INVOICE_EMAIL_ELIGIBLE_STATUSES, buildLocalInvoicePdfForOrder, extractChildOrderRefsFromSalePayload, isOrderEligibleForInvoiceEmail, mapErpPayloadToFulfillment, mapErpPayloadToInvoiceNumber, resolveOrderInvoicePdfBytes, streamOrderInvoicePdf, unwrapErpReadData };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkXHPRD45G_cjs = require('./chunk-XHPRD45G.cjs');
|
|
4
4
|
|
|
5
5
|
// src/lib/order-inventory.ts
|
|
6
6
|
var STOCK_HELD = /* @__PURE__ */ new Set([
|
|
@@ -10,7 +10,7 @@ var STOCK_HELD = /* @__PURE__ */ new Set([
|
|
|
10
10
|
function orderStatusHoldsStock(status) {
|
|
11
11
|
return STOCK_HELD.has(String(status ?? "").trim().toLowerCase());
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
chunkXHPRD45G_cjs.__name(orderStatusHoldsStock, "orderStatusHoldsStock");
|
|
14
14
|
function orderInventorySnapshotFromRow(order) {
|
|
15
15
|
return {
|
|
16
16
|
status: order.status ?? "pending",
|
|
@@ -28,12 +28,12 @@ function orderInventorySnapshotFromRow(order) {
|
|
|
28
28
|
}).filter((l) => l.productId > 0 && l.quantity > 0)
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
chunkXHPRD45G_cjs.__name(orderInventorySnapshotFromRow, "orderInventorySnapshotFromRow");
|
|
32
32
|
function lineKey(productId, variantId) {
|
|
33
33
|
const vid = variantId != null && Number.isFinite(Number(variantId)) && Number(variantId) > 0 ? Number(variantId) : 0;
|
|
34
34
|
return `${productId}:${vid}`;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
chunkXHPRD45G_cjs.__name(lineKey, "lineKey");
|
|
37
37
|
function mergeInventoryLines(lines) {
|
|
38
38
|
const m = /* @__PURE__ */ new Map();
|
|
39
39
|
for (const line of lines) {
|
|
@@ -55,19 +55,19 @@ function mergeInventoryLines(lines) {
|
|
|
55
55
|
}
|
|
56
56
|
return m;
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
chunkXHPRD45G_cjs.__name(mergeInventoryLines, "mergeInventoryLines");
|
|
59
59
|
function productRepo(ds, entityMap) {
|
|
60
60
|
const target = entityMap.products;
|
|
61
61
|
if (!target) throw new Error("products entity not configured");
|
|
62
62
|
return ds.getRepository(target);
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
chunkXHPRD45G_cjs.__name(productRepo, "productRepo");
|
|
65
65
|
function variantRepo(ds, entityMap) {
|
|
66
66
|
const target = entityMap.product_variants;
|
|
67
67
|
if (!target) return null;
|
|
68
68
|
return ds.getRepository(target);
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
chunkXHPRD45G_cjs.__name(variantRepo, "variantRepo");
|
|
71
71
|
async function validateInventoryForConfirmedOrderLines(ds, entityMap, lines) {
|
|
72
72
|
const merged = mergeInventoryLines(lines);
|
|
73
73
|
const byProduct = /* @__PURE__ */ new Map();
|
|
@@ -116,7 +116,7 @@ async function validateInventoryForConfirmedOrderLines(ds, entityMap, lines) {
|
|
|
116
116
|
}
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
chunkXHPRD45G_cjs.__name(validateInventoryForConfirmedOrderLines, "validateInventoryForConfirmedOrderLines");
|
|
120
120
|
async function validateInventoryForOrderBecomingConfirmed(ds, entityMap, prevSnap, nextLines) {
|
|
121
121
|
const mergedNext = mergeInventoryLines(nextLines);
|
|
122
122
|
const prevByKey = prevSnap && orderStatusHoldsStock(prevSnap.status) ? mergeInventoryLines(prevSnap.lines) : /* @__PURE__ */ new Map();
|
|
@@ -171,7 +171,7 @@ async function validateInventoryForOrderBecomingConfirmed(ds, entityMap, prevSna
|
|
|
171
171
|
}
|
|
172
172
|
return null;
|
|
173
173
|
}
|
|
174
|
-
|
|
174
|
+
chunkXHPRD45G_cjs.__name(validateInventoryForOrderBecomingConfirmed, "validateInventoryForOrderBecomingConfirmed");
|
|
175
175
|
async function applyInventoryDelta(ds, entityMap, lines, sign, validateDeduct) {
|
|
176
176
|
const merged = mergeInventoryLines(lines);
|
|
177
177
|
const pRepo = productRepo(ds, entityMap);
|
|
@@ -226,7 +226,7 @@ async function applyInventoryDelta(ds, entityMap, lines, sign, validateDeduct) {
|
|
|
226
226
|
}
|
|
227
227
|
return null;
|
|
228
228
|
}
|
|
229
|
-
|
|
229
|
+
chunkXHPRD45G_cjs.__name(applyInventoryDelta, "applyInventoryDelta");
|
|
230
230
|
async function reconcileOrderInventoryBetweenSnapshots(ds, entityMap, prev, next) {
|
|
231
231
|
const wasHeld = orderStatusHoldsStock(prev.status);
|
|
232
232
|
const isHeld = orderStatusHoldsStock(next.status);
|
|
@@ -240,7 +240,7 @@ async function reconcileOrderInventoryBetweenSnapshots(ds, entityMap, prev, next
|
|
|
240
240
|
}
|
|
241
241
|
return null;
|
|
242
242
|
}
|
|
243
|
-
|
|
243
|
+
chunkXHPRD45G_cjs.__name(reconcileOrderInventoryBetweenSnapshots, "reconcileOrderInventoryBetweenSnapshots");
|
|
244
244
|
async function deductInventoryForConfirmedOrder(ds, entityMap, lines, options) {
|
|
245
245
|
const validate = options?.validate !== false;
|
|
246
246
|
if (validate) {
|
|
@@ -249,11 +249,11 @@ async function deductInventoryForConfirmedOrder(ds, entityMap, lines, options) {
|
|
|
249
249
|
}
|
|
250
250
|
return applyInventoryDelta(ds, entityMap, lines, -1, validate);
|
|
251
251
|
}
|
|
252
|
-
|
|
252
|
+
chunkXHPRD45G_cjs.__name(deductInventoryForConfirmedOrder, "deductInventoryForConfirmedOrder");
|
|
253
253
|
async function restoreInventoryForCancelledOrder(ds, entityMap, lines) {
|
|
254
254
|
return applyInventoryDelta(ds, entityMap, lines, 1, false);
|
|
255
255
|
}
|
|
256
|
-
|
|
256
|
+
chunkXHPRD45G_cjs.__name(restoreInventoryForCancelledOrder, "restoreInventoryForCancelledOrder");
|
|
257
257
|
|
|
258
258
|
exports.deductInventoryForConfirmedOrder = deductInventoryForConfirmedOrder;
|
|
259
259
|
exports.mergeInventoryLines = mergeInventoryLines;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { logErp, queueErp, errorErp } from './chunk-
|
|
2
|
-
import { __name } from './chunk-
|
|
1
|
+
import { logErp, queueErp, errorErp } from './chunk-7QJI56OL.js';
|
|
2
|
+
import { __name } from './chunk-5BKT4CS5.js';
|
|
3
3
|
|
|
4
4
|
// src/plugins/erp/paid-order-erp.ts
|
|
5
5
|
function roundMoney(major) {
|