@infuro/cms-core 1.0.45 → 1.0.46
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/README.md +19 -2
- package/dist/admin.cjs +873 -214
- package/dist/admin.d.cts +7 -1
- package/dist/admin.d.ts +7 -1
- package/dist/admin.js +874 -215
- package/dist/api.cjs +40 -37
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +8 -5
- package/dist/auth.cjs +23 -23
- package/dist/auth.d.cts +1 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +2 -2
- package/dist/chunk-2KUCQVAQ.js +936 -0
- package/dist/chunk-3K5AIEIZ.js +256 -0
- package/dist/{chunk-I6NH72MO.js → chunk-57O3HZPG.js} +9 -1
- package/dist/chunk-7PMHZRF3.cjs +872 -0
- package/dist/chunk-BXYZDMTZ.cjs +953 -0
- package/dist/chunk-CQHXW4TR.js +107 -0
- package/dist/{chunk-NNQBWDCI.js → chunk-CRYKVJTO.js} +55 -959
- package/dist/chunk-DBPSJYLZ.js +47 -0
- package/dist/{chunk-TAHX46EI.cjs → chunk-FBKDMRQL.cjs} +9 -1
- package/dist/chunk-GUSHM5HN.js +862 -0
- package/dist/chunk-HY3AXLOI.cjs +265 -0
- package/dist/chunk-L3525VXI.js +243 -0
- package/dist/{chunk-ZMRQ72F6.cjs → chunk-NBY4NVTY.cjs} +3 -3
- package/dist/chunk-OY2YTBMP.cjs +50 -0
- package/dist/{chunk-BLR6H5GL.js → chunk-SF2XKMCI.js} +3 -3
- package/dist/{chunk-22FFHLTO.cjs → chunk-TCSGFAWB.cjs} +56 -970
- package/dist/{chunk-F5XFHYTG.cjs → chunk-UDVLFVEC.cjs} +661 -382
- package/dist/{chunk-MVXLRANV.js → chunk-UKC3HYXI.js} +591 -323
- package/dist/chunk-V25RDUOU.cjs +248 -0
- package/dist/chunk-XMRMZ6NQ.cjs +109 -0
- package/dist/cli.cjs +9 -4
- package/dist/cli.js +9 -4
- package/dist/{email-queue-TPZWLTIV.cjs → email-queue-6NJY6HNM.cjs} +7 -5
- package/dist/email-queue-OI2HSCGE.js +4 -0
- package/dist/erp-order-invoice-3GXDE443.js +3 -0
- package/dist/erp-order-invoice-EYYNR526.cjs +24 -0
- package/dist/index.cjs +391 -364
- package/dist/index.d.cts +267 -14
- package/dist/index.d.ts +267 -14
- package/dist/index.js +12 -110
- package/dist/migrations/1781810000000-OrderItemsVariantId.ts +44 -0
- package/dist/migrations/1781900000000-UserInviteStatusToken.ts +46 -0
- package/dist/migrations/1782000000000-ComboSlug.ts +58 -0
- package/dist/migrations/1782100000000-DiscountDeviceType.ts +20 -0
- package/dist/order-inventory-2MYRKEPC.cjs +39 -0
- package/dist/order-inventory-76V4XIGW.js +2 -0
- package/dist/order-notification-dispatcher-SBQAMM5V.cjs +21 -0
- package/dist/{order-notification-dispatcher-XWIJYDGA.js → order-notification-dispatcher-ZJZB2HUN.js} +5 -2
- package/dist/retire-soft-deleted-unique-5VXBA5XX.cjs +15 -0
- package/dist/retire-soft-deleted-unique-NXQIH4BC.js +2 -0
- package/dist/send-order-placed-emails-B5ZVJT7T.cjs +15 -0
- package/dist/send-order-placed-emails-WPI37KRZ.js +6 -0
- package/package.json +5 -4
- package/src/admin/admin.css +27 -24
- package/dist/chunk-5ELSW2UP.js +0 -150
- package/dist/chunk-PNOKNSG2.cjs +0 -222
- package/dist/chunk-WEMDMVHQ.js +0 -216
- package/dist/chunk-XW5ATPRW.cjs +0 -155
- package/dist/email-queue-CGZBVVAS.js +0 -2
- package/dist/erp-order-invoice-3YISSOWW.js +0 -3
- package/dist/erp-order-invoice-ZR5F2KTA.cjs +0 -12
- package/dist/order-notification-dispatcher-RU7BTGGX.cjs +0 -18
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkHY3AXLOI_cjs = require('./chunk-HY3AXLOI.cjs');
|
|
4
|
+
var chunkOY2YTBMP_cjs = require('./chunk-OY2YTBMP.cjs');
|
|
5
|
+
var chunk7PMHZRF3_cjs = require('./chunk-7PMHZRF3.cjs');
|
|
6
|
+
var chunkTCSGFAWB_cjs = require('./chunk-TCSGFAWB.cjs');
|
|
4
7
|
var chunk7NMT3GBR_cjs = require('./chunk-7NMT3GBR.cjs');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
8
|
+
var chunkV25RDUOU_cjs = require('./chunk-V25RDUOU.cjs');
|
|
9
|
+
var chunkBXYZDMTZ_cjs = require('./chunk-BXYZDMTZ.cjs');
|
|
7
10
|
var chunk3DZRIZOD_cjs = require('./chunk-3DZRIZOD.cjs');
|
|
8
11
|
var chunkSPQFNIYJ_cjs = require('./chunk-SPQFNIYJ.cjs');
|
|
9
12
|
var chunkXQ3QUHWR_cjs = require('./chunk-XQ3QUHWR.cjs');
|
|
10
|
-
var
|
|
13
|
+
var chunkNBY4NVTY_cjs = require('./chunk-NBY4NVTY.cjs');
|
|
11
14
|
var chunkX6UQFV4X_cjs = require('./chunk-X6UQFV4X.cjs');
|
|
12
15
|
var chunkD5FBNKQM_cjs = require('./chunk-D5FBNKQM.cjs');
|
|
13
16
|
var chunkUPLVMVRX_cjs = require('./chunk-UPLVMVRX.cjs');
|
|
@@ -656,6 +659,144 @@ function applyEventApprovalStatusSideEffects(updatePayload, opts) {
|
|
|
656
659
|
}
|
|
657
660
|
chunkUSNT2KNT_cjs.__name(applyEventApprovalStatusSideEffects, "applyEventApprovalStatusSideEffects");
|
|
658
661
|
|
|
662
|
+
// src/lib/discount-usage.ts
|
|
663
|
+
async function countDiscountOrdersForContact(dataSource, discountId, contactId) {
|
|
664
|
+
try {
|
|
665
|
+
const rows = await dataSource.query(`SELECT COUNT(DISTINCT od."orderId")::int AS count
|
|
666
|
+
FROM order_discounts od
|
|
667
|
+
WHERE od."discountId" = $1 AND od."userId" = $2`, [
|
|
668
|
+
discountId,
|
|
669
|
+
contactId
|
|
670
|
+
]);
|
|
671
|
+
return Number(rows?.[0]?.count ?? 0);
|
|
672
|
+
} catch {
|
|
673
|
+
return 0;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
chunkUSNT2KNT_cjs.__name(countDiscountOrdersForContact, "countDiscountOrdersForContact");
|
|
677
|
+
function isMaxTotalUsageReached(discount) {
|
|
678
|
+
if (discount.maxTotalUsage == null) return false;
|
|
679
|
+
return Number(discount.usedCount ?? 0) >= Number(discount.maxTotalUsage);
|
|
680
|
+
}
|
|
681
|
+
chunkUSNT2KNT_cjs.__name(isMaxTotalUsageReached, "isMaxTotalUsageReached");
|
|
682
|
+
async function isMaxPerUserUsageReached(dataSource, discount, contactId) {
|
|
683
|
+
if (discount.maxUsagePerUser == null || contactId == null) return false;
|
|
684
|
+
const count = await countDiscountOrdersForContact(dataSource, discount.id, contactId);
|
|
685
|
+
return count >= Number(discount.maxUsagePerUser);
|
|
686
|
+
}
|
|
687
|
+
chunkUSNT2KNT_cjs.__name(isMaxPerUserUsageReached, "isMaxPerUserUsageReached");
|
|
688
|
+
async function checkAndIncrementDiscountUsage(dataSource, entityMap, discountId, contactId) {
|
|
689
|
+
if (!entityMap.discounts) return null;
|
|
690
|
+
const discountRepo = dataSource.getRepository(entityMap.discounts);
|
|
691
|
+
const discount = await discountRepo.findOne({
|
|
692
|
+
where: {
|
|
693
|
+
id: discountId
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
if (!discount) return `Discount #${discountId} not found`;
|
|
697
|
+
const d = discount;
|
|
698
|
+
if (d.maxUsagePerUser != null) {
|
|
699
|
+
const usageCount = await countDiscountOrdersForContact(dataSource, discountId, contactId);
|
|
700
|
+
if (usageCount >= Number(d.maxUsagePerUser)) {
|
|
701
|
+
return "You have reached the maximum usage limit for this discount";
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
const updated = await dataSource.query(`UPDATE discounts
|
|
705
|
+
SET "usedCount" = "usedCount" + 1
|
|
706
|
+
WHERE id = $1
|
|
707
|
+
AND ("maxTotalUsage" IS NULL OR "usedCount" < "maxTotalUsage")
|
|
708
|
+
RETURNING id`, [
|
|
709
|
+
discountId
|
|
710
|
+
]);
|
|
711
|
+
if (!Array.isArray(updated) || updated.length === 0) {
|
|
712
|
+
return "Discount usage limit has been reached";
|
|
713
|
+
}
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
chunkUSNT2KNT_cjs.__name(checkAndIncrementDiscountUsage, "checkAndIncrementDiscountUsage");
|
|
717
|
+
async function decrementDiscountUsage(dataSource, entityMap, discountId, orderId) {
|
|
718
|
+
if (!entityMap.discounts) return;
|
|
719
|
+
try {
|
|
720
|
+
await dataSource.query(`UPDATE discounts SET "usedCount" = GREATEST("usedCount" - 1, 0) WHERE id = $1`, [
|
|
721
|
+
discountId
|
|
722
|
+
]);
|
|
723
|
+
if (entityMap.order_discounts) {
|
|
724
|
+
await dataSource.getRepository(entityMap.order_discounts).delete({
|
|
725
|
+
orderId,
|
|
726
|
+
discountId
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
} catch (err) {
|
|
730
|
+
console.error("[discountEngine] decrementDiscountUsage failed:", err);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
chunkUSNT2KNT_cjs.__name(decrementDiscountUsage, "decrementDiscountUsage");
|
|
734
|
+
async function recordDiscountUsage(dataSource, entityMap, orderId, discountId, contactId, discountAmount) {
|
|
735
|
+
if (!entityMap.order_discounts) return;
|
|
736
|
+
try {
|
|
737
|
+
let discountCode = "";
|
|
738
|
+
if (entityMap.discounts) {
|
|
739
|
+
const discountRow = await dataSource.getRepository(entityMap.discounts).findOne({
|
|
740
|
+
where: {
|
|
741
|
+
id: discountId
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
discountCode = discountRow?.couponCode ?? "";
|
|
745
|
+
}
|
|
746
|
+
const odRepo = dataSource.getRepository(entityMap.order_discounts);
|
|
747
|
+
const orderItemRepo = dataSource.getRepository(entityMap.order_items);
|
|
748
|
+
const items = await orderItemRepo.find({
|
|
749
|
+
where: {
|
|
750
|
+
orderId
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
const discountedItems = items.filter((item) => Number(item.discount ?? 0) > 0);
|
|
754
|
+
if (discountedItems.length === 0) {
|
|
755
|
+
const firstItem = items[0];
|
|
756
|
+
if (!firstItem) return;
|
|
757
|
+
await odRepo.save(odRepo.create({
|
|
758
|
+
orderId,
|
|
759
|
+
orderItemId: firstItem.id,
|
|
760
|
+
discountId,
|
|
761
|
+
discountCode,
|
|
762
|
+
discountAmount,
|
|
763
|
+
userId: contactId
|
|
764
|
+
}));
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
for (const item of discountedItems) {
|
|
768
|
+
const i = item;
|
|
769
|
+
await odRepo.save(odRepo.create({
|
|
770
|
+
orderId,
|
|
771
|
+
orderItemId: i.id,
|
|
772
|
+
discountId,
|
|
773
|
+
discountCode,
|
|
774
|
+
discountAmount: Number(i.discount ?? 0),
|
|
775
|
+
userId: contactId
|
|
776
|
+
}));
|
|
777
|
+
}
|
|
778
|
+
} catch (err) {
|
|
779
|
+
console.error("[discountEngine] recordDiscountUsage failed:", err);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
chunkUSNT2KNT_cjs.__name(recordDiscountUsage, "recordDiscountUsage");
|
|
783
|
+
async function consumeAppliedDiscountUsages(dataSource, entityMap, orderId, contactId, applied) {
|
|
784
|
+
const unique = /* @__PURE__ */ new Map();
|
|
785
|
+
for (const row of applied) {
|
|
786
|
+
const id = Number(row.id);
|
|
787
|
+
if (!Number.isFinite(id) || id < 1) continue;
|
|
788
|
+
const amount = Math.max(0, Number(row.calculatedDiscount) || 0);
|
|
789
|
+
unique.set(id, (unique.get(id) ?? 0) + amount);
|
|
790
|
+
}
|
|
791
|
+
for (const [discountId, discountAmount] of unique) {
|
|
792
|
+
const usageErr = await checkAndIncrementDiscountUsage(dataSource, entityMap, discountId, contactId);
|
|
793
|
+
if (usageErr) return usageErr;
|
|
794
|
+
await recordDiscountUsage(dataSource, entityMap, orderId, discountId, contactId, discountAmount);
|
|
795
|
+
}
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
chunkUSNT2KNT_cjs.__name(consumeAppliedDiscountUsages, "consumeAppliedDiscountUsages");
|
|
799
|
+
|
|
659
800
|
// src/lib/default-vendor-id.ts
|
|
660
801
|
function getDefaultVendorId() {
|
|
661
802
|
const raw = process.env.DEFAULT_VENDOR_ID;
|
|
@@ -1999,6 +2140,7 @@ async function ensureUniqueProductSlug(repo, baseSlug, vendorId, excludeId) {
|
|
|
1999
2140
|
let slug = baseSlug;
|
|
2000
2141
|
let suffix = 0;
|
|
2001
2142
|
while (true) {
|
|
2143
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(repo, "slug", slug);
|
|
2002
2144
|
const where = excludeId != null ? {
|
|
2003
2145
|
slug,
|
|
2004
2146
|
vendorId,
|
|
@@ -2018,6 +2160,21 @@ async function ensureUniqueProductSlug(repo, baseSlug, vendorId, excludeId) {
|
|
|
2018
2160
|
}
|
|
2019
2161
|
}
|
|
2020
2162
|
chunkUSNT2KNT_cjs.__name(ensureUniqueProductSlug, "ensureUniqueProductSlug");
|
|
2163
|
+
async function normalizeComboNameAndSlug(repo, body, vendorId, existing, excludeId) {
|
|
2164
|
+
const incomingName = typeof body.name === "string" ? body.name.trim() : "";
|
|
2165
|
+
const incomingSlugRaw = typeof body.slug === "string" ? body.slug.trim() : "";
|
|
2166
|
+
const existingName = typeof existing?.name === "string" ? existing.name.trim() : "";
|
|
2167
|
+
const existingSlug = typeof existing?.slug === "string" ? existing.slug.trim() : "";
|
|
2168
|
+
const name = incomingName || existingName;
|
|
2169
|
+
if (!name) return "Name is required";
|
|
2170
|
+
if (incomingName) body.name = name;
|
|
2171
|
+
const nameBasedSlug = slugifyProductLabel(name);
|
|
2172
|
+
const typedSlug = incomingSlugRaw ? slugifyProductLabel(incomingSlugRaw) : "";
|
|
2173
|
+
const slug = typedSlug || (excludeId != null ? existingSlug : "") || nameBasedSlug;
|
|
2174
|
+
body.slug = await ensureUniqueProductSlug(repo, slug, vendorId, excludeId);
|
|
2175
|
+
return null;
|
|
2176
|
+
}
|
|
2177
|
+
chunkUSNT2KNT_cjs.__name(normalizeComboNameAndSlug, "normalizeComboNameAndSlug");
|
|
2021
2178
|
async function hydrateProductEventNames(dataSource, entityMap, products) {
|
|
2022
2179
|
if (!products.length) return products;
|
|
2023
2180
|
if (!entityMap.event_products || !entityMap.events) {
|
|
@@ -2264,6 +2421,20 @@ async function normalizeProductNameAndSlug(repo, body, vendorId, existing, exclu
|
|
|
2264
2421
|
return null;
|
|
2265
2422
|
}
|
|
2266
2423
|
chunkUSNT2KNT_cjs.__name(normalizeProductNameAndSlug, "normalizeProductNameAndSlug");
|
|
2424
|
+
async function retireSoftDeletedUniquesFromBody(repo, body) {
|
|
2425
|
+
const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
|
|
2426
|
+
if (!cols.has("deleted")) return;
|
|
2427
|
+
for (const col of [
|
|
2428
|
+
"slug",
|
|
2429
|
+
"email"
|
|
2430
|
+
]) {
|
|
2431
|
+
if (!cols.has(col)) continue;
|
|
2432
|
+
const raw = body[col];
|
|
2433
|
+
if (typeof raw !== "string" || !raw.trim()) continue;
|
|
2434
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(repo, col, raw.trim());
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
chunkUSNT2KNT_cjs.__name(retireSoftDeletedUniquesFromBody, "retireSoftDeletedUniquesFromBody");
|
|
2267
2438
|
function buildSoftDeletePayload(meta, deletedBy) {
|
|
2268
2439
|
const payload = {
|
|
2269
2440
|
deleted: true
|
|
@@ -2500,6 +2671,7 @@ function discountEvaluateRule(rule, cartLines, cartTotal) {
|
|
|
2500
2671
|
case "category":
|
|
2501
2672
|
case "cart":
|
|
2502
2673
|
case "paymentMethod":
|
|
2674
|
+
case "deviceType":
|
|
2503
2675
|
case "order": {
|
|
2504
2676
|
if (rule.subType === "nthOrder") {
|
|
2505
2677
|
return true;
|
|
@@ -2683,87 +2855,22 @@ function applyDiscountToOrderLines(lines, evalResult, maxDiscountAmount) {
|
|
|
2683
2855
|
return totalDiscountApplied;
|
|
2684
2856
|
}
|
|
2685
2857
|
chunkUSNT2KNT_cjs.__name(applyDiscountToOrderLines, "applyDiscountToOrderLines");
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
const discountRepo = dataSource.getRepository(entityMap["discounts"]);
|
|
2689
|
-
const discount = await discountRepo.findOne({
|
|
2690
|
-
where: {
|
|
2691
|
-
id: discountId
|
|
2692
|
-
}
|
|
2693
|
-
});
|
|
2694
|
-
if (!discount) return `Discount #${discountId} not found`;
|
|
2695
|
-
await dataSource.query(`UPDATE discounts SET "usedCount" = "usedCount" + 1 WHERE id = $1`, [
|
|
2696
|
-
discountId
|
|
2697
|
-
]);
|
|
2698
|
-
return null;
|
|
2858
|
+
function asDiscountUsageEntityMap(entityMap) {
|
|
2859
|
+
return entityMap;
|
|
2699
2860
|
}
|
|
2700
|
-
chunkUSNT2KNT_cjs.__name(
|
|
2701
|
-
async function
|
|
2702
|
-
|
|
2703
|
-
try {
|
|
2704
|
-
await dataSource.query(`UPDATE discounts SET "usedCount" = GREATEST("usedCount" - 1, 0) WHERE id = $1`, [
|
|
2705
|
-
discountId
|
|
2706
|
-
]);
|
|
2707
|
-
if (entityMap["order_discounts"]) {
|
|
2708
|
-
await dataSource.getRepository(entityMap["order_discounts"]).delete({
|
|
2709
|
-
orderId,
|
|
2710
|
-
discountId
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2713
|
-
} catch (err) {
|
|
2714
|
-
console.error("[discountEngine] decrementDiscountUsage failed:", err);
|
|
2715
|
-
}
|
|
2861
|
+
chunkUSNT2KNT_cjs.__name(asDiscountUsageEntityMap, "asDiscountUsageEntityMap");
|
|
2862
|
+
async function checkAndIncrementDiscountUsage2(dataSource, entityMap, discountId, contactId) {
|
|
2863
|
+
return checkAndIncrementDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), discountId, contactId);
|
|
2716
2864
|
}
|
|
2717
|
-
chunkUSNT2KNT_cjs.__name(
|
|
2718
|
-
async function
|
|
2719
|
-
|
|
2720
|
-
try {
|
|
2721
|
-
let discountCode = "";
|
|
2722
|
-
if (entityMap["discounts"]) {
|
|
2723
|
-
const discountRow = await dataSource.getRepository(entityMap["discounts"]).findOne({
|
|
2724
|
-
where: {
|
|
2725
|
-
id: discountId
|
|
2726
|
-
}
|
|
2727
|
-
});
|
|
2728
|
-
discountCode = discountRow?.couponCode ?? "";
|
|
2729
|
-
}
|
|
2730
|
-
const odRepo = dataSource.getRepository(entityMap["order_discounts"]);
|
|
2731
|
-
const orderItemRepo = dataSource.getRepository(entityMap.order_items);
|
|
2732
|
-
const items = await orderItemRepo.find({
|
|
2733
|
-
where: {
|
|
2734
|
-
orderId
|
|
2735
|
-
}
|
|
2736
|
-
});
|
|
2737
|
-
const discountedItems = items.filter((item) => Number(item.discount ?? 0) > 0);
|
|
2738
|
-
if (discountedItems.length === 0) {
|
|
2739
|
-
const firstItem = items[0];
|
|
2740
|
-
if (!firstItem) return;
|
|
2741
|
-
await odRepo.save(odRepo.create({
|
|
2742
|
-
orderId,
|
|
2743
|
-
orderItemId: firstItem.id,
|
|
2744
|
-
discountId,
|
|
2745
|
-
discountCode,
|
|
2746
|
-
discountAmount,
|
|
2747
|
-
userId: contactId
|
|
2748
|
-
}));
|
|
2749
|
-
return;
|
|
2750
|
-
}
|
|
2751
|
-
for (const item of discountedItems) {
|
|
2752
|
-
const i = item;
|
|
2753
|
-
await odRepo.save(odRepo.create({
|
|
2754
|
-
orderId,
|
|
2755
|
-
orderItemId: i.id,
|
|
2756
|
-
discountId,
|
|
2757
|
-
discountCode,
|
|
2758
|
-
discountAmount: Number(i.discount ?? 0),
|
|
2759
|
-
userId: contactId
|
|
2760
|
-
}));
|
|
2761
|
-
}
|
|
2762
|
-
} catch (err) {
|
|
2763
|
-
console.error("[discountEngine] recordDiscountUsage failed:", err);
|
|
2764
|
-
}
|
|
2865
|
+
chunkUSNT2KNT_cjs.__name(checkAndIncrementDiscountUsage2, "checkAndIncrementDiscountUsage");
|
|
2866
|
+
async function decrementDiscountUsage2(dataSource, entityMap, discountId, orderId) {
|
|
2867
|
+
return decrementDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), discountId, orderId);
|
|
2765
2868
|
}
|
|
2766
|
-
chunkUSNT2KNT_cjs.__name(
|
|
2869
|
+
chunkUSNT2KNT_cjs.__name(decrementDiscountUsage2, "decrementDiscountUsage");
|
|
2870
|
+
async function recordDiscountUsage2(dataSource, entityMap, orderId, discountId, contactId, discountAmount) {
|
|
2871
|
+
return recordDiscountUsage(dataSource, asDiscountUsageEntityMap(entityMap), orderId, discountId, contactId, discountAmount);
|
|
2872
|
+
}
|
|
2873
|
+
chunkUSNT2KNT_cjs.__name(recordDiscountUsage2, "recordDiscountUsage");
|
|
2767
2874
|
async function validateCoupon(dataSource, entityMap, couponCode, orderLines, currency = "INR", contactId, isAutomatic, discountId, vendorId) {
|
|
2768
2875
|
if (!entityMap["discounts"]) return {
|
|
2769
2876
|
valid: false,
|
|
@@ -2808,21 +2915,12 @@ async function validateCoupon(dataSource, entityMap, couponCode, orderLines, cur
|
|
|
2808
2915
|
};
|
|
2809
2916
|
}
|
|
2810
2917
|
if (contactId != null && d.maxUsagePerUser != null) {
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
]);
|
|
2818
|
-
const usageCount = Number(userUsage?.[0]?.count ?? 0);
|
|
2819
|
-
if (usageCount >= d.maxUsagePerUser) {
|
|
2820
|
-
return {
|
|
2821
|
-
valid: false,
|
|
2822
|
-
error: "You have reached the maximum usage limit for this discount"
|
|
2823
|
-
};
|
|
2824
|
-
}
|
|
2825
|
-
} catch {
|
|
2918
|
+
const usageCount = await countDiscountOrdersForContact(dataSource, d.id, contactId);
|
|
2919
|
+
if (usageCount >= d.maxUsagePerUser) {
|
|
2920
|
+
return {
|
|
2921
|
+
valid: false,
|
|
2922
|
+
error: "You have reached the maximum usage limit for this discount"
|
|
2923
|
+
};
|
|
2826
2924
|
}
|
|
2827
2925
|
}
|
|
2828
2926
|
const flatRules = entityMap["discount_rules"] ? await dataSource.getRepository(entityMap["discount_rules"]).find({
|
|
@@ -2900,128 +2998,32 @@ function normalizeOrderLinesInput(raw) {
|
|
|
2900
2998
|
if (!Number.isFinite(productId) || productId <= 0) continue;
|
|
2901
2999
|
const qRaw = Number(r.quantity ?? 1);
|
|
2902
3000
|
const q = Number.isFinite(qRaw) ? Math.min(99999, Math.max(1, Math.floor(qRaw))) : 1;
|
|
2903
|
-
|
|
3001
|
+
const vidRaw = r.variantId ?? r.variant_id;
|
|
3002
|
+
const vid = vidRaw != null && String(vidRaw).trim() !== "" ? Number(vidRaw) : NaN;
|
|
3003
|
+
const variantId = Number.isFinite(vid) && vid > 0 ? vid : null;
|
|
3004
|
+
const key = `${productId}:${variantId ?? 0}`;
|
|
3005
|
+
const prev = merged.get(key);
|
|
3006
|
+
if (prev) prev.quantity += q;
|
|
3007
|
+
else merged.set(key, {
|
|
3008
|
+
productId,
|
|
3009
|
+
quantity: q,
|
|
3010
|
+
variantId
|
|
3011
|
+
});
|
|
2904
3012
|
}
|
|
2905
3013
|
return [
|
|
2906
|
-
...merged.
|
|
2907
|
-
]
|
|
2908
|
-
productId,
|
|
2909
|
-
quantity
|
|
2910
|
-
}));
|
|
3014
|
+
...merged.values()
|
|
3015
|
+
];
|
|
2911
3016
|
}
|
|
2912
3017
|
chunkUSNT2KNT_cjs.__name(normalizeOrderLinesInput, "normalizeOrderLinesInput");
|
|
2913
3018
|
var ORDER_STATUS_CONFIRMED = "confirmed";
|
|
2914
|
-
function
|
|
2915
|
-
|
|
2916
|
-
status: order.status ?? "pending",
|
|
2917
|
-
lines: (order.items ?? []).map((i) => ({
|
|
2918
|
-
productId: Number(i.productId),
|
|
2919
|
-
quantity: Math.max(0, Math.floor(Number(i.quantity) || 0))
|
|
2920
|
-
})).filter((l) => l.productId > 0 && l.quantity > 0)
|
|
2921
|
-
};
|
|
2922
|
-
}
|
|
2923
|
-
chunkUSNT2KNT_cjs.__name(orderInventorySnapshotFromRow, "orderInventorySnapshotFromRow");
|
|
2924
|
-
function mergeInventoryLinesByProduct(lines) {
|
|
2925
|
-
const m = /* @__PURE__ */ new Map();
|
|
2926
|
-
for (const { productId, quantity } of lines) {
|
|
2927
|
-
if (!Number.isFinite(productId) || productId <= 0 || quantity <= 0) continue;
|
|
2928
|
-
m.set(productId, (m.get(productId) ?? 0) + quantity);
|
|
2929
|
-
}
|
|
2930
|
-
return m;
|
|
2931
|
-
}
|
|
2932
|
-
chunkUSNT2KNT_cjs.__name(mergeInventoryLinesByProduct, "mergeInventoryLinesByProduct");
|
|
2933
|
-
async function validateInventoryForConfirmedOrderLines(dataSource, entityMap, calcLines) {
|
|
2934
|
-
const productRepo = dataSource.getRepository(entityMap.products);
|
|
2935
|
-
const merged = mergeInventoryLinesByProduct(calcLines.filter((l) => l.found && l.productId != null).map((l) => ({
|
|
3019
|
+
async function validateInventoryForConfirmedOrderLines2(dataSource, entityMap, calcLines) {
|
|
3020
|
+
const lines = calcLines.filter((l) => l.found && l.productId != null).map((l) => ({
|
|
2936
3021
|
productId: l.productId,
|
|
2937
3022
|
quantity: l.quantity
|
|
2938
|
-
}))
|
|
2939
|
-
|
|
2940
|
-
const row = await productRepo.findOne({
|
|
2941
|
-
where: {
|
|
2942
|
-
id: productId,
|
|
2943
|
-
deleted: false
|
|
2944
|
-
}
|
|
2945
|
-
});
|
|
2946
|
-
if (!row) return `Product #${productId} not found`;
|
|
2947
|
-
if (row.type === "service") continue;
|
|
2948
|
-
const cur = Number(row.quantity ?? 0);
|
|
2949
|
-
if (cur < qty) {
|
|
2950
|
-
const name = row.name ?? String(productId);
|
|
2951
|
-
return `Insufficient stock for ${name}: available ${cur}, required ${qty}`;
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
return null;
|
|
2955
|
-
}
|
|
2956
|
-
chunkUSNT2KNT_cjs.__name(validateInventoryForConfirmedOrderLines, "validateInventoryForConfirmedOrderLines");
|
|
2957
|
-
async function applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, sign, validateDeduct) {
|
|
2958
|
-
const productRepo = dataSource.getRepository(entityMap.products);
|
|
2959
|
-
for (const [productId, qty] of merged) {
|
|
2960
|
-
const row = await productRepo.findOne({
|
|
2961
|
-
where: {
|
|
2962
|
-
id: productId,
|
|
2963
|
-
deleted: false
|
|
2964
|
-
}
|
|
2965
|
-
});
|
|
2966
|
-
if (!row) return `Product #${productId} not found`;
|
|
2967
|
-
if (row.type === "service") continue;
|
|
2968
|
-
const cur = Number(row.quantity ?? 0);
|
|
2969
|
-
if (sign === -1) {
|
|
2970
|
-
if (validateDeduct && cur < qty) {
|
|
2971
|
-
const name = row.name ?? String(productId);
|
|
2972
|
-
return `Insufficient stock for ${name}: available ${cur}, required ${qty}`;
|
|
2973
|
-
}
|
|
2974
|
-
await productRepo.update(productId, {
|
|
2975
|
-
quantity: Math.max(0, cur - qty)
|
|
2976
|
-
});
|
|
2977
|
-
} else {
|
|
2978
|
-
await productRepo.update(productId, {
|
|
2979
|
-
quantity: cur + qty
|
|
2980
|
-
});
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
|
-
return null;
|
|
2984
|
-
}
|
|
2985
|
-
chunkUSNT2KNT_cjs.__name(applyInventoryDeltaForMergedLines, "applyInventoryDeltaForMergedLines");
|
|
2986
|
-
async function validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, prevSnap, nextLines) {
|
|
2987
|
-
const mergedNext = mergeInventoryLinesByProduct(nextLines);
|
|
2988
|
-
const productRepo = dataSource.getRepository(entityMap.products);
|
|
2989
|
-
const prevByProduct = prevSnap?.status === ORDER_STATUS_CONFIRMED ? mergeInventoryLinesByProduct(prevSnap.lines) : /* @__PURE__ */ new Map();
|
|
2990
|
-
for (const [productId, need] of mergedNext) {
|
|
2991
|
-
const row = await productRepo.findOne({
|
|
2992
|
-
where: {
|
|
2993
|
-
id: productId,
|
|
2994
|
-
deleted: false
|
|
2995
|
-
}
|
|
2996
|
-
});
|
|
2997
|
-
if (!row) return `Product #${productId} not found`;
|
|
2998
|
-
if (row.type === "service") continue;
|
|
2999
|
-
let available = Number(row.quantity ?? 0);
|
|
3000
|
-
available += prevByProduct.get(productId) ?? 0;
|
|
3001
|
-
if (available < need) {
|
|
3002
|
-
const name = row.name ?? String(productId);
|
|
3003
|
-
return `Insufficient stock for ${name}: available ${available}, required ${need}`;
|
|
3004
|
-
}
|
|
3005
|
-
}
|
|
3006
|
-
return null;
|
|
3007
|
-
}
|
|
3008
|
-
chunkUSNT2KNT_cjs.__name(validateInventoryForOrderBecomingConfirmed, "validateInventoryForOrderBecomingConfirmed");
|
|
3009
|
-
async function reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, prev, next) {
|
|
3010
|
-
const wasConfirmed = prev.status === ORDER_STATUS_CONFIRMED;
|
|
3011
|
-
const isConfirmed = next.status === ORDER_STATUS_CONFIRMED;
|
|
3012
|
-
if (wasConfirmed) {
|
|
3013
|
-
const merged = mergeInventoryLinesByProduct(prev.lines);
|
|
3014
|
-
const err = await applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, 1, false);
|
|
3015
|
-
if (err) return err;
|
|
3016
|
-
}
|
|
3017
|
-
if (isConfirmed) {
|
|
3018
|
-
const merged = mergeInventoryLinesByProduct(next.lines);
|
|
3019
|
-
const err = await applyInventoryDeltaForMergedLines(dataSource, entityMap, merged, -1, true);
|
|
3020
|
-
if (err) return err;
|
|
3021
|
-
}
|
|
3022
|
-
return null;
|
|
3023
|
+
}));
|
|
3024
|
+
return chunkHY3AXLOI_cjs.validateInventoryForConfirmedOrderLines(dataSource, entityMap, lines);
|
|
3023
3025
|
}
|
|
3024
|
-
chunkUSNT2KNT_cjs.__name(
|
|
3026
|
+
chunkUSNT2KNT_cjs.__name(validateInventoryForConfirmedOrderLines2, "validateInventoryForConfirmedOrderLines");
|
|
3025
3027
|
async function resolveProductTaxRate(dataSource, entityMap, productId, productVendorId) {
|
|
3026
3028
|
if (!entityMap.product_config || !entityMap.taxes) {
|
|
3027
3029
|
return {
|
|
@@ -5007,6 +5009,22 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5007
5009
|
status: 400
|
|
5008
5010
|
});
|
|
5009
5011
|
}
|
|
5012
|
+
if (resource === "combos") {
|
|
5013
|
+
const vendorIdForSlug = scopeCreate.type === "vendor" ? scopeCreate.vendorId : Number(persistBody.vendorId);
|
|
5014
|
+
if (!Number.isFinite(vendorIdForSlug) || vendorIdForSlug <= 0) {
|
|
5015
|
+
return json({
|
|
5016
|
+
error: "vendorId is required"
|
|
5017
|
+
}, {
|
|
5018
|
+
status: 400
|
|
5019
|
+
});
|
|
5020
|
+
}
|
|
5021
|
+
const comboSlugErr = await normalizeComboNameAndSlug(repo, persistBody, vendorIdForSlug);
|
|
5022
|
+
if (comboSlugErr) return json({
|
|
5023
|
+
error: comboSlugErr
|
|
5024
|
+
}, {
|
|
5025
|
+
status: 400
|
|
5026
|
+
});
|
|
5027
|
+
}
|
|
5010
5028
|
sanitizeBodyForEntity(repo, persistBody);
|
|
5011
5029
|
let created;
|
|
5012
5030
|
try {
|
|
@@ -5105,6 +5123,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5105
5123
|
persistBody.orderNumber = `ORD00${randomPart}`;
|
|
5106
5124
|
persistBody.qrToken = crypto2__default.default.randomBytes(16).toString("hex");
|
|
5107
5125
|
}
|
|
5126
|
+
await retireSoftDeletedUniquesFromBody(repo, persistBody);
|
|
5108
5127
|
created = await repo.save(repo.create(persistBody));
|
|
5109
5128
|
if (resource === "orders") {
|
|
5110
5129
|
const orderItemRepo = dataSource.getRepository(entityMap.order_items);
|
|
@@ -5146,8 +5165,8 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5146
5165
|
}
|
|
5147
5166
|
}
|
|
5148
5167
|
const createdStatus = String(persistBody.status ?? "pending");
|
|
5149
|
-
if (createdStatus
|
|
5150
|
-
const stockErr = await
|
|
5168
|
+
if (chunkHY3AXLOI_cjs.orderStatusHoldsStock(createdStatus)) {
|
|
5169
|
+
const stockErr = await validateInventoryForConfirmedOrderLines2(dataSource, entityMap, lines);
|
|
5151
5170
|
if (stockErr) {
|
|
5152
5171
|
await repo.delete(created.id);
|
|
5153
5172
|
return json({
|
|
@@ -5169,6 +5188,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5169
5188
|
await orderItemRepo.save(orderItemRepo.create({
|
|
5170
5189
|
orderId: created.id,
|
|
5171
5190
|
productId: line.productId,
|
|
5191
|
+
variantId: null,
|
|
5172
5192
|
quantity: line.quantity,
|
|
5173
5193
|
unitPrice: line.unitPrice,
|
|
5174
5194
|
subTotal: line.subtotal,
|
|
@@ -5244,10 +5264,10 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5244
5264
|
]
|
|
5245
5265
|
});
|
|
5246
5266
|
if (reloadedOrder) {
|
|
5247
|
-
const invErr = await reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, {
|
|
5267
|
+
const invErr = await chunkHY3AXLOI_cjs.reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, {
|
|
5248
5268
|
status: "pending",
|
|
5249
5269
|
lines: []
|
|
5250
|
-
}, orderInventorySnapshotFromRow(reloadedOrder));
|
|
5270
|
+
}, chunkHY3AXLOI_cjs.orderInventorySnapshotFromRow(reloadedOrder));
|
|
5251
5271
|
if (invErr) {
|
|
5252
5272
|
logCrudServerError("POST order inventory reconcile failed", {
|
|
5253
5273
|
message: invErr,
|
|
@@ -5262,7 +5282,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5262
5282
|
}
|
|
5263
5283
|
if (orderDiscountId) {
|
|
5264
5284
|
if (createdStatus === ORDER_STATUS_CONFIRMED) {
|
|
5265
|
-
const usageErr = await
|
|
5285
|
+
const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, orderDiscountId, persistBody.contactId);
|
|
5266
5286
|
if (usageErr) {
|
|
5267
5287
|
await repo.delete(created.id);
|
|
5268
5288
|
return json({
|
|
@@ -5272,7 +5292,7 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5272
5292
|
});
|
|
5273
5293
|
}
|
|
5274
5294
|
}
|
|
5275
|
-
await
|
|
5295
|
+
await recordDiscountUsage2(dataSource, entityMap, created.id, orderDiscountId, persistBody.contactId, discount);
|
|
5276
5296
|
}
|
|
5277
5297
|
const orderIdForNotify = created.id;
|
|
5278
5298
|
void import('./emit-order-notification-trigger-D2N3KFHL.cjs').then(({ fireOrderNotificationTrigger }) => {
|
|
@@ -5281,6 +5301,16 @@ function createCrudHandler(dataSource, entityMap, options) {
|
|
|
5281
5301
|
entityMap
|
|
5282
5302
|
});
|
|
5283
5303
|
});
|
|
5304
|
+
if (getCms) {
|
|
5305
|
+
void import('./send-order-placed-emails-B5ZVJT7T.cjs').then(({ sendOrderPlacedEmailsAfterConfirmation }) => {
|
|
5306
|
+
return sendOrderPlacedEmailsAfterConfirmation(orderIdForNotify, {
|
|
5307
|
+
getDataSource: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => dataSource, "getDataSource"),
|
|
5308
|
+
entityMap,
|
|
5309
|
+
getCms: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => await getCms(), "getCms")
|
|
5310
|
+
});
|
|
5311
|
+
}).catch(() => {
|
|
5312
|
+
});
|
|
5313
|
+
}
|
|
5284
5314
|
}
|
|
5285
5315
|
} catch (err) {
|
|
5286
5316
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -5926,6 +5956,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
5926
5956
|
}
|
|
5927
5957
|
}
|
|
5928
5958
|
sanitizeBodyForEntity(repo, updatePayload2);
|
|
5959
|
+
await retireSoftDeletedUniquesFromBody(repo, updatePayload2);
|
|
5929
5960
|
await repo.update(numericId, updatePayload2);
|
|
5930
5961
|
if (Array.isArray(rawBody.tags)) {
|
|
5931
5962
|
const tagNames = rawBody.tags.map((t) => String(t).trim()).filter(Boolean);
|
|
@@ -5987,7 +6018,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
5987
6018
|
status: 404
|
|
5988
6019
|
});
|
|
5989
6020
|
if (resource === "orders") {
|
|
5990
|
-
orderInvPrev = orderInventorySnapshotFromRow(cur);
|
|
6021
|
+
orderInvPrev = chunkHY3AXLOI_cjs.orderInventorySnapshotFromRow(cur);
|
|
5991
6022
|
}
|
|
5992
6023
|
}
|
|
5993
6024
|
if (resource === "orders" && rawBody && typeof rawBody === "object" && Array.isArray(rawBody.orderLines)) {
|
|
@@ -6014,8 +6045,8 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6014
6045
|
} : await calculateOrderTotalsFromLines(dataSource, entityMap, orderLinesNorm, effectiveCurrency, putDiscountId, Number.isFinite(putOrderVendorId) ? putOrderVendorId : null);
|
|
6015
6046
|
const scalarUpdate = pickColumnUpdates(repo, rawBody);
|
|
6016
6047
|
const nextStatus = typeof scalarUpdate.status === "string" && scalarUpdate.status ? String(scalarUpdate.status) : orderInvPrev?.status ?? "pending";
|
|
6017
|
-
if (nextStatus
|
|
6018
|
-
const verr = await validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, lines.filter((l) => l.found && l.productId != null).map((l) => ({
|
|
6048
|
+
if (chunkHY3AXLOI_cjs.orderStatusHoldsStock(nextStatus) && lines.length > 0) {
|
|
6049
|
+
const verr = await chunkHY3AXLOI_cjs.validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, lines.filter((l) => l.found && l.productId != null).map((l) => ({
|
|
6019
6050
|
productId: l.productId,
|
|
6020
6051
|
quantity: l.quantity
|
|
6021
6052
|
})));
|
|
@@ -6119,7 +6150,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6119
6150
|
status: 404
|
|
6120
6151
|
});
|
|
6121
6152
|
if (orderInvPrev) {
|
|
6122
|
-
const invErr = await reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, orderInvPrev, orderInventorySnapshotFromRow(updatedOrder));
|
|
6153
|
+
const invErr = await chunkHY3AXLOI_cjs.reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, orderInvPrev, chunkHY3AXLOI_cjs.orderInventorySnapshotFromRow(updatedOrder));
|
|
6123
6154
|
if (invErr) return json({
|
|
6124
6155
|
error: invErr
|
|
6125
6156
|
}, {
|
|
@@ -6143,17 +6174,17 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6143
6174
|
}) : null;
|
|
6144
6175
|
const existingDiscountId = existingOd ? existingOd.discountId : null;
|
|
6145
6176
|
if (!putDiscountId && existingDiscountId && wasConfirmed) {
|
|
6146
|
-
await
|
|
6177
|
+
await decrementDiscountUsage2(dataSource, entityMap, existingDiscountId, numericId);
|
|
6147
6178
|
if (entityMap["order_discounts"] && existingOd) {
|
|
6148
6179
|
await dataSource.getRepository(entityMap["order_discounts"]).delete(existingOd.id);
|
|
6149
6180
|
}
|
|
6150
6181
|
}
|
|
6151
6182
|
if (putDiscountId && existingDiscountId && putDiscountId !== existingDiscountId) {
|
|
6152
6183
|
if (wasConfirmed) {
|
|
6153
|
-
await
|
|
6184
|
+
await decrementDiscountUsage2(dataSource, entityMap, existingDiscountId, numericId);
|
|
6154
6185
|
}
|
|
6155
6186
|
if (isNowConfirmed) {
|
|
6156
|
-
const usageErr = await
|
|
6187
|
+
const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
|
|
6157
6188
|
if (usageErr) return json({
|
|
6158
6189
|
error: usageErr
|
|
6159
6190
|
}, {
|
|
@@ -6166,12 +6197,12 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6166
6197
|
discountAmount: discount
|
|
6167
6198
|
});
|
|
6168
6199
|
} else {
|
|
6169
|
-
await
|
|
6200
|
+
await recordDiscountUsage2(dataSource, entityMap, numericId, putDiscountId, cid, discount);
|
|
6170
6201
|
}
|
|
6171
6202
|
}
|
|
6172
6203
|
if (putDiscountId && existingDiscountId && putDiscountId === existingDiscountId) {
|
|
6173
6204
|
if (!wasConfirmed && isNowConfirmed) {
|
|
6174
|
-
const usageErr = await
|
|
6205
|
+
const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
|
|
6175
6206
|
if (usageErr) return json({
|
|
6176
6207
|
error: usageErr
|
|
6177
6208
|
}, {
|
|
@@ -6179,7 +6210,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6179
6210
|
});
|
|
6180
6211
|
}
|
|
6181
6212
|
if (wasConfirmed && !isNowConfirmed) {
|
|
6182
|
-
await
|
|
6213
|
+
await decrementDiscountUsage2(dataSource, entityMap, putDiscountId, numericId);
|
|
6183
6214
|
}
|
|
6184
6215
|
if (existingOd && entityMap["order_discounts"]) {
|
|
6185
6216
|
await dataSource.getRepository(entityMap["order_discounts"]).update(existingOd.id, {
|
|
@@ -6189,14 +6220,14 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6189
6220
|
}
|
|
6190
6221
|
if (putDiscountId && !existingDiscountId) {
|
|
6191
6222
|
if (isNowConfirmed) {
|
|
6192
|
-
const usageErr = await
|
|
6223
|
+
const usageErr = await checkAndIncrementDiscountUsage2(dataSource, entityMap, putDiscountId, cid);
|
|
6193
6224
|
if (usageErr) return json({
|
|
6194
6225
|
error: usageErr
|
|
6195
6226
|
}, {
|
|
6196
6227
|
status: 400
|
|
6197
6228
|
});
|
|
6198
6229
|
}
|
|
6199
|
-
await
|
|
6230
|
+
await recordDiscountUsage2(dataSource, entityMap, numericId, putDiscountId, cid, discount);
|
|
6200
6231
|
}
|
|
6201
6232
|
}
|
|
6202
6233
|
}
|
|
@@ -6667,8 +6698,8 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6667
6698
|
}
|
|
6668
6699
|
if (resource === "orders" && orderInvPrev) {
|
|
6669
6700
|
const nextSt = typeof updatePayload.status === "string" && updatePayload.status ? String(updatePayload.status) : orderInvPrev.status;
|
|
6670
|
-
if (nextSt
|
|
6671
|
-
const verr = await validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, orderInvPrev.lines);
|
|
6701
|
+
if (chunkHY3AXLOI_cjs.orderStatusHoldsStock(nextSt) && orderInvPrev.lines.length > 0) {
|
|
6702
|
+
const verr = await chunkHY3AXLOI_cjs.validateInventoryForOrderBecomingConfirmed(dataSource, entityMap, orderInvPrev, orderInvPrev.lines);
|
|
6672
6703
|
if (verr) return json({
|
|
6673
6704
|
error: verr
|
|
6674
6705
|
}, {
|
|
@@ -6676,6 +6707,33 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6676
6707
|
});
|
|
6677
6708
|
}
|
|
6678
6709
|
}
|
|
6710
|
+
if (resource === "combos") {
|
|
6711
|
+
const currentCombo = await repo.findOne({
|
|
6712
|
+
where: {
|
|
6713
|
+
id: numericId,
|
|
6714
|
+
deleted: false
|
|
6715
|
+
}
|
|
6716
|
+
});
|
|
6717
|
+
if (!currentCombo) return json({
|
|
6718
|
+
message: "Not found"
|
|
6719
|
+
}, {
|
|
6720
|
+
status: 404
|
|
6721
|
+
});
|
|
6722
|
+
const vendorIdForSlug = scopePut.type === "vendor" ? scopePut.vendorId : Number(currentCombo.vendorId);
|
|
6723
|
+
if (!Number.isFinite(vendorIdForSlug) || vendorIdForSlug <= 0) {
|
|
6724
|
+
return json({
|
|
6725
|
+
error: "vendorId is required"
|
|
6726
|
+
}, {
|
|
6727
|
+
status: 400
|
|
6728
|
+
});
|
|
6729
|
+
}
|
|
6730
|
+
const comboSlugErr = await normalizeComboNameAndSlug(repo, updatePayload, vendorIdForSlug, currentCombo, numericId);
|
|
6731
|
+
if (comboSlugErr) return json({
|
|
6732
|
+
error: comboSlugErr
|
|
6733
|
+
}, {
|
|
6734
|
+
status: 400
|
|
6735
|
+
});
|
|
6736
|
+
}
|
|
6679
6737
|
if (Object.keys(updatePayload).length > 0) {
|
|
6680
6738
|
if (resource === "payments" && updatePayload.status === "paid" && updatePayload.paidAt == null) {
|
|
6681
6739
|
const existingPayment = await repo.findOne({
|
|
@@ -6689,6 +6747,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6689
6747
|
}
|
|
6690
6748
|
}
|
|
6691
6749
|
sanitizeBodyForEntity(repo, updatePayload);
|
|
6750
|
+
await retireSoftDeletedUniquesFromBody(repo, updatePayload);
|
|
6692
6751
|
await repo.update(numericId, updatePayload);
|
|
6693
6752
|
}
|
|
6694
6753
|
if (resource === "orders" && rawBody && entityMap["order_addresses"]) {
|
|
@@ -6741,7 +6800,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6741
6800
|
}
|
|
6742
6801
|
});
|
|
6743
6802
|
if (resource === "orders" && orderInvPrev && updated) {
|
|
6744
|
-
const invErr = await reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, orderInvPrev, orderInventorySnapshotFromRow(updated));
|
|
6803
|
+
const invErr = await chunkHY3AXLOI_cjs.reconcileOrderInventoryBetweenSnapshots(dataSource, entityMap, orderInvPrev, chunkHY3AXLOI_cjs.orderInventorySnapshotFromRow(updated));
|
|
6745
6804
|
if (invErr) return json({
|
|
6746
6805
|
error: invErr
|
|
6747
6806
|
}, {
|
|
@@ -6864,7 +6923,7 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6864
6923
|
});
|
|
6865
6924
|
if (od) {
|
|
6866
6925
|
const odRow = od;
|
|
6867
|
-
await
|
|
6926
|
+
await decrementDiscountUsage2(dataSource, entityMap, odRow.discountId, numericId);
|
|
6868
6927
|
}
|
|
6869
6928
|
}
|
|
6870
6929
|
}
|
|
@@ -6877,11 +6936,19 @@ function createCrudByIdHandler(dataSource, entityMap, options) {
|
|
|
6877
6936
|
}
|
|
6878
6937
|
}
|
|
6879
6938
|
await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy));
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6939
|
+
const softDeletedCols = repo.metadata.columns.map((c) => c.propertyName);
|
|
6940
|
+
const uniqueColsToRetire = [
|
|
6941
|
+
"slug",
|
|
6942
|
+
"email"
|
|
6943
|
+
].filter((col) => softDeletedCols.includes(col));
|
|
6944
|
+
if (existing && uniqueColsToRetire.length > 0) {
|
|
6945
|
+
for (const col of uniqueColsToRetire) {
|
|
6946
|
+
const raw = existing[col];
|
|
6947
|
+
if (typeof raw !== "string") continue;
|
|
6948
|
+
const value = raw.trim();
|
|
6949
|
+
if (!value || value.includes("__deleted_")) continue;
|
|
6883
6950
|
await repo.update(numericId, {
|
|
6884
|
-
|
|
6951
|
+
[col]: `${value}__deleted_${numericId}`
|
|
6885
6952
|
});
|
|
6886
6953
|
}
|
|
6887
6954
|
}
|
|
@@ -6929,6 +6996,49 @@ async function linkUnclaimedContactToUser(dataSource, contactsEntity, userId, em
|
|
|
6929
6996
|
});
|
|
6930
6997
|
}
|
|
6931
6998
|
chunkUSNT2KNT_cjs.__name(linkUnclaimedContactToUser, "linkUnclaimedContactToUser");
|
|
6999
|
+
function buildUserInviteLink(baseUrl, token) {
|
|
7000
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
7001
|
+
return `${base}/admin/invite?token=${encodeURIComponent(token)}`;
|
|
7002
|
+
}
|
|
7003
|
+
chunkUSNT2KNT_cjs.__name(buildUserInviteLink, "buildUserInviteLink");
|
|
7004
|
+
function newUserInviteToken() {
|
|
7005
|
+
return crypto2.randomBytes(32).toString("hex");
|
|
7006
|
+
}
|
|
7007
|
+
chunkUSNT2KNT_cjs.__name(newUserInviteToken, "newUserInviteToken");
|
|
7008
|
+
async function findUserByInviteToken(dataSource, userEntity, token) {
|
|
7009
|
+
const trimmed = token.trim();
|
|
7010
|
+
if (!trimmed) return null;
|
|
7011
|
+
const repo = dataSource.getRepository(userEntity);
|
|
7012
|
+
const row = await repo.findOne({
|
|
7013
|
+
where: {
|
|
7014
|
+
inviteToken: trimmed,
|
|
7015
|
+
deleted: false
|
|
7016
|
+
},
|
|
7017
|
+
select: [
|
|
7018
|
+
"id",
|
|
7019
|
+
"email",
|
|
7020
|
+
"blocked",
|
|
7021
|
+
"password",
|
|
7022
|
+
"inviteStatus",
|
|
7023
|
+
"inviteToken"
|
|
7024
|
+
]
|
|
7025
|
+
});
|
|
7026
|
+
if (!row) return null;
|
|
7027
|
+
const u = row;
|
|
7028
|
+
return u;
|
|
7029
|
+
}
|
|
7030
|
+
chunkUSNT2KNT_cjs.__name(findUserByInviteToken, "findUserByInviteToken");
|
|
7031
|
+
async function completeUserInviteAccept(dataSource, userEntity, userId, passwordHash) {
|
|
7032
|
+
await dataSource.getRepository(userEntity).update(userId, {
|
|
7033
|
+
password: passwordHash,
|
|
7034
|
+
blocked: false,
|
|
7035
|
+
inviteStatus: "active",
|
|
7036
|
+
inviteToken: null
|
|
7037
|
+
});
|
|
7038
|
+
}
|
|
7039
|
+
chunkUSNT2KNT_cjs.__name(completeUserInviteAccept, "completeUserInviteAccept");
|
|
7040
|
+
|
|
7041
|
+
// src/lib/vendor-invite-token.ts
|
|
6932
7042
|
var VENDOR_INVITE_METADATA_TOKEN = "inviteToken";
|
|
6933
7043
|
var VENDOR_INVITE_METADATA_EXPIRES = "inviteExpiresAt";
|
|
6934
7044
|
var VENDOR_INVITE_METADATA_SENT = "inviteSentAt";
|
|
@@ -6953,6 +7063,13 @@ function invalidatedInviteMessage() {
|
|
|
6953
7063
|
return "This invitation is no longer valid. Ask an admin to resend the invite.";
|
|
6954
7064
|
}
|
|
6955
7065
|
chunkUSNT2KNT_cjs.__name(invalidatedInviteMessage, "invalidatedInviteMessage");
|
|
7066
|
+
function userAlreadyActive(user) {
|
|
7067
|
+
const hasPassword = !!(user.password && String(user.password).trim());
|
|
7068
|
+
if (user.inviteStatus === "active" && hasPassword) return true;
|
|
7069
|
+
if (user.inviteStatus === "pending") return false;
|
|
7070
|
+
return !user.blocked && hasPassword;
|
|
7071
|
+
}
|
|
7072
|
+
chunkUSNT2KNT_cjs.__name(userAlreadyActive, "userAlreadyActive");
|
|
6956
7073
|
async function validateInviteTokenForActivation(dataSource, entityMap, token) {
|
|
6957
7074
|
const trimmedToken = String(token ?? "").trim();
|
|
6958
7075
|
if (!trimmedToken) {
|
|
@@ -6999,15 +7116,15 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
|
|
|
6999
7116
|
"id",
|
|
7000
7117
|
"email",
|
|
7001
7118
|
"blocked",
|
|
7002
|
-
"password"
|
|
7119
|
+
"password",
|
|
7120
|
+
"inviteStatus"
|
|
7003
7121
|
]
|
|
7004
7122
|
});
|
|
7005
7123
|
if (!user2) return {
|
|
7006
7124
|
ok: false,
|
|
7007
7125
|
error: "User not found"
|
|
7008
7126
|
};
|
|
7009
|
-
|
|
7010
|
-
if (!user2.blocked && hasPassword2) {
|
|
7127
|
+
if (userAlreadyActive(user2)) {
|
|
7011
7128
|
return {
|
|
7012
7129
|
ok: false,
|
|
7013
7130
|
error: "User is already active"
|
|
@@ -7023,6 +7140,24 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
|
|
|
7023
7140
|
};
|
|
7024
7141
|
}
|
|
7025
7142
|
}
|
|
7143
|
+
if (userRepo && entityMap.users) {
|
|
7144
|
+
const userMatch = await findUserByInviteToken(dataSource, entityMap.users, trimmedToken);
|
|
7145
|
+
if (userMatch) {
|
|
7146
|
+
if (userMatch.inviteStatus === "active" || userAlreadyActive(userMatch)) {
|
|
7147
|
+
return {
|
|
7148
|
+
ok: false,
|
|
7149
|
+
error: "This invitation has already been accepted"
|
|
7150
|
+
};
|
|
7151
|
+
}
|
|
7152
|
+
return {
|
|
7153
|
+
ok: true,
|
|
7154
|
+
target: {
|
|
7155
|
+
userId: userMatch.id,
|
|
7156
|
+
email: userMatch.email
|
|
7157
|
+
}
|
|
7158
|
+
};
|
|
7159
|
+
}
|
|
7160
|
+
}
|
|
7026
7161
|
let email;
|
|
7027
7162
|
try {
|
|
7028
7163
|
email = Buffer.from(trimmedToken, "base64").toString("utf8").trim();
|
|
@@ -7052,22 +7187,30 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
|
|
|
7052
7187
|
"id",
|
|
7053
7188
|
"email",
|
|
7054
7189
|
"blocked",
|
|
7055
|
-
"password"
|
|
7190
|
+
"password",
|
|
7191
|
+
"inviteStatus",
|
|
7192
|
+
"inviteToken"
|
|
7056
7193
|
]
|
|
7057
7194
|
});
|
|
7058
7195
|
if (!user) return {
|
|
7059
7196
|
ok: false,
|
|
7060
7197
|
error: "User not found"
|
|
7061
7198
|
};
|
|
7062
|
-
const
|
|
7063
|
-
if (
|
|
7199
|
+
const u = user;
|
|
7200
|
+
if (userAlreadyActive(u)) {
|
|
7064
7201
|
return {
|
|
7065
7202
|
ok: false,
|
|
7066
7203
|
error: "User is already active"
|
|
7067
7204
|
};
|
|
7068
7205
|
}
|
|
7206
|
+
if (u.inviteToken && String(u.inviteToken).trim()) {
|
|
7207
|
+
return {
|
|
7208
|
+
ok: false,
|
|
7209
|
+
error: invalidatedInviteMessage()
|
|
7210
|
+
};
|
|
7211
|
+
}
|
|
7069
7212
|
if (entityMap.vendors) {
|
|
7070
|
-
const ownerVendor = await loadOwnerVendorForUser(dataSource, entityMap.vendors,
|
|
7213
|
+
const ownerVendor = await loadOwnerVendorForUser(dataSource, entityMap.vendors, u.id);
|
|
7071
7214
|
if (ownerVendor && readVendorInviteToken(ownerVendor.metadata)) {
|
|
7072
7215
|
return {
|
|
7073
7216
|
ok: false,
|
|
@@ -7078,8 +7221,8 @@ async function validateInviteTokenForActivation(dataSource, entityMap, token) {
|
|
|
7078
7221
|
return {
|
|
7079
7222
|
ok: true,
|
|
7080
7223
|
target: {
|
|
7081
|
-
userId:
|
|
7082
|
-
email: String(
|
|
7224
|
+
userId: u.id,
|
|
7225
|
+
email: String(u.email)
|
|
7083
7226
|
}
|
|
7084
7227
|
};
|
|
7085
7228
|
}
|
|
@@ -7297,10 +7440,7 @@ function createInviteAcceptHandler(config) {
|
|
|
7297
7440
|
}
|
|
7298
7441
|
if (beforeActivate) await beforeActivate(email, userId);
|
|
7299
7442
|
const hashedPassword = await hashPassword(password);
|
|
7300
|
-
await dataSource
|
|
7301
|
-
password: hashedPassword,
|
|
7302
|
-
blocked: false
|
|
7303
|
-
});
|
|
7443
|
+
await completeUserInviteAccept(dataSource, entityMap.users, userId, hashedPassword);
|
|
7304
7444
|
if (vendorId != null && entityMap.vendors) {
|
|
7305
7445
|
await completeVendorInviteAccept(dataSource, entityMap.vendors, vendorId);
|
|
7306
7446
|
}
|
|
@@ -7661,50 +7801,6 @@ async function findLlmAgentByScope(dataSource, entityMap, scope, options = {}) {
|
|
|
7661
7801
|
}
|
|
7662
7802
|
chunkUSNT2KNT_cjs.__name(findLlmAgentByScope, "findLlmAgentByScope");
|
|
7663
7803
|
|
|
7664
|
-
// src/lib/retire-soft-deleted-unique.ts
|
|
7665
|
-
async function retireSoftDeletedUniqueValue(repo, column, value) {
|
|
7666
|
-
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
7667
|
-
if (!trimmed) return;
|
|
7668
|
-
const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
|
|
7669
|
-
if (!cols.has(column) || !cols.has("deleted")) return;
|
|
7670
|
-
const rows = await repo.find({
|
|
7671
|
-
where: {
|
|
7672
|
-
[column]: trimmed,
|
|
7673
|
-
deleted: true
|
|
7674
|
-
}
|
|
7675
|
-
});
|
|
7676
|
-
for (const row of rows) {
|
|
7677
|
-
const id = row.id;
|
|
7678
|
-
if (!Number.isFinite(id)) continue;
|
|
7679
|
-
const current = String(row[column] ?? "");
|
|
7680
|
-
if (current.includes("__deleted_")) continue;
|
|
7681
|
-
await repo.update(id, {
|
|
7682
|
-
[column]: `${trimmed}__deleted_${id}`
|
|
7683
|
-
});
|
|
7684
|
-
}
|
|
7685
|
-
}
|
|
7686
|
-
chunkUSNT2KNT_cjs.__name(retireSoftDeletedUniqueValue, "retireSoftDeletedUniqueValue");
|
|
7687
|
-
async function activeUniqueValueExists(repo, column, value, excludeId) {
|
|
7688
|
-
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
7689
|
-
if (!trimmed) return false;
|
|
7690
|
-
const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));
|
|
7691
|
-
if (!cols.has(column)) return false;
|
|
7692
|
-
const qb = repo.createQueryBuilder("row").where(`row.${column} = :value`, {
|
|
7693
|
-
value: trimmed
|
|
7694
|
-
});
|
|
7695
|
-
if (cols.has("deleted")) {
|
|
7696
|
-
qb.andWhere("row.deleted = false");
|
|
7697
|
-
}
|
|
7698
|
-
if (excludeId != null && Number.isFinite(excludeId) && excludeId > 0) {
|
|
7699
|
-
qb.andWhere("row.id != :excludeId", {
|
|
7700
|
-
excludeId
|
|
7701
|
-
});
|
|
7702
|
-
}
|
|
7703
|
-
const hit = await qb.getOne();
|
|
7704
|
-
return !!hit;
|
|
7705
|
-
}
|
|
7706
|
-
chunkUSNT2KNT_cjs.__name(activeUniqueValueExists, "activeUniqueValueExists");
|
|
7707
|
-
|
|
7708
7804
|
// src/lib/media-folder-path.ts
|
|
7709
7805
|
function sanitizeMediaFolderPath(input) {
|
|
7710
7806
|
if (input == null) return "";
|
|
@@ -8771,6 +8867,9 @@ function createUploadHandler(config) {
|
|
|
8771
8867
|
"image/png",
|
|
8772
8868
|
"image/gif",
|
|
8773
8869
|
"image/webp",
|
|
8870
|
+
"video/mp4",
|
|
8871
|
+
"video/webm",
|
|
8872
|
+
"video/quicktime",
|
|
8774
8873
|
"application/pdf",
|
|
8775
8874
|
"text/plain",
|
|
8776
8875
|
"application/zip",
|
|
@@ -8798,8 +8897,11 @@ function createUploadHandler(config) {
|
|
|
8798
8897
|
});
|
|
8799
8898
|
const defaultMax = 10 * 1024 * 1024;
|
|
8800
8899
|
const maxZipBytes = 80 * 1024 * 1024;
|
|
8900
|
+
const maxVideoBytes = 100 * 1024 * 1024;
|
|
8801
8901
|
const baseMax = maxSizeBytes ?? defaultMax;
|
|
8802
|
-
const
|
|
8902
|
+
const isZip = file.type === "application/zip" || file.type === "application/x-zip-compressed";
|
|
8903
|
+
const isVideo = file.type === "video/mp4" || file.type === "video/webm" || file.type === "video/quicktime";
|
|
8904
|
+
const effectiveMax = isZip ? Math.max(baseMax, maxZipBytes) : isVideo ? Math.max(baseMax, maxVideoBytes) : baseMax;
|
|
8803
8905
|
if (file.size > effectiveMax) return json({
|
|
8804
8906
|
error: "File size exceeds limit"
|
|
8805
8907
|
}, {
|
|
@@ -8872,12 +8974,20 @@ function createUploadHandler(config) {
|
|
|
8872
8974
|
parentId
|
|
8873
8975
|
});
|
|
8874
8976
|
} catch (err) {
|
|
8977
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
8875
8978
|
console.error("[upload] File upload failed", {
|
|
8876
|
-
error:
|
|
8979
|
+
error: message,
|
|
8877
8980
|
stack: err instanceof Error ? err.stack : void 0,
|
|
8878
8981
|
name: err instanceof Error ? err.name : void 0,
|
|
8879
8982
|
metadata: err && typeof err === "object" && "$metadata" in err ? err.$metadata : void 0
|
|
8880
8983
|
});
|
|
8984
|
+
if (/Failed to parse body as FormData/i.test(message)) {
|
|
8985
|
+
return json({
|
|
8986
|
+
error: "File upload failed: request body could not be read as FormData. Exclude /api/upload from middleware matcher and raise proxyClientMaxBodySize."
|
|
8987
|
+
}, {
|
|
8988
|
+
status: 500
|
|
8989
|
+
});
|
|
8990
|
+
}
|
|
8881
8991
|
return json({
|
|
8882
8992
|
error: "File upload failed"
|
|
8883
8993
|
}, {
|
|
@@ -9100,14 +9210,14 @@ function createFormSaveHandlers(config) {
|
|
|
9100
9210
|
const { fields: _f, ...formRow } = body;
|
|
9101
9211
|
const slug = typeof formRow.slug === "string" ? formRow.slug.trim() : "";
|
|
9102
9212
|
if (slug) {
|
|
9103
|
-
if (await activeUniqueValueExists(formRepo(), "slug", slug)) {
|
|
9213
|
+
if (await chunkOY2YTBMP_cjs.activeUniqueValueExists(formRepo(), "slug", slug)) {
|
|
9104
9214
|
return json({
|
|
9105
9215
|
error: "A form with this slug already exists"
|
|
9106
9216
|
}, {
|
|
9107
9217
|
status: 400
|
|
9108
9218
|
});
|
|
9109
9219
|
}
|
|
9110
|
-
await retireSoftDeletedUniqueValue(formRepo(), "slug", slug);
|
|
9220
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(formRepo(), "slug", slug);
|
|
9111
9221
|
}
|
|
9112
9222
|
const form = await formRepo().save(formRepo().create(formRow));
|
|
9113
9223
|
for (let i = 0; i < fields.length; i++) {
|
|
@@ -9192,14 +9302,14 @@ function createFormSaveHandlers(config) {
|
|
|
9192
9302
|
const slug = formRow.slug.trim();
|
|
9193
9303
|
formRow.slug = slug;
|
|
9194
9304
|
if (slug) {
|
|
9195
|
-
if (await activeUniqueValueExists(formRepo(), "slug", slug, formId)) {
|
|
9305
|
+
if (await chunkOY2YTBMP_cjs.activeUniqueValueExists(formRepo(), "slug", slug, formId)) {
|
|
9196
9306
|
return json({
|
|
9197
9307
|
error: "A form with this slug already exists"
|
|
9198
9308
|
}, {
|
|
9199
9309
|
status: 400
|
|
9200
9310
|
});
|
|
9201
9311
|
}
|
|
9202
|
-
await retireSoftDeletedUniqueValue(formRepo(), "slug", slug);
|
|
9312
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(formRepo(), "slug", slug);
|
|
9203
9313
|
}
|
|
9204
9314
|
}
|
|
9205
9315
|
if (Object.keys(formRow).length > 0) await formRepo().update(formId, formRow);
|
|
@@ -9542,7 +9652,7 @@ function createFormSubmissionHandler(config) {
|
|
|
9542
9652
|
label: f.label && String(f.label).trim() || `Field ${f.id}`,
|
|
9543
9653
|
value: formatSubmissionFieldValue(data[String(f.id)])
|
|
9544
9654
|
}));
|
|
9545
|
-
await
|
|
9655
|
+
await chunkV25RDUOU_cjs.queueEmail(cms, {
|
|
9546
9656
|
to,
|
|
9547
9657
|
templateName: "formSubmission",
|
|
9548
9658
|
ctx: {
|
|
@@ -9596,7 +9706,7 @@ function createUsersApiHandlers(config) {
|
|
|
9596
9706
|
try {
|
|
9597
9707
|
const cms = await getCms();
|
|
9598
9708
|
const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};
|
|
9599
|
-
await
|
|
9709
|
+
await chunkV25RDUOU_cjs.queueEmail(cms, {
|
|
9600
9710
|
to: toEmail,
|
|
9601
9711
|
templateName: "invite",
|
|
9602
9712
|
ctx: {
|
|
@@ -9631,7 +9741,8 @@ function createUsersApiHandlers(config) {
|
|
|
9631
9741
|
"name",
|
|
9632
9742
|
"email",
|
|
9633
9743
|
"id",
|
|
9634
|
-
"blocked"
|
|
9744
|
+
"blocked",
|
|
9745
|
+
"inviteStatus"
|
|
9635
9746
|
]);
|
|
9636
9747
|
const sortField = allowedSort.has(sortFieldRaw) ? sortFieldRaw : "createdAt";
|
|
9637
9748
|
const sortOrder = url.searchParams.get("sortOrder") === "desc" ? "DESC" : "ASC";
|
|
@@ -9644,6 +9755,7 @@ function createUsersApiHandlers(config) {
|
|
|
9644
9755
|
"u.name",
|
|
9645
9756
|
"u.email",
|
|
9646
9757
|
"u.blocked",
|
|
9758
|
+
"u.inviteStatus",
|
|
9647
9759
|
"u.createdAt",
|
|
9648
9760
|
"u.updatedAt",
|
|
9649
9761
|
"u.groupId",
|
|
@@ -9739,6 +9851,7 @@ function createUsersApiHandlers(config) {
|
|
|
9739
9851
|
const isCustomer = !!(customerG && gid === customerG.id);
|
|
9740
9852
|
const adminAccess = isCustomer ? false : body.adminAccess === false ? false : true;
|
|
9741
9853
|
const blocked = body.blocked === true || body.blocked === "true" || body.blocked === 1 || body.blocked === "1";
|
|
9854
|
+
const inviteToken = newUserInviteToken();
|
|
9742
9855
|
const newUser = existing?.deleted ? await (async () => {
|
|
9743
9856
|
await userRepo().update(existing.id, {
|
|
9744
9857
|
deleted: false,
|
|
@@ -9748,6 +9861,8 @@ function createUsersApiHandlers(config) {
|
|
|
9748
9861
|
email,
|
|
9749
9862
|
password: null,
|
|
9750
9863
|
blocked,
|
|
9864
|
+
inviteStatus: "pending",
|
|
9865
|
+
inviteToken,
|
|
9751
9866
|
groupId: gid,
|
|
9752
9867
|
adminAccess,
|
|
9753
9868
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -9764,6 +9879,8 @@ function createUsersApiHandlers(config) {
|
|
|
9764
9879
|
email,
|
|
9765
9880
|
password: null,
|
|
9766
9881
|
blocked,
|
|
9882
|
+
inviteStatus: "pending",
|
|
9883
|
+
inviteToken,
|
|
9767
9884
|
groupId: gid,
|
|
9768
9885
|
adminAccess
|
|
9769
9886
|
}));
|
|
@@ -9781,13 +9898,12 @@ function createUsersApiHandlers(config) {
|
|
|
9781
9898
|
phone
|
|
9782
9899
|
});
|
|
9783
9900
|
}
|
|
9784
|
-
const
|
|
9785
|
-
const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;
|
|
9786
|
-
await trySendInviteEmail(newUser.email, inviteLink, newUser.name ?? "");
|
|
9901
|
+
const inviteLink = buildUserInviteLink(baseUrl, inviteToken);
|
|
9787
9902
|
return json({
|
|
9788
|
-
message:
|
|
9903
|
+
message: "User created successfully. Invite is pending until they set a password.",
|
|
9789
9904
|
user: newUser,
|
|
9790
|
-
inviteLink
|
|
9905
|
+
inviteLink,
|
|
9906
|
+
emailSent: false
|
|
9791
9907
|
}, {
|
|
9792
9908
|
status: 201
|
|
9793
9909
|
});
|
|
@@ -9821,6 +9937,7 @@ function createUsersApiHandlers(config) {
|
|
|
9821
9937
|
"email",
|
|
9822
9938
|
"phone",
|
|
9823
9939
|
"blocked",
|
|
9940
|
+
"inviteStatus",
|
|
9824
9941
|
"createdAt",
|
|
9825
9942
|
"updatedAt",
|
|
9826
9943
|
"groupId"
|
|
@@ -9933,6 +10050,7 @@ function createUsersApiHandlers(config) {
|
|
|
9933
10050
|
"email",
|
|
9934
10051
|
"phone",
|
|
9935
10052
|
"blocked",
|
|
10053
|
+
"inviteStatus",
|
|
9936
10054
|
"createdAt",
|
|
9937
10055
|
"updatedAt",
|
|
9938
10056
|
"groupId"
|
|
@@ -10000,13 +10118,21 @@ function createUsersApiHandlers(config) {
|
|
|
10000
10118
|
});
|
|
10001
10119
|
}
|
|
10002
10120
|
},
|
|
10003
|
-
async regenerateInvite(
|
|
10004
|
-
const authErr = await requireAuth(new Request(
|
|
10121
|
+
async regenerateInvite(req, id) {
|
|
10122
|
+
const authErr = await requireAuth(new Request(req.url));
|
|
10005
10123
|
if (authErr) return authErr;
|
|
10006
10124
|
if (requireEntityPermission) {
|
|
10007
|
-
const pe = await requireEntityPermission(
|
|
10125
|
+
const pe = await requireEntityPermission(req, "users", "update");
|
|
10008
10126
|
if (pe) return pe;
|
|
10009
10127
|
}
|
|
10128
|
+
let sendEmail = true;
|
|
10129
|
+
let rotate = true;
|
|
10130
|
+
try {
|
|
10131
|
+
const body = await req.json().catch(() => ({}));
|
|
10132
|
+
if (body.sendEmail === false) sendEmail = false;
|
|
10133
|
+
if (body.rotate === false) rotate = false;
|
|
10134
|
+
} catch {
|
|
10135
|
+
}
|
|
10010
10136
|
try {
|
|
10011
10137
|
const user = await userRepo().findOne({
|
|
10012
10138
|
where: {
|
|
@@ -10016,7 +10142,11 @@ function createUsersApiHandlers(config) {
|
|
|
10016
10142
|
select: [
|
|
10017
10143
|
"id",
|
|
10018
10144
|
"email",
|
|
10019
|
-
"name"
|
|
10145
|
+
"name",
|
|
10146
|
+
"password",
|
|
10147
|
+
"inviteStatus",
|
|
10148
|
+
"inviteToken",
|
|
10149
|
+
"blocked"
|
|
10020
10150
|
]
|
|
10021
10151
|
});
|
|
10022
10152
|
if (!user) return json({
|
|
@@ -10024,34 +10154,75 @@ function createUsersApiHandlers(config) {
|
|
|
10024
10154
|
}, {
|
|
10025
10155
|
status: 404
|
|
10026
10156
|
});
|
|
10027
|
-
|
|
10157
|
+
const u = user;
|
|
10158
|
+
const hasPassword = !!(u.password && String(u.password).trim());
|
|
10159
|
+
if (u.inviteStatus === "active" && hasPassword) {
|
|
10160
|
+
return json({
|
|
10161
|
+
error: "User has already accepted the invite"
|
|
10162
|
+
}, {
|
|
10163
|
+
status: 400
|
|
10164
|
+
});
|
|
10165
|
+
}
|
|
10166
|
+
let inviteLink = "";
|
|
10028
10167
|
if (entityMap.vendors) {
|
|
10029
10168
|
const vendorRepo = dataSource.getRepository(entityMap.vendors);
|
|
10030
10169
|
const vendor = await vendorRepo.findOne({
|
|
10031
10170
|
where: {
|
|
10032
|
-
userId:
|
|
10171
|
+
userId: u.id,
|
|
10033
10172
|
deleted: false
|
|
10034
10173
|
}
|
|
10035
10174
|
});
|
|
10036
10175
|
const v = vendor;
|
|
10037
10176
|
if (v && (v.inviteStatus === "pending" || v.inviteStatus === "expired")) {
|
|
10038
|
-
const
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
|
|
10177
|
+
const nextMetadata = rotate ? applyRotatingVendorInvite(v.metadata) : {
|
|
10178
|
+
...v.metadata ?? {}
|
|
10179
|
+
};
|
|
10180
|
+
if (rotate || v.inviteStatus !== "pending") {
|
|
10181
|
+
await vendorRepo.update(v.id, {
|
|
10182
|
+
metadata: nextMetadata,
|
|
10183
|
+
inviteStatus: "pending"
|
|
10184
|
+
});
|
|
10185
|
+
}
|
|
10186
|
+
const token = readVendorInviteToken(nextMetadata);
|
|
10044
10187
|
if (token) {
|
|
10045
10188
|
inviteLink = buildVendorInviteLink(baseUrl, token);
|
|
10046
10189
|
}
|
|
10190
|
+
const { markVendorInvitePendingForUser } = await import('./vendor-invite-status-77O7ZQ3U.cjs');
|
|
10191
|
+
await markVendorInvitePendingForUser(dataSource, entityMap.vendors, u.id);
|
|
10192
|
+
}
|
|
10193
|
+
}
|
|
10194
|
+
if (!inviteLink) {
|
|
10195
|
+
let token = u.inviteToken?.trim() || "";
|
|
10196
|
+
if (rotate || !token) {
|
|
10197
|
+
token = newUserInviteToken();
|
|
10198
|
+
await userRepo().update(u.id, {
|
|
10199
|
+
inviteToken: token,
|
|
10200
|
+
inviteStatus: "pending",
|
|
10201
|
+
password: null
|
|
10202
|
+
});
|
|
10203
|
+
} else if (u.inviteStatus !== "pending") {
|
|
10204
|
+
await userRepo().update(u.id, {
|
|
10205
|
+
inviteStatus: "pending"
|
|
10206
|
+
});
|
|
10047
10207
|
}
|
|
10048
|
-
|
|
10049
|
-
|
|
10208
|
+
inviteLink = buildUserInviteLink(baseUrl, token);
|
|
10209
|
+
} else if (rotate) {
|
|
10210
|
+
await userRepo().update(u.id, {
|
|
10211
|
+
inviteStatus: "pending",
|
|
10212
|
+
password: null
|
|
10213
|
+
});
|
|
10050
10214
|
}
|
|
10051
|
-
|
|
10215
|
+
let emailSent = false;
|
|
10216
|
+
if (sendEmail && inviteLink) {
|
|
10217
|
+
await trySendInviteEmail(u.email, inviteLink, u.name ?? "");
|
|
10218
|
+
emailSent = true;
|
|
10219
|
+
}
|
|
10220
|
+
const rotatedNote = rotate ? " Previous invite link is no longer valid." : "";
|
|
10052
10221
|
return json({
|
|
10053
|
-
message: "New invite link
|
|
10054
|
-
|
|
10222
|
+
message: emailSent ? `Invite email sent.${rotatedNote}` : sendEmail ? `Invite link ready (email may not have been sent \u2014 check email plugin).${rotatedNote}` : rotate ? "New invite link created. Previous invite link is no longer valid." : "Invite link ready.",
|
|
10223
|
+
emailSent,
|
|
10224
|
+
inviteLink,
|
|
10225
|
+
inviteStatus: "pending"
|
|
10055
10226
|
});
|
|
10056
10227
|
} catch {
|
|
10057
10228
|
return json({
|
|
@@ -10808,7 +10979,7 @@ function createChatHandlers(config) {
|
|
|
10808
10979
|
const notifyEmailAgent = await findLlmAgentByScope(dataSource, entityMap, LLM_AGENT_SCOPE_EMAIL_INTENT_CHATBOT, {
|
|
10809
10980
|
enabledOnly: false
|
|
10810
10981
|
});
|
|
10811
|
-
const emailTool =
|
|
10982
|
+
const emailTool = chunkTCSGFAWB_cjs.resolveChatEmailToolSettings(llmSettings, {
|
|
10812
10983
|
chatbotValidationRules: agentRow?.validationRules ?? null,
|
|
10813
10984
|
notifyAgent: notifyEmailAgent ? {
|
|
10814
10985
|
systemInstruction: notifyEmailAgent.systemInstruction,
|
|
@@ -10818,7 +10989,7 @@ function createChatHandlers(config) {
|
|
|
10818
10989
|
const emailPlugin2 = cms.getPlugin("email");
|
|
10819
10990
|
const convLeadSent = conv.leadEmailSentAt;
|
|
10820
10991
|
const chatAgentFn = llm.chatAgent?.bind(llm);
|
|
10821
|
-
console.info(
|
|
10992
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline check", {
|
|
10822
10993
|
conversationId,
|
|
10823
10994
|
enabled: emailTool.enabled,
|
|
10824
10995
|
intentCount: emailTool.intents.length,
|
|
@@ -10832,27 +11003,27 @@ function createChatHandlers(config) {
|
|
|
10832
11003
|
mergedPromptIncludesNotify: Boolean(notifyEmailAgent?.systemInstruction?.trim())
|
|
10833
11004
|
});
|
|
10834
11005
|
if (!emailTool.enabled) {
|
|
10835
|
-
console.info(
|
|
11006
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10836
11007
|
conversationId,
|
|
10837
11008
|
reason: "email_tool_disabled"
|
|
10838
11009
|
});
|
|
10839
11010
|
} else if (emailTool.intents.length === 0) {
|
|
10840
|
-
console.info(
|
|
11011
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10841
11012
|
conversationId,
|
|
10842
11013
|
reason: "no_intents_configured"
|
|
10843
11014
|
});
|
|
10844
11015
|
} else if (!emailPlugin2) {
|
|
10845
|
-
console.info(
|
|
11016
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10846
11017
|
conversationId,
|
|
10847
11018
|
reason: "email_plugin_missing"
|
|
10848
11019
|
});
|
|
10849
11020
|
} else if (!chatAgentFn) {
|
|
10850
|
-
console.info(
|
|
11021
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10851
11022
|
conversationId,
|
|
10852
11023
|
reason: "llm_chat_agent_unavailable"
|
|
10853
11024
|
});
|
|
10854
11025
|
} else if (convLeadSent) {
|
|
10855
|
-
console.info(
|
|
11026
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10856
11027
|
conversationId,
|
|
10857
11028
|
reason: "lead_email_already_sent",
|
|
10858
11029
|
leadEmailSentAt: convLeadSent
|
|
@@ -10865,7 +11036,7 @@ function createChatHandlers(config) {
|
|
|
10865
11036
|
}
|
|
10866
11037
|
});
|
|
10867
11038
|
if (!contactRow) {
|
|
10868
|
-
console.warn(
|
|
11039
|
+
console.warn(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline skipped", {
|
|
10869
11040
|
conversationId,
|
|
10870
11041
|
reason: "contact_not_found",
|
|
10871
11042
|
contactId
|
|
@@ -10873,7 +11044,7 @@ function createChatHandlers(config) {
|
|
|
10873
11044
|
} else {
|
|
10874
11045
|
const c = contactRow;
|
|
10875
11046
|
try {
|
|
10876
|
-
const intent = await
|
|
11047
|
+
const intent = await chunkTCSGFAWB_cjs.detectChatLeadIntent({
|
|
10877
11048
|
chatAgent: chatAgentFn
|
|
10878
11049
|
}, {
|
|
10879
11050
|
settings: emailTool,
|
|
@@ -10887,15 +11058,15 @@ function createChatHandlers(config) {
|
|
|
10887
11058
|
model: agentRow?.model?.trim() || notifyEmailAgent?.model?.trim() || void 0
|
|
10888
11059
|
});
|
|
10889
11060
|
if (!intent.intent || !intent.emailTo) {
|
|
10890
|
-
console.info(
|
|
11061
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "no email sent", {
|
|
10891
11062
|
conversationId,
|
|
10892
11063
|
reason: intent.intent ? "missing_email_to" : "no_intent_match",
|
|
10893
11064
|
intentLabel: intent.intentLabel,
|
|
10894
11065
|
classifierReason: intent.reason
|
|
10895
11066
|
});
|
|
10896
11067
|
} else {
|
|
10897
|
-
const intentRecipients =
|
|
10898
|
-
console.info(
|
|
11068
|
+
const intentRecipients = chunkTCSGFAWB_cjs.parseIntentRecipientEmails(intent.emailTo);
|
|
11069
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "intent matched \u2014 sending", {
|
|
10899
11070
|
conversationId,
|
|
10900
11071
|
intent: intent.intent,
|
|
10901
11072
|
emailTo: intent.emailTo,
|
|
@@ -10904,8 +11075,8 @@ function createChatHandlers(config) {
|
|
|
10904
11075
|
});
|
|
10905
11076
|
const emailSettings = await loadSettingsGroupMap(dataSource, entityMap, "email");
|
|
10906
11077
|
const brandingSettings = await loadSettingsGroupMap(dataSource, entityMap, "branding");
|
|
10907
|
-
const companyDetails =
|
|
10908
|
-
const leadResult = await
|
|
11078
|
+
const companyDetails = chunkBXYZDMTZ_cjs.mergeEmailLayoutCompanyDetails(brandingSettings, emailSettings);
|
|
11079
|
+
const leadResult = await chunkTCSGFAWB_cjs.sendChatLeadEmail(cms, emailSettings, brandingSettings, {
|
|
10909
11080
|
contactName: String(c.name ?? "").trim() || "Visitor",
|
|
10910
11081
|
contactEmail: String(c.email ?? "").trim(),
|
|
10911
11082
|
contactPhone: c.phone ?? null,
|
|
@@ -10913,7 +11084,7 @@ function createChatHandlers(config) {
|
|
|
10913
11084
|
latestMessage: message,
|
|
10914
11085
|
intentCode: intent.intent,
|
|
10915
11086
|
intentReason: intent.intentLabel || intent.reason,
|
|
10916
|
-
transcript:
|
|
11087
|
+
transcript: chunkTCSGFAWB_cjs.buildTranscriptForLeadEmail(history, message),
|
|
10917
11088
|
companyDetails,
|
|
10918
11089
|
recipients: intentRecipients.length > 0 ? intentRecipients : void 0
|
|
10919
11090
|
});
|
|
@@ -10921,13 +11092,13 @@ function createChatHandlers(config) {
|
|
|
10921
11092
|
await convRepo().update(conversationId, {
|
|
10922
11093
|
leadEmailSentAt: /* @__PURE__ */ new Date()
|
|
10923
11094
|
});
|
|
10924
|
-
console.info(
|
|
11095
|
+
console.info(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "lead email recorded", {
|
|
10925
11096
|
conversationId,
|
|
10926
11097
|
sent: true,
|
|
10927
11098
|
recipients: leadResult.recipients
|
|
10928
11099
|
});
|
|
10929
11100
|
} else {
|
|
10930
|
-
console.warn(
|
|
11101
|
+
console.warn(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "lead email not sent", {
|
|
10931
11102
|
conversationId,
|
|
10932
11103
|
sent: false,
|
|
10933
11104
|
error: leadResult.error ?? "unknown",
|
|
@@ -10936,7 +11107,7 @@ function createChatHandlers(config) {
|
|
|
10936
11107
|
}
|
|
10937
11108
|
}
|
|
10938
11109
|
} catch (intentErr) {
|
|
10939
|
-
console.warn(
|
|
11110
|
+
console.warn(chunkTCSGFAWB_cjs.CHAT_EMAIL_LOG, "pipeline error", {
|
|
10940
11111
|
conversationId,
|
|
10941
11112
|
error: intentErr instanceof Error ? intentErr.message : String(intentErr)
|
|
10942
11113
|
});
|
|
@@ -10953,7 +11124,7 @@ function createChatHandlers(config) {
|
|
|
10953
11124
|
});
|
|
10954
11125
|
if (agentRow && llm.chatAgent) {
|
|
10955
11126
|
const fromAgent = llmAgentToChatAgentOptions(agentRow);
|
|
10956
|
-
const systemPrompt =
|
|
11127
|
+
const systemPrompt = chunkTCSGFAWB_cjs.buildChatbotSystemPromptWithEmailTool(fromAgent.systemPrompt, parsedValidation.guardrailsForPrompt, emailTool);
|
|
10957
11128
|
const res = await llm.chatAgent({
|
|
10958
11129
|
...fromAgent,
|
|
10959
11130
|
systemPrompt: systemPrompt || void 0,
|
|
@@ -10974,7 +11145,7 @@ ${contextParts.join("\n\n")}` : "";
|
|
|
10974
11145
|
agentRow.systemInstruction?.trim(),
|
|
10975
11146
|
ragSystem
|
|
10976
11147
|
].filter(Boolean).join("\n\n");
|
|
10977
|
-
systemContent =
|
|
11148
|
+
systemContent = chunkTCSGFAWB_cjs.buildChatbotSystemPromptWithEmailTool(mergedBase || defaultSystem, parsedValidation.guardrailsForPrompt, emailTool) || defaultSystem;
|
|
10978
11149
|
} else {
|
|
10979
11150
|
systemContent = ragSystem || defaultSystem;
|
|
10980
11151
|
}
|
|
@@ -12400,7 +12571,7 @@ function createAdminRolesHandlers(config) {
|
|
|
12400
12571
|
}, {
|
|
12401
12572
|
status: 401
|
|
12402
12573
|
});
|
|
12403
|
-
if (!
|
|
12574
|
+
if (!chunkNBY4NVTY_cjs.canManageRoles(u) && !chunkX6UQFV4X_cjs.canManageVendorRoles(u)) {
|
|
12404
12575
|
return json({
|
|
12405
12576
|
error: "Forbidden"
|
|
12406
12577
|
}, {
|
|
@@ -12411,7 +12582,7 @@ function createAdminRolesHandlers(config) {
|
|
|
12411
12582
|
}
|
|
12412
12583
|
chunkUSNT2KNT_cjs.__name(gate, "gate");
|
|
12413
12584
|
function isVendorRolesOnly(u) {
|
|
12414
|
-
return chunkX6UQFV4X_cjs.canManageVendorRoles(u) && !
|
|
12585
|
+
return chunkX6UQFV4X_cjs.canManageVendorRoles(u) && !chunkNBY4NVTY_cjs.canManageRoles(u);
|
|
12415
12586
|
}
|
|
12416
12587
|
chunkUSNT2KNT_cjs.__name(isVendorRolesOnly, "isVendorRolesOnly");
|
|
12417
12588
|
const vendorRoleEntities = [
|
|
@@ -12768,12 +12939,12 @@ async function sendVendorOnboardEmails(input, deps) {
|
|
|
12768
12939
|
getSettingsGroup(deps, "branding"),
|
|
12769
12940
|
getSettingsGroup(deps, "email")
|
|
12770
12941
|
]);
|
|
12771
|
-
const companyDetails =
|
|
12772
|
-
const notifyEmails =
|
|
12942
|
+
const companyDetails = chunkBXYZDMTZ_cjs.mergeEmailLayoutCompanyDetails(branding, emailSettings);
|
|
12943
|
+
const notifyEmails = chunkTCSGFAWB_cjs.parseEmailRecipientsFromConfig(emailSettings.salesTeamEmails ?? emailSettings.salesTeamEmail);
|
|
12773
12944
|
const sendToOwner = input.sendToOwner !== false;
|
|
12774
12945
|
const ownerEmail = input.ownerEmail?.trim() || "";
|
|
12775
12946
|
const cms = await deps.getCms();
|
|
12776
|
-
await
|
|
12947
|
+
await chunkV25RDUOU_cjs.queueVendorOnboardEmails(cms, {
|
|
12777
12948
|
vendorName: input.vendorName,
|
|
12778
12949
|
vendorSlug: input.vendorSlug,
|
|
12779
12950
|
ownerName: input.ownerName,
|
|
@@ -13352,7 +13523,7 @@ function createVendorOnboardHandlers(config) {
|
|
|
13352
13523
|
}
|
|
13353
13524
|
});
|
|
13354
13525
|
if (dupVendor) throw new Error("VENDOR_SLUG_EXISTS");
|
|
13355
|
-
await retireSoftDeletedUniqueValue(vendorRepo, "slug", slug);
|
|
13526
|
+
await chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue(vendorRepo, "slug", slug);
|
|
13356
13527
|
let ownerGroup = await groupRepo.findOne({
|
|
13357
13528
|
where: {
|
|
13358
13529
|
name: chunkX6UQFV4X_cjs.VENDOR_OWNER_GROUP_NAME,
|
|
@@ -14756,6 +14927,13 @@ exports.User = class User {
|
|
|
14756
14927
|
phoneVerifiedAt;
|
|
14757
14928
|
emailVerifiedAt;
|
|
14758
14929
|
password;
|
|
14930
|
+
/**
|
|
14931
|
+
* `pending` = invite outstanding (cannot sign in until password is set).
|
|
14932
|
+
* `active` = invite accepted / account usable (subject to `blocked`).
|
|
14933
|
+
*/
|
|
14934
|
+
inviteStatus;
|
|
14935
|
+
/** Rotating invite token; null when active or no invite outstanding. */
|
|
14936
|
+
inviteToken;
|
|
14759
14937
|
blocked;
|
|
14760
14938
|
adminAccess;
|
|
14761
14939
|
groupId;
|
|
@@ -14808,6 +14986,24 @@ _ts_decorate4([
|
|
|
14808
14986
|
}),
|
|
14809
14987
|
_ts_metadata4("design:type", Object)
|
|
14810
14988
|
], exports.User.prototype, "password", void 0);
|
|
14989
|
+
_ts_decorate4([
|
|
14990
|
+
typeorm.Column({
|
|
14991
|
+
type: "enum",
|
|
14992
|
+
enum: [
|
|
14993
|
+
"pending",
|
|
14994
|
+
"active"
|
|
14995
|
+
],
|
|
14996
|
+
enumName: "users_invitestatus_enum",
|
|
14997
|
+
default: "active"
|
|
14998
|
+
}),
|
|
14999
|
+
_ts_metadata4("design:type", typeof UserInviteStatus === "undefined" ? Object : UserInviteStatus)
|
|
15000
|
+
], exports.User.prototype, "inviteStatus", void 0);
|
|
15001
|
+
_ts_decorate4([
|
|
15002
|
+
typeorm.Column("varchar", {
|
|
15003
|
+
nullable: true
|
|
15004
|
+
}),
|
|
15005
|
+
_ts_metadata4("design:type", Object)
|
|
15006
|
+
], exports.User.prototype, "inviteToken", void 0);
|
|
14811
15007
|
_ts_decorate4([
|
|
14812
15008
|
typeorm.Column("boolean", {
|
|
14813
15009
|
default: false
|
|
@@ -19541,6 +19737,8 @@ exports.OrderItem = class OrderItem {
|
|
|
19541
19737
|
id;
|
|
19542
19738
|
orderId;
|
|
19543
19739
|
productId;
|
|
19740
|
+
/** Selected product variant at order time (optional). */
|
|
19741
|
+
variantId;
|
|
19544
19742
|
discountIds;
|
|
19545
19743
|
vendorId;
|
|
19546
19744
|
vendor;
|
|
@@ -19576,6 +19774,12 @@ _ts_decorate39([
|
|
|
19576
19774
|
typeorm.Column("int"),
|
|
19577
19775
|
_ts_metadata39("design:type", Number)
|
|
19578
19776
|
], exports.OrderItem.prototype, "productId", void 0);
|
|
19777
|
+
_ts_decorate39([
|
|
19778
|
+
typeorm.Column("int", {
|
|
19779
|
+
nullable: true
|
|
19780
|
+
}),
|
|
19781
|
+
_ts_metadata39("design:type", Object)
|
|
19782
|
+
], exports.OrderItem.prototype, "variantId", void 0);
|
|
19579
19783
|
_ts_decorate39([
|
|
19580
19784
|
typeorm.Column({
|
|
19581
19785
|
type: "int",
|
|
@@ -20385,6 +20589,7 @@ var Type = /* @__PURE__ */ (function(Type2) {
|
|
|
20385
20589
|
Type2["CATEGORY"] = "category";
|
|
20386
20590
|
Type2["CART"] = "cart";
|
|
20387
20591
|
Type2["PAYMENT_METHOD"] = "paymentMethod";
|
|
20592
|
+
Type2["DEVICE_TYPE"] = "deviceType";
|
|
20388
20593
|
Type2["ORDER"] = "order";
|
|
20389
20594
|
Type2["QUANTITY"] = "quantity";
|
|
20390
20595
|
Type2["TIME"] = "time";
|
|
@@ -22407,6 +22612,7 @@ exports.Combo = class Combo {
|
|
|
22407
22612
|
vendorId;
|
|
22408
22613
|
vendor;
|
|
22409
22614
|
name;
|
|
22615
|
+
slug;
|
|
22410
22616
|
desc;
|
|
22411
22617
|
eventId;
|
|
22412
22618
|
event;
|
|
@@ -22450,6 +22656,12 @@ _ts_decorate63([
|
|
|
22450
22656
|
}),
|
|
22451
22657
|
_ts_metadata63("design:type", String)
|
|
22452
22658
|
], exports.Combo.prototype, "name", void 0);
|
|
22659
|
+
_ts_decorate63([
|
|
22660
|
+
typeorm.Column({
|
|
22661
|
+
type: "varchar"
|
|
22662
|
+
}),
|
|
22663
|
+
_ts_metadata63("design:type", String)
|
|
22664
|
+
], exports.Combo.prototype, "slug", void 0);
|
|
22453
22665
|
_ts_decorate63([
|
|
22454
22666
|
typeorm.Column({
|
|
22455
22667
|
type: "text",
|
|
@@ -22587,7 +22799,11 @@ _ts_decorate63([
|
|
|
22587
22799
|
_ts_metadata63("design:type", Number)
|
|
22588
22800
|
], exports.Combo.prototype, "deletedBy", void 0);
|
|
22589
22801
|
exports.Combo = _ts_decorate63([
|
|
22590
|
-
typeorm.Entity("combos")
|
|
22802
|
+
typeorm.Entity("combos"),
|
|
22803
|
+
typeorm.Unique("UQ_combos_vendor_slug", [
|
|
22804
|
+
"vendorId",
|
|
22805
|
+
"slug"
|
|
22806
|
+
])
|
|
22591
22807
|
], exports.Combo);
|
|
22592
22808
|
function _ts_decorate64(decorators, target, key, desc) {
|
|
22593
22809
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -26432,16 +26648,16 @@ function whatsappPlugin(config = {}) {
|
|
|
26432
26648
|
db = await getWhatsAppSettings?.() ?? {};
|
|
26433
26649
|
} catch {
|
|
26434
26650
|
}
|
|
26435
|
-
if (!
|
|
26651
|
+
if (!chunk7PMHZRF3_cjs.isWhatsAppPluginEnabled(db)) {
|
|
26436
26652
|
context.logger.warn("WhatsApp plugin skipped: disabled in Plugins \u2192 WhatsApp");
|
|
26437
26653
|
return null;
|
|
26438
26654
|
}
|
|
26439
|
-
const merged =
|
|
26440
|
-
if (!getWhatsAppSettings && !
|
|
26655
|
+
const merged = chunk7PMHZRF3_cjs.mergeWhatsAppConfigLayers(env, db, staticRest);
|
|
26656
|
+
if (!getWhatsAppSettings && !chunk7PMHZRF3_cjs.whatsAppConfigured(merged)) {
|
|
26441
26657
|
context.logger.warn("WhatsApp plugin skipped: set WHATSAPP_ACCESS_TOKEN and WHATSAPP_PHONE_NUMBER_ID, or pass getWhatsAppSettings");
|
|
26442
26658
|
return null;
|
|
26443
26659
|
}
|
|
26444
|
-
const svc = new
|
|
26660
|
+
const svc = new chunk7PMHZRF3_cjs.WhatsAppService(env, staticRest, getWhatsAppSettings, getMessageTemplateRow);
|
|
26445
26661
|
return {
|
|
26446
26662
|
send: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name((opts) => svc.send(opts), "send")
|
|
26447
26663
|
};
|
|
@@ -26513,9 +26729,12 @@ function createMessageTemplateRowLoader(dataSource, entityMap) {
|
|
|
26513
26729
|
};
|
|
26514
26730
|
}
|
|
26515
26731
|
chunkUSNT2KNT_cjs.__name(createMessageTemplateRowLoader, "createMessageTemplateRowLoader");
|
|
26516
|
-
function registerMessagingQueueProcessors(cms) {
|
|
26517
|
-
|
|
26518
|
-
|
|
26732
|
+
function registerMessagingQueueProcessors(cms, entityMap) {
|
|
26733
|
+
chunkV25RDUOU_cjs.registerEmailQueueProcessor(cms, {
|
|
26734
|
+
getDataSource: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => cms.dataSource, "getDataSource"),
|
|
26735
|
+
entityMap
|
|
26736
|
+
});
|
|
26737
|
+
chunk7PMHZRF3_cjs.registerWhatsAppQueueProcessor(cms);
|
|
26519
26738
|
}
|
|
26520
26739
|
chunkUSNT2KNT_cjs.__name(registerMessagingQueueProcessors, "registerMessagingQueueProcessors");
|
|
26521
26740
|
async function ensureMessagingPluginsOnCms(base, options) {
|
|
@@ -26544,7 +26763,7 @@ async function ensureMessagingPluginsOnCms(base, options) {
|
|
|
26544
26763
|
}
|
|
26545
26764
|
if (!cms.getPlugin("email")) {
|
|
26546
26765
|
try {
|
|
26547
|
-
const instance = await
|
|
26766
|
+
const instance = await chunkTCSGFAWB_cjs.emailPlugin({
|
|
26548
26767
|
type: "SMTP",
|
|
26549
26768
|
from: config.SMTP_FROM ?? "no-reply@localhost",
|
|
26550
26769
|
to: config.SMTP_TO ?? ""
|
|
@@ -26566,7 +26785,7 @@ async function ensureMessagingPluginsOnCms(base, options) {
|
|
|
26566
26785
|
}
|
|
26567
26786
|
}
|
|
26568
26787
|
const merged = Object.keys(overlay).length > 0 ? overlayCmsPlugins(cms, overlay) : cms;
|
|
26569
|
-
registerMessagingQueueProcessors(merged);
|
|
26788
|
+
registerMessagingQueueProcessors(merged, entityMap);
|
|
26570
26789
|
return merged;
|
|
26571
26790
|
}
|
|
26572
26791
|
chunkUSNT2KNT_cjs.__name(ensureMessagingPluginsOnCms, "ensureMessagingPluginsOnCms");
|
|
@@ -26585,7 +26804,7 @@ function messagingPlugins(options) {
|
|
|
26585
26804
|
const config = options.config ?? (typeof process !== "undefined" ? process.env : {});
|
|
26586
26805
|
return [
|
|
26587
26806
|
queuePlugin(),
|
|
26588
|
-
|
|
26807
|
+
chunkTCSGFAWB_cjs.emailPlugin({
|
|
26589
26808
|
type: "SMTP",
|
|
26590
26809
|
from: config.SMTP_FROM ?? "no-reply@localhost",
|
|
26591
26810
|
to: config.SMTP_TO ?? ""
|
|
@@ -26615,7 +26834,7 @@ async function createCmsAppWithMessaging(options) {
|
|
|
26615
26834
|
logger,
|
|
26616
26835
|
plugins: mergedPlugins
|
|
26617
26836
|
});
|
|
26618
|
-
registerMessagingQueueProcessors(cms);
|
|
26837
|
+
registerMessagingQueueProcessors(cms, entityMap);
|
|
26619
26838
|
return cms;
|
|
26620
26839
|
}
|
|
26621
26840
|
chunkUSNT2KNT_cjs.__name(createCmsAppWithMessaging, "createCmsAppWithMessaging");
|
|
@@ -26719,7 +26938,7 @@ function createCmsApiHandler(config) {
|
|
|
26719
26938
|
} : void 0;
|
|
26720
26939
|
const entityMap = withLlmKnowledgeEntityFallbacks(rawEntityMap);
|
|
26721
26940
|
if (getCms) {
|
|
26722
|
-
|
|
26941
|
+
chunk7PMHZRF3_cjs.initWhatsappTriggerDispatcher({
|
|
26723
26942
|
dataSource,
|
|
26724
26943
|
entityMap,
|
|
26725
26944
|
getCms
|
|
@@ -26752,7 +26971,7 @@ function createCmsApiHandler(config) {
|
|
|
26752
26971
|
status: 401
|
|
26753
26972
|
});
|
|
26754
26973
|
}
|
|
26755
|
-
const allowed =
|
|
26974
|
+
const allowed = chunkNBY4NVTY_cjs.sessionHasEntityAccess(u, entity, action);
|
|
26756
26975
|
await chunkX6UQFV4X_cjs.logEntityAccessDecision(dataSource, "cmsApi.requireEntityPermission", u, entity, action, {
|
|
26757
26976
|
allowed,
|
|
26758
26977
|
resolvePath: "hydrated_session"
|
|
@@ -26812,7 +27031,7 @@ function createCmsApiHandler(config) {
|
|
|
26812
27031
|
companyDetails
|
|
26813
27032
|
};
|
|
26814
27033
|
if (queue) {
|
|
26815
|
-
const { queueEmail: queueEmail2 } = await import('./email-queue-
|
|
27034
|
+
const { queueEmail: queueEmail2 } = await import('./email-queue-6NJY6HNM.cjs');
|
|
26816
27035
|
await queueEmail2(cms, {
|
|
26817
27036
|
to: opts.to,
|
|
26818
27037
|
templateName: "passwordReset",
|
|
@@ -28066,14 +28285,27 @@ function createCmsApiHandler(config) {
|
|
|
28066
28285
|
const pe = await requireEntityPermissionEffective(req, "orders", "read");
|
|
28067
28286
|
if (pe) return pe;
|
|
28068
28287
|
const cms = await getCms();
|
|
28069
|
-
const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-
|
|
28288
|
+
const { streamOrderInvoicePdf: streamOrderInvoicePdf2 } = await import('./erp-order-invoice-EYYNR526.cjs');
|
|
28070
28289
|
const oid = Number(path2[1]);
|
|
28071
28290
|
if (!Number.isFinite(oid)) return config.json({
|
|
28072
28291
|
error: "Invalid id"
|
|
28073
28292
|
}, {
|
|
28074
28293
|
status: 400
|
|
28075
28294
|
});
|
|
28076
|
-
|
|
28295
|
+
try {
|
|
28296
|
+
return await streamOrderInvoicePdf2(cms, dataSource, entityMap, oid, {});
|
|
28297
|
+
} catch (err) {
|
|
28298
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
28299
|
+
console.error("[invoice] route failed", {
|
|
28300
|
+
orderId: oid,
|
|
28301
|
+
error: msg
|
|
28302
|
+
});
|
|
28303
|
+
return config.json({
|
|
28304
|
+
error: `Invoice failed: ${msg}`
|
|
28305
|
+
}, {
|
|
28306
|
+
status: 500
|
|
28307
|
+
});
|
|
28308
|
+
}
|
|
28077
28309
|
}
|
|
28078
28310
|
if (path2[0] === "orders" && path2.length === 3 && path2[2] === "repost-erp" && getCms) {
|
|
28079
28311
|
const a = await config.requireAuth(req);
|
|
@@ -28420,7 +28652,7 @@ function createCmsApiHandler(config) {
|
|
|
28420
28652
|
status: 400
|
|
28421
28653
|
});
|
|
28422
28654
|
}
|
|
28423
|
-
const { resendOrderNotification } = await import('./order-notification-dispatcher-
|
|
28655
|
+
const { resendOrderNotification } = await import('./order-notification-dispatcher-SBQAMM5V.cjs');
|
|
28424
28656
|
const result = await resendOrderNotification(triggerKey, orderId, {
|
|
28425
28657
|
dataSource,
|
|
28426
28658
|
entityMap,
|
|
@@ -28492,6 +28724,30 @@ function createCmsApiHandler(config) {
|
|
|
28492
28724
|
paymentId = Number(payment.id);
|
|
28493
28725
|
}
|
|
28494
28726
|
}
|
|
28727
|
+
const orderWithItems = await orderRepo.findOne({
|
|
28728
|
+
where: {
|
|
28729
|
+
id: orderId,
|
|
28730
|
+
deleted: false
|
|
28731
|
+
},
|
|
28732
|
+
relations: [
|
|
28733
|
+
"items"
|
|
28734
|
+
]
|
|
28735
|
+
});
|
|
28736
|
+
if (orderWithItems) {
|
|
28737
|
+
const { reconcileOrderInventoryBetweenSnapshots: reconcileOrderInventoryBetweenSnapshots2, orderInventorySnapshotFromRow: orderInventorySnapshotFromRow2 } = await import('./order-inventory-2MYRKEPC.cjs');
|
|
28738
|
+
const prevSnap = orderInventorySnapshotFromRow2(orderWithItems);
|
|
28739
|
+
const invErr = await reconcileOrderInventoryBetweenSnapshots2(dataSource, entityMap, prevSnap, {
|
|
28740
|
+
status: "cancelled",
|
|
28741
|
+
lines: prevSnap.lines
|
|
28742
|
+
});
|
|
28743
|
+
if (invErr) {
|
|
28744
|
+
return config.json({
|
|
28745
|
+
error: invErr
|
|
28746
|
+
}, {
|
|
28747
|
+
status: 400
|
|
28748
|
+
});
|
|
28749
|
+
}
|
|
28750
|
+
}
|
|
28495
28751
|
await orderRepo.update(orderId, {
|
|
28496
28752
|
status: "cancelled"
|
|
28497
28753
|
});
|
|
@@ -29151,12 +29407,12 @@ async function refreshOrderFromErp(cms, dataSource, entityMap, submission, order
|
|
|
29151
29407
|
const r1 = await submission.postErpReadAction("get-order-status", {
|
|
29152
29408
|
platformOrderId: refId
|
|
29153
29409
|
});
|
|
29154
|
-
const d1 = r1.ok ?
|
|
29410
|
+
const d1 = r1.ok ? chunkBXYZDMTZ_cjs.unwrapErpReadData(r1.json) : null;
|
|
29155
29411
|
if (d1) {
|
|
29156
29412
|
const mapped = mapErpSaleStatusToOrderStatus(typeof d1.status === "string" ? d1.status : typeof d1.orderStatus === "string" ? d1.orderStatus : typeof d1.state === "string" ? d1.state : void 0);
|
|
29157
29413
|
if (mapped) newStatus = mapped;
|
|
29158
|
-
fulfillment =
|
|
29159
|
-
const refs =
|
|
29414
|
+
fulfillment = chunkBXYZDMTZ_cjs.mapErpPayloadToFulfillment(d1);
|
|
29415
|
+
const refs = chunkBXYZDMTZ_cjs.extractChildOrderRefsFromSalePayload(d1);
|
|
29160
29416
|
if (refs.length) {
|
|
29161
29417
|
await ensureChildOrdersFromRefs(orderRepo, order, refs, order.contactId, String(order.currency || "INR"));
|
|
29162
29418
|
}
|
|
@@ -29164,16 +29420,16 @@ async function refreshOrderFromErp(cms, dataSource, entityMap, submission, order
|
|
|
29164
29420
|
const r2 = await submission.postErpReadAction("get-fulfillment-status", {
|
|
29165
29421
|
platformOrderId: refId
|
|
29166
29422
|
});
|
|
29167
|
-
const d2 = r2.ok ?
|
|
29423
|
+
const d2 = r2.ok ? chunkBXYZDMTZ_cjs.unwrapErpReadData(r2.json) : null;
|
|
29168
29424
|
if (d2) {
|
|
29169
|
-
fulfillment = deepMergeFulfillment(fulfillment,
|
|
29425
|
+
fulfillment = deepMergeFulfillment(fulfillment, chunkBXYZDMTZ_cjs.mapErpPayloadToFulfillment(d2));
|
|
29170
29426
|
}
|
|
29171
29427
|
const r3 = await submission.postErpReadAction("get-invoice", {
|
|
29172
29428
|
platformOrderId: refId
|
|
29173
29429
|
});
|
|
29174
|
-
const d3 = r3.ok ?
|
|
29430
|
+
const d3 = r3.ok ? chunkBXYZDMTZ_cjs.unwrapErpReadData(r3.json) : null;
|
|
29175
29431
|
if (d3) {
|
|
29176
|
-
invoiceNumber =
|
|
29432
|
+
invoiceNumber = chunkBXYZDMTZ_cjs.mapErpPayloadToInvoiceNumber(d3);
|
|
29177
29433
|
invoiceId = pickInvoiceId(d3);
|
|
29178
29434
|
}
|
|
29179
29435
|
const oid = order.id;
|
|
@@ -29209,10 +29465,10 @@ async function refreshOrderFromErp(cms, dataSource, entityMap, submission, order
|
|
|
29209
29465
|
const r = await submission.postErpReadAction("get-return-status", {
|
|
29210
29466
|
platformReturnId
|
|
29211
29467
|
});
|
|
29212
|
-
const d = r.ok ?
|
|
29468
|
+
const d = r.ok ? chunkBXYZDMTZ_cjs.unwrapErpReadData(r.json) : null;
|
|
29213
29469
|
if (!d) return;
|
|
29214
29470
|
const mapped = mapErpSaleStatusToOrderStatus(typeof d.status === "string" ? d.status : typeof d.returnStatus === "string" ? d.returnStatus : void 0);
|
|
29215
|
-
const fulfillment =
|
|
29471
|
+
const fulfillment = chunkBXYZDMTZ_cjs.mapErpPayloadToFulfillment(d);
|
|
29216
29472
|
const patch = {};
|
|
29217
29473
|
if (fulfillment !== void 0) patch.fulfillment = fulfillment;
|
|
29218
29474
|
const nextMeta = Object.keys(patch).length ? mergeOrderMetadataPatch(meta, patch) : meta;
|
|
@@ -29535,6 +29791,14 @@ function createStorefrontApiHandler(config) {
|
|
|
29535
29791
|
entityMap
|
|
29536
29792
|
});
|
|
29537
29793
|
}).catch((err) => console.error("[notification-triggers] import failed", err));
|
|
29794
|
+
if (!getCms) return;
|
|
29795
|
+
void import('./send-order-placed-emails-B5ZVJT7T.cjs').then(({ sendOrderPlacedEmailsAfterConfirmation }) => {
|
|
29796
|
+
return sendOrderPlacedEmailsAfterConfirmation(orderId, {
|
|
29797
|
+
getDataSource: /* @__PURE__ */ chunkUSNT2KNT_cjs.__name(async () => dataSource, "getDataSource"),
|
|
29798
|
+
entityMap,
|
|
29799
|
+
getCms
|
|
29800
|
+
});
|
|
29801
|
+
}).catch((err) => console.error("[order-emails] sendOrderPlacedEmailsAfterConfirmation failed", err));
|
|
29538
29802
|
}
|
|
29539
29803
|
chunkUSNT2KNT_cjs.__name(fireOrderPlacedNotification, "fireOrderPlacedNotification");
|
|
29540
29804
|
const otpAllowPhoneLogin = config.otpAllowPhoneLogin !== false;
|
|
@@ -31136,7 +31400,7 @@ function createStorefrontApiHandler(config) {
|
|
|
31136
31400
|
status: 503
|
|
31137
31401
|
});
|
|
31138
31402
|
const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};
|
|
31139
|
-
await
|
|
31403
|
+
await chunkV25RDUOU_cjs.queueEmail(cms, {
|
|
31140
31404
|
to: identifier,
|
|
31141
31405
|
templateName: "otp",
|
|
31142
31406
|
ctx: {
|
|
@@ -31303,9 +31567,12 @@ function createStorefrontApiHandler(config) {
|
|
|
31303
31567
|
}, {
|
|
31304
31568
|
status: 400
|
|
31305
31569
|
});
|
|
31570
|
+
const { retireSoftDeletedUniqueValue: retireSoftDeletedUniqueValue2 } = await import('./retire-soft-deleted-unique-5VXBA5XX.cjs');
|
|
31571
|
+
await retireSoftDeletedUniqueValue2(userRepo(), "email", email);
|
|
31306
31572
|
const existing = await userRepo().findOne({
|
|
31307
31573
|
where: {
|
|
31308
|
-
email
|
|
31574
|
+
email,
|
|
31575
|
+
deleted: false
|
|
31309
31576
|
}
|
|
31310
31577
|
});
|
|
31311
31578
|
if (existing) return json({
|
|
@@ -31358,7 +31625,7 @@ function createStorefrontApiHandler(config) {
|
|
|
31358
31625
|
const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};
|
|
31359
31626
|
const base = (publicSiteUrl || "").replace(/\/$/, "").trim() || "http://localhost:3000";
|
|
31360
31627
|
const verifyEmailUrl = `${base}/verify-email?token=${encodeURIComponent(rawToken)}`;
|
|
31361
|
-
await
|
|
31628
|
+
await chunkV25RDUOU_cjs.queueEmail(cms, {
|
|
31362
31629
|
to: email,
|
|
31363
31630
|
templateName: "signup",
|
|
31364
31631
|
ctx: {
|
|
@@ -32116,7 +32383,7 @@ function createStorefrontApiHandler(config) {
|
|
|
32116
32383
|
status: 400
|
|
32117
32384
|
});
|
|
32118
32385
|
const cms = await getCms();
|
|
32119
|
-
return
|
|
32386
|
+
return chunkBXYZDMTZ_cjs.streamOrderInvoicePdf(cms, dataSource, entityMap, orderId, {
|
|
32120
32387
|
ownerContactId: contact.id
|
|
32121
32388
|
});
|
|
32122
32389
|
}
|
|
@@ -32186,6 +32453,7 @@ function createStorefrontApiHandler(config) {
|
|
|
32186
32453
|
unitPrice: line.unitPrice,
|
|
32187
32454
|
tax: line.tax,
|
|
32188
32455
|
total: line.total,
|
|
32456
|
+
metadata: line.metadata ?? null,
|
|
32189
32457
|
product: p ? {
|
|
32190
32458
|
name: p.name,
|
|
32191
32459
|
slug: p.slug,
|
|
@@ -32278,12 +32546,17 @@ exports.assertProductApprovalUpdate = assertProductApprovalUpdate;
|
|
|
32278
32546
|
exports.buildBlogMetadataUserPrompt = buildBlogMetadataUserPrompt;
|
|
32279
32547
|
exports.buildCronFromSchedule = buildCronFromSchedule;
|
|
32280
32548
|
exports.buildRssUserPromptFromFeeds = buildRssUserPromptFromFeeds;
|
|
32549
|
+
exports.buildUserInviteLink = buildUserInviteLink;
|
|
32281
32550
|
exports.buildVendorInviteLink = buildVendorInviteLink;
|
|
32282
32551
|
exports.calculateOrderRefundPreview = calculateOrderRefundPreview;
|
|
32283
32552
|
exports.calculateRefundFromPolicy = calculateRefundFromPolicy;
|
|
32553
|
+
exports.checkAndIncrementDiscountUsage = checkAndIncrementDiscountUsage;
|
|
32284
32554
|
exports.checkEventsEnabled = checkEventsEnabled;
|
|
32285
32555
|
exports.checkMultiVendorEnabled = checkMultiVendorEnabled;
|
|
32556
|
+
exports.completeUserInviteAccept = completeUserInviteAccept;
|
|
32557
|
+
exports.consumeAppliedDiscountUsages = consumeAppliedDiscountUsages;
|
|
32286
32558
|
exports.contactIsVendorCustomer = contactIsVendorCustomer;
|
|
32559
|
+
exports.countDiscountOrdersForContact = countDiscountOrdersForContact;
|
|
32287
32560
|
exports.countRecentOtpSends = countRecentOtpSends;
|
|
32288
32561
|
exports.createAnalyticsHandlers = createAnalyticsHandlers;
|
|
32289
32562
|
exports.createBlogBySlugHandler = createBlogBySlugHandler;
|
|
@@ -32318,6 +32591,7 @@ exports.createVendorOnboardHandlers = createVendorOnboardHandlers;
|
|
|
32318
32591
|
exports.customerPhoneForEmail = customerPhoneForEmail;
|
|
32319
32592
|
exports.customerPhoneForUser = customerPhoneForUser;
|
|
32320
32593
|
exports.daysBeforeEventStart = daysBeforeEventStart;
|
|
32594
|
+
exports.decrementDiscountUsage = decrementDiscountUsage;
|
|
32321
32595
|
exports.describeEventTierPolicy = describeEventTierPolicy;
|
|
32322
32596
|
exports.ensureCustomerForUser = ensureCustomerForUser;
|
|
32323
32597
|
exports.ensureCustomerRecord = ensureCustomerRecord;
|
|
@@ -32326,6 +32600,7 @@ exports.ensureScheduleQueueWorker = ensureScheduleQueueWorker;
|
|
|
32326
32600
|
exports.ensureVendorCustomerForOrderContact = ensureVendorCustomerForOrderContact;
|
|
32327
32601
|
exports.ensureVendorCustomersForOrder = ensureVendorCustomersForOrder;
|
|
32328
32602
|
exports.findActiveRefundPolicyForVendor = findActiveRefundPolicyForVendor;
|
|
32603
|
+
exports.findUserByInviteToken = findUserByInviteToken;
|
|
32329
32604
|
exports.findVendorByInviteToken = findVendorByInviteToken;
|
|
32330
32605
|
exports.formatTierRange = formatTierRange;
|
|
32331
32606
|
exports.generateNumericOtp = generateNumericOtp;
|
|
@@ -32342,6 +32617,8 @@ exports.invalidateRequireEventApprovalCache = invalidateRequireEventApprovalCach
|
|
|
32342
32617
|
exports.invalidateRequireProductApprovalCache = invalidateRequireProductApprovalCache;
|
|
32343
32618
|
exports.invalidateVendorCatalogCreateFlagsCache = invalidateVendorCatalogCreateFlagsCache;
|
|
32344
32619
|
exports.isCustomerTypeContact = isCustomerTypeContact;
|
|
32620
|
+
exports.isMaxPerUserUsageReached = isMaxPerUserUsageReached;
|
|
32621
|
+
exports.isMaxTotalUsageReached = isMaxTotalUsageReached;
|
|
32345
32622
|
exports.isSyntheticCustomerPhone = isSyntheticCustomerPhone;
|
|
32346
32623
|
exports.isZipMedia = isZipMedia;
|
|
32347
32624
|
exports.linkUnclaimedContactToUser = linkUnclaimedContactToUser;
|
|
@@ -32354,6 +32631,7 @@ exports.metaFetchUserManagedPages = metaFetchUserManagedPages;
|
|
|
32354
32631
|
exports.metaPostPageFeed = metaPostPageFeed;
|
|
32355
32632
|
exports.metaPostPagePhoto = metaPostPagePhoto;
|
|
32356
32633
|
exports.metaResolvePageAccessToken = metaResolvePageAccessToken;
|
|
32634
|
+
exports.newUserInviteToken = newUserInviteToken;
|
|
32357
32635
|
exports.normalizeCustomerPhone = normalizeCustomerPhone;
|
|
32358
32636
|
exports.normalizePhoneE164 = normalizePhoneE164;
|
|
32359
32637
|
exports.normalizeRefundTiers = normalizeRefundTiers;
|
|
@@ -32367,6 +32645,7 @@ exports.queueErpCreateContactIfEnabled = queueErpCreateContactIfEnabled;
|
|
|
32367
32645
|
exports.queueJobScheduleNow = queueJobScheduleNow;
|
|
32368
32646
|
exports.queuePlugin = queuePlugin;
|
|
32369
32647
|
exports.queueSms = queueSms;
|
|
32648
|
+
exports.recordDiscountUsage = recordDiscountUsage;
|
|
32370
32649
|
exports.registerJobRunnerWorker = registerJobRunnerWorker;
|
|
32371
32650
|
exports.registerMessagingQueueProcessors = registerMessagingQueueProcessors;
|
|
32372
32651
|
exports.registerSmsQueueProcessor = registerSmsQueueProcessor;
|