@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.
Files changed (150) hide show
  1. package/dist/{OrderTrackPage-W3J6WIG2.js → OrderTrackPage-VBZUVZOU.js} +1 -1
  2. package/dist/{OrderTrackPage-Z6FCJQYY.cjs → OrderTrackPage-VFIXWJOW.cjs} +4 -4
  3. package/dist/admin.cjs +121 -12
  4. package/dist/admin.js +121 -12
  5. package/dist/api.cjs +57 -54
  6. package/dist/api.js +24 -21
  7. package/dist/auth.cjs +62 -62
  8. package/dist/auth.js +6 -6
  9. package/dist/{chunk-XJNNOSJR.js → chunk-2BNVRFUQ.js} +1 -1
  10. package/dist/chunk-2JHGIWH7.cjs +2700 -0
  11. package/dist/{chunk-3DZRIZOD.cjs → chunk-3ASNJS2H.cjs} +3 -3
  12. package/dist/{chunk-7NMT3GBR.cjs → chunk-3LQS4ATQ.cjs} +4 -4
  13. package/dist/{chunk-GWDI752Q.js → chunk-3XCTGADT.js} +1 -1
  14. package/dist/chunk-47G65M5Q.cjs +18 -0
  15. package/dist/{chunk-XFDIIVZB.cjs → chunk-4MNVIGVJ.cjs} +11 -11
  16. package/dist/{chunk-OY2YTBMP.cjs → chunk-4WZNRVEZ.cjs} +3 -3
  17. package/dist/{chunk-OVTOP42W.js → chunk-53AMBXMM.js} +1 -1
  18. package/dist/chunk-5BKT4CS5.js +28 -0
  19. package/dist/chunk-5DSY3GQI.js +16 -0
  20. package/dist/{chunk-AYERBA7I.js → chunk-5NVGWJSY.js} +1 -1
  21. package/dist/{chunk-HF3L2GIT.cjs → chunk-5YMKJ3TH.cjs} +16 -16
  22. package/dist/{chunk-WFMVD567.cjs → chunk-6MM5OMRL.cjs} +11 -11
  23. package/dist/{chunk-5MZFQRDW.cjs → chunk-747MJJCZ.cjs} +147 -147
  24. package/dist/{chunk-SYBOCAWB.js → chunk-7QJI56OL.js} +1 -1
  25. package/dist/{chunk-DBPSJYLZ.js → chunk-BK5XW5XH.js} +1 -1
  26. package/dist/chunk-BQQMTQ4C.cjs +455 -0
  27. package/dist/{chunk-6YOQ7G5O.js → chunk-CFUSYGSA.js} +1 -1
  28. package/dist/{chunk-OOTLNH63.cjs → chunk-CIZZX57T.cjs} +2 -2
  29. package/dist/{chunk-7L6KWI7S.cjs → chunk-CTTV375J.cjs} +13 -13
  30. package/dist/{chunk-ZY64VJMS.js → chunk-D4LR3S77.js} +2 -2
  31. package/dist/{chunk-GLLCLRCQ.js → chunk-DBBYLSQP.js} +179 -49
  32. package/dist/{chunk-5NOZSG6J.js → chunk-DWNQTFJ5.js} +2 -2
  33. package/dist/{chunk-2IAXTKQN.cjs → chunk-DZNWS2MM.cjs} +2 -2
  34. package/dist/chunk-E62LKM6Z.cjs +49 -0
  35. package/dist/{chunk-CRFV5WJK.js → chunk-ECNYZG6T.js} +1 -1
  36. package/dist/{chunk-TZEMLHSP.cjs → chunk-EYUBL7YH.cjs} +7 -7
  37. package/dist/{chunk-WMMZZRDJ.cjs → chunk-HGR4IA7I.cjs} +18 -18
  38. package/dist/{chunk-TJ2MIQUT.cjs → chunk-JRW3GQD4.cjs} +4 -4
  39. package/dist/{chunk-3K5AIEIZ.js → chunk-JYRFSFXH.js} +1 -1
  40. package/dist/chunk-K6RXCLD5.js +45 -0
  41. package/dist/{chunk-TU23GJPJ.js → chunk-LJ5C4RBF.js} +3 -3
  42. package/dist/{chunk-O4AFPDQ4.cjs → chunk-LXWF6T7F.cjs} +33 -33
  43. package/dist/{chunk-EIZKW2PF.js → chunk-LY7CDNC6.js} +1 -1
  44. package/dist/{chunk-PA6YDMFZ.cjs → chunk-M5QDJOUP.cjs} +12 -12
  45. package/dist/{chunk-MQBT33IV.js → chunk-MGT4DJ2D.js} +1 -1
  46. package/dist/{chunk-2ISSXYBZ.js → chunk-MJDNS324.js} +5 -5
  47. package/dist/{chunk-H3IVLIPR.cjs → chunk-OXFC3DAM.cjs} +4 -4
  48. package/dist/chunk-PQJIJ4ZX.js +445 -0
  49. package/dist/{chunk-HY3AXLOI.cjs → chunk-PRXVSSIF.cjs} +13 -13
  50. package/dist/{chunk-TDV6EJHV.js → chunk-PRZOLCFW.js} +2 -2
  51. package/dist/{chunk-BVLN75LP.cjs → chunk-QL44NCZC.cjs} +1221 -1091
  52. package/dist/{chunk-VM6OVUUM.cjs → chunk-QN6PZLAP.cjs} +40 -40
  53. package/dist/{chunk-OV5TRZET.cjs → chunk-QXAQ3V7R.cjs} +27 -27
  54. package/dist/{chunk-NV5IRHI3.js → chunk-RBKVMHBH.js} +9 -9
  55. package/dist/{chunk-UPLVMVRX.cjs → chunk-RQCXRCYM.cjs} +2 -2
  56. package/dist/{chunk-WUQAOTHA.js → chunk-SERRQ736.js} +1 -1
  57. package/dist/{chunk-SS3K7OIM.cjs → chunk-SWSTGV4F.cjs} +81 -81
  58. package/dist/{chunk-RCE5SJBA.js → chunk-T47VP2ZT.js} +3 -3
  59. package/dist/{chunk-FLUF2GZH.js → chunk-WHMIWJL7.js} +1 -1
  60. package/dist/{chunk-JC6DLWTE.js → chunk-WQZ4AH2P.js} +1 -1
  61. package/dist/{chunk-D5FBNKQM.cjs → chunk-WXH3GMCF.cjs} +8 -8
  62. package/dist/chunk-XHPRD45G.cjs +32 -0
  63. package/dist/{chunk-THL5JDWJ.cjs → chunk-Y54WDY2O.cjs} +2 -2
  64. package/dist/{chunk-YRCKEGL2.js → chunk-YDMHG6BA.js} +1 -1
  65. package/dist/chunk-YHVA5NHI.js +2698 -0
  66. package/dist/{chunk-JXF23MPG.js → chunk-ZMIMKNSQ.js} +1 -1
  67. package/dist/cli.cjs +10 -10
  68. package/dist/cli.js +1 -1
  69. package/dist/email-queue-BJDH2ID7.cjs +29 -0
  70. package/dist/email-queue-MWP4R67H.js +8 -0
  71. package/dist/email-service-6JODEMUA.js +3 -0
  72. package/dist/email-service-VA4Q4ZRB.cjs +28 -0
  73. package/dist/emit-order-notification-trigger-X36V4DOH.cjs +16 -0
  74. package/dist/emit-order-notification-trigger-XKN2TWVF.js +3 -0
  75. package/dist/erp-config-enabled-32XTHBBT.cjs +11 -0
  76. package/dist/erp-config-enabled-CASE5YVI.js +2 -0
  77. package/dist/erp-order-invoice-5O42ZKC5.cjs +28 -0
  78. package/dist/erp-order-invoice-JEQKFXG4.js +7 -0
  79. package/dist/{event-order-defaults-DU7V3YND.cjs → event-order-defaults-TR45WAQQ.cjs} +10 -10
  80. package/dist/{event-order-defaults-H4RT7NMR.js → event-order-defaults-VXYO6NHT.js} +2 -2
  81. package/dist/generate-local-invoice-pdf-2NCA2WBL.cjs +12 -0
  82. package/dist/generate-local-invoice-pdf-XUH6GYEJ.js +3 -0
  83. package/dist/hooks.cjs +24 -24
  84. package/dist/hooks.js +2 -2
  85. package/dist/index.cjs +497 -494
  86. package/dist/index.d.cts +7 -1
  87. package/dist/index.d.ts +7 -1
  88. package/dist/index.js +39 -36
  89. package/dist/interpolate-KD37IRF2.js +2 -0
  90. package/dist/interpolate-WP6OSJHN.cjs +11 -0
  91. package/dist/invoice-templates-2ESQ7K4N.cjs +19 -0
  92. package/dist/invoice-templates-3AXTXERZ.js +2 -0
  93. package/dist/middleware.cjs +4 -4
  94. package/dist/middleware.js +2 -2
  95. package/dist/{order-assignees-handlers-L3RVKUBS.js → order-assignees-handlers-F7WOZHOG.js} +1 -1
  96. package/dist/{order-assignees-handlers-KF7RMTV5.cjs → order-assignees-handlers-JEJ5IDID.cjs} +3 -3
  97. package/dist/{order-completion-otp-handlers-HFGCPC4O.js → order-completion-otp-handlers-FIW7PZ6W.js} +12 -9
  98. package/dist/{order-completion-otp-handlers-DZAXK4GQ.cjs → order-completion-otp-handlers-LNAZTMTS.cjs} +25 -22
  99. package/dist/{order-inventory-76V4XIGW.js → order-inventory-R3AU6N4V.js} +2 -2
  100. package/dist/{order-inventory-2MYRKEPC.cjs → order-inventory-UUFPWLBW.cjs} +10 -10
  101. package/dist/order-notification-dispatcher-FS54ANAV.js +13 -0
  102. package/dist/order-notification-dispatcher-GG5C4LKZ.cjs +38 -0
  103. package/dist/paid-order-erp-GRXR2OG6.js +3 -0
  104. package/dist/paid-order-erp-X5QHPI23.cjs +12 -0
  105. package/dist/pg-boss-service-CMW3KQJM.js +2 -0
  106. package/dist/pg-boss-service-GA6ZVD5G.cjs +15 -0
  107. package/dist/{razorpay-U23LGY72.cjs → razorpay-GP2DXVP2.cjs} +2 -2
  108. package/dist/{razorpay-KLO2KNCB.js → razorpay-I3G5LNYH.js} +1 -1
  109. package/dist/{rbac-debug-db-KWV7D5PQ.cjs → rbac-debug-db-2ZI3XKA4.cjs} +4 -4
  110. package/dist/{rbac-debug-db-DFZWZ6GV.js → rbac-debug-db-IRKT6G62.js} +2 -2
  111. package/dist/resolve-invoice-asset-url-64QQUVC3.js +2 -0
  112. package/dist/resolve-invoice-asset-url-J7WAMD26.cjs +11 -0
  113. package/dist/retire-soft-deleted-unique-DZALT537.cjs +15 -0
  114. package/dist/{retire-soft-deleted-unique-NXQIH4BC.js → retire-soft-deleted-unique-F25KZBZK.js} +2 -2
  115. package/dist/sms-defaults-DSO3M26Y.js +2 -0
  116. package/dist/{sms-defaults-KCOPKQBA.cjs → sms-defaults-GDFILHHR.cjs} +5 -5
  117. package/dist/{sms-notification-templates-handlers-SJLO7JGZ.js → sms-notification-templates-handlers-ZGDCVS5Z.js} +1 -1
  118. package/dist/{sms-notification-templates-handlers-YSB3L2PK.cjs → sms-notification-templates-handlers-ZKLKFRFZ.cjs} +3 -3
  119. package/dist/{stripe-VU6OEG2D.cjs → stripe-2APRZHKU.cjs} +2 -2
  120. package/dist/{stripe-4FD27QVJ.js → stripe-7CO2ETTN.js} +1 -1
  121. package/dist/theme.cjs +10 -10
  122. package/dist/theme.js +3 -3
  123. package/dist/vendor-invite-status-45ZCWKCX.js +2 -0
  124. package/dist/{vendor-invite-status-77O7ZQ3U.cjs → vendor-invite-status-AT2E4FUA.cjs} +5 -5
  125. package/package.json +2 -1
  126. package/dist/chunk-GLD263KW.cjs +0 -862
  127. package/dist/chunk-OPJEV44S.js +0 -847
  128. package/dist/chunk-SHUYVCID.js +0 -4
  129. package/dist/chunk-USNT2KNT.cjs +0 -6
  130. package/dist/email-queue-4OY45JIU.cjs +0 -26
  131. package/dist/email-queue-HGXB2FIS.js +0 -5
  132. package/dist/email-service-5O24BSFR.cjs +0 -28
  133. package/dist/email-service-ADDF52PJ.js +0 -3
  134. package/dist/emit-order-notification-trigger-EJJZ6XTS.js +0 -3
  135. package/dist/emit-order-notification-trigger-ZD5YN3JM.cjs +0 -16
  136. package/dist/erp-config-enabled-CUMQ6N2V.cjs +0 -11
  137. package/dist/erp-config-enabled-T37X7T34.js +0 -2
  138. package/dist/erp-order-invoice-H6HCJ7YS.js +0 -4
  139. package/dist/erp-order-invoice-YUSPZ7CE.cjs +0 -25
  140. package/dist/interpolate-WAKPN56R.cjs +0 -11
  141. package/dist/interpolate-WDUWDF3I.js +0 -2
  142. package/dist/order-notification-dispatcher-ECPFI7CD.js +0 -10
  143. package/dist/order-notification-dispatcher-LL7ETKLU.cjs +0 -35
  144. package/dist/paid-order-erp-3USEG6WL.js +0 -3
  145. package/dist/paid-order-erp-FSQ3GSXE.cjs +0 -12
  146. package/dist/pg-boss-service-BDGOKM2T.cjs +0 -15
  147. package/dist/pg-boss-service-WCBJD4JB.js +0 -2
  148. package/dist/retire-soft-deleted-unique-5VXBA5XX.cjs +0 -15
  149. package/dist/sms-defaults-2NL24H57.js +0 -2
  150. 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 chunkUSNT2KNT_cjs = require('./chunk-USNT2KNT.cjs');
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
- chunkUSNT2KNT_cjs.__name(orderStatusHoldsStock, "orderStatusHoldsStock");
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
- chunkUSNT2KNT_cjs.__name(orderInventorySnapshotFromRow, "orderInventorySnapshotFromRow");
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
- chunkUSNT2KNT_cjs.__name(lineKey, "lineKey");
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
- chunkUSNT2KNT_cjs.__name(mergeInventoryLines, "mergeInventoryLines");
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
- chunkUSNT2KNT_cjs.__name(productRepo, "productRepo");
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
- chunkUSNT2KNT_cjs.__name(variantRepo, "variantRepo");
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
- chunkUSNT2KNT_cjs.__name(validateInventoryForConfirmedOrderLines, "validateInventoryForConfirmedOrderLines");
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
- chunkUSNT2KNT_cjs.__name(validateInventoryForOrderBecomingConfirmed, "validateInventoryForOrderBecomingConfirmed");
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
- chunkUSNT2KNT_cjs.__name(applyInventoryDelta, "applyInventoryDelta");
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
- chunkUSNT2KNT_cjs.__name(reconcileOrderInventoryBetweenSnapshots, "reconcileOrderInventoryBetweenSnapshots");
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
- chunkUSNT2KNT_cjs.__name(deductInventoryForConfirmedOrder, "deductInventoryForConfirmedOrder");
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
- chunkUSNT2KNT_cjs.__name(restoreInventoryForCancelledOrder, "restoreInventoryForCancelledOrder");
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-SYBOCAWB.js';
2
- import { __name } from './chunk-SHUYVCID.js';
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) {