@goweekdays/core 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +165 -11
- package/dist/index.js +1161 -265
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1173 -267
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11342,8 +11342,10 @@ __export(src_exports, {
|
|
|
11342
11342
|
MMember: () => MMember,
|
|
11343
11343
|
MONGO_DB: () => MONGO_DB,
|
|
11344
11344
|
MONGO_URI: () => MONGO_URI,
|
|
11345
|
+
MOrder: () => MOrder,
|
|
11345
11346
|
MOrg: () => MOrg,
|
|
11346
11347
|
MPaymentMethod: () => MPaymentMethod,
|
|
11348
|
+
MPromoCode: () => MPromoCode,
|
|
11347
11349
|
MRole: () => MRole,
|
|
11348
11350
|
MSubscription: () => MSubscription,
|
|
11349
11351
|
MToken: () => MToken,
|
|
@@ -11371,6 +11373,7 @@ __export(src_exports, {
|
|
|
11371
11373
|
XENDIT_BASE_URL: () => XENDIT_BASE_URL,
|
|
11372
11374
|
XENDIT_SECRET_KEY: () => XENDIT_SECRET_KEY,
|
|
11373
11375
|
isDev: () => isDev,
|
|
11376
|
+
schema: () => schema2,
|
|
11374
11377
|
useAddressController: () => useAddressController,
|
|
11375
11378
|
useAddressRepo: () => useAddressRepo,
|
|
11376
11379
|
useAuthController: () => useAuthController,
|
|
@@ -11388,12 +11391,16 @@ __export(src_exports, {
|
|
|
11388
11391
|
useFileRepo: () => useFileRepo,
|
|
11389
11392
|
useFileService: () => useFileService,
|
|
11390
11393
|
useMemberRepo: () => useMemberRepo,
|
|
11394
|
+
useOrderController: () => useOrderController,
|
|
11395
|
+
useOrderRepo: () => useOrderRepo,
|
|
11391
11396
|
useOrgController: () => useOrgController,
|
|
11392
11397
|
useOrgRepo: () => useOrgRepo,
|
|
11393
11398
|
useOrgService: () => useOrgService,
|
|
11394
11399
|
usePaymentMethodController: () => usePaymentMethodController,
|
|
11395
11400
|
usePaymentMethodRepo: () => usePaymentMethodRepo,
|
|
11396
11401
|
usePaymentMethodService: () => usePaymentMethodService,
|
|
11402
|
+
usePromoCodeController: () => usePromoCodeController,
|
|
11403
|
+
usePromoCodeRepo: () => usePromoCodeRepo,
|
|
11397
11404
|
useRoleController: () => useRoleController,
|
|
11398
11405
|
useRoleRepo: () => useRoleRepo,
|
|
11399
11406
|
useRoleService: () => useRoleService,
|
|
@@ -12438,10 +12445,10 @@ var import_utils8 = require("@goweekdays/utils");
|
|
|
12438
12445
|
var import_joi2 = __toESM(require("joi"));
|
|
12439
12446
|
var import_mongodb8 = require("mongodb");
|
|
12440
12447
|
function MMember(value) {
|
|
12441
|
-
const
|
|
12448
|
+
const schema3 = import_joi2.default.object({
|
|
12442
12449
|
_id: import_joi2.default.string().hex().optional().allow("", null),
|
|
12443
|
-
org: import_joi2.default.string().hex().
|
|
12444
|
-
orgName: import_joi2.default.string().
|
|
12450
|
+
org: import_joi2.default.string().hex().optional().allow("", null),
|
|
12451
|
+
orgName: import_joi2.default.string().optional().allow("", null),
|
|
12445
12452
|
name: import_joi2.default.string().required(),
|
|
12446
12453
|
user: import_joi2.default.string().hex().required(),
|
|
12447
12454
|
role: import_joi2.default.string().hex().required(),
|
|
@@ -12450,7 +12457,7 @@ function MMember(value) {
|
|
|
12450
12457
|
updatedAt: import_joi2.default.string().optional().allow("", null),
|
|
12451
12458
|
deletedAt: import_joi2.default.string().optional().allow("", null)
|
|
12452
12459
|
});
|
|
12453
|
-
const { error } =
|
|
12460
|
+
const { error } = schema3.validate(value);
|
|
12454
12461
|
if (error) {
|
|
12455
12462
|
throw new import_utils8.BadRequestError(error.message);
|
|
12456
12463
|
}
|
|
@@ -12477,8 +12484,8 @@ function MMember(value) {
|
|
|
12477
12484
|
}
|
|
12478
12485
|
return {
|
|
12479
12486
|
_id: value._id,
|
|
12480
|
-
org: value.org,
|
|
12481
|
-
orgName: value.orgName,
|
|
12487
|
+
org: value.org ?? "",
|
|
12488
|
+
orgName: value.orgName ?? "",
|
|
12482
12489
|
name: value.name,
|
|
12483
12490
|
user: value.user,
|
|
12484
12491
|
role: value.role,
|
|
@@ -13520,7 +13527,10 @@ function useRoleRepo() {
|
|
|
13520
13527
|
}
|
|
13521
13528
|
async function createUniqueIndex() {
|
|
13522
13529
|
try {
|
|
13523
|
-
await collection.createIndex(
|
|
13530
|
+
await collection.createIndex(
|
|
13531
|
+
{ name: 1, type: 1, org: 1 },
|
|
13532
|
+
{ unique: true }
|
|
13533
|
+
);
|
|
13524
13534
|
} catch (error) {
|
|
13525
13535
|
throw new import_utils14.InternalServerError("Failed to create unique index on role.");
|
|
13526
13536
|
}
|
|
@@ -13534,7 +13544,7 @@ function useRoleRepo() {
|
|
|
13534
13544
|
import_utils14.logger.log({ level: "error", message: `${error}` });
|
|
13535
13545
|
const isDuplicated = error.message.includes("duplicate");
|
|
13536
13546
|
if (isDuplicated) {
|
|
13537
|
-
throw new import_utils14.BadRequestError("
|
|
13547
|
+
throw new import_utils14.BadRequestError("Role already exists");
|
|
13538
13548
|
}
|
|
13539
13549
|
throw new import_utils14.InternalServerError("Failed to create role.");
|
|
13540
13550
|
}
|
|
@@ -15527,36 +15537,75 @@ function useCommentController() {
|
|
|
15527
15537
|
|
|
15528
15538
|
// src/models/subscription.model.ts
|
|
15529
15539
|
var import_utils27 = require("@goweekdays/utils");
|
|
15540
|
+
var import_joi11 = __toESM(require("joi"));
|
|
15530
15541
|
var import_mongodb20 = require("mongodb");
|
|
15531
15542
|
function MSubscription(value) {
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15543
|
+
const schema3 = import_joi11.default.object({
|
|
15544
|
+
_id: import_joi11.default.string().hex().optional().allow("", null),
|
|
15545
|
+
user: import_joi11.default.string().hex().optional().allow("", null),
|
|
15546
|
+
org: import_joi11.default.string().hex().optional().allow("", null),
|
|
15547
|
+
customerId: import_joi11.default.string().required(),
|
|
15548
|
+
paymentMethodId: import_joi11.default.string().required(),
|
|
15549
|
+
amount: import_joi11.default.number().positive().min(0).required(),
|
|
15550
|
+
currency: import_joi11.default.string().required(),
|
|
15551
|
+
description: import_joi11.default.string().optional().allow("", null),
|
|
15552
|
+
promoCode: import_joi11.default.string().optional().allow("", null),
|
|
15553
|
+
type: import_joi11.default.string().valid("organization", "affiliate").required(),
|
|
15554
|
+
seats: import_joi11.default.number().optional().min(0).allow(null, ""),
|
|
15555
|
+
status: import_joi11.default.string().optional().allow("", null),
|
|
15556
|
+
billingCycle: import_joi11.default.string().valid("monthly", "yearly").required(),
|
|
15557
|
+
// Ensure valid values
|
|
15558
|
+
nextBillingDate: import_joi11.default.date().optional(),
|
|
15559
|
+
lastPaymentStatus: import_joi11.default.string().optional().allow("", null),
|
|
15560
|
+
failedAttempts: import_joi11.default.number().optional().allow("", null),
|
|
15561
|
+
createdAt: import_joi11.default.date().optional(),
|
|
15562
|
+
updatedAt: import_joi11.default.string().optional().allow("", null),
|
|
15563
|
+
deletedAt: import_joi11.default.string().optional().allow("", null)
|
|
15564
|
+
}).custom((value2, helpers) => {
|
|
15565
|
+
if (!value2.user && !value2.org) {
|
|
15566
|
+
return helpers.error("any.invalid", {
|
|
15567
|
+
message: "Either user or org is required."
|
|
15568
|
+
});
|
|
15551
15569
|
}
|
|
15552
|
-
|
|
15570
|
+
return value2;
|
|
15571
|
+
});
|
|
15572
|
+
const { error } = schema3.validate(value);
|
|
15573
|
+
if (error) {
|
|
15574
|
+
throw new import_utils27.BadRequestError(error.details[0].message);
|
|
15575
|
+
}
|
|
15576
|
+
if (value._id)
|
|
15577
|
+
value._id = new import_mongodb20.ObjectId(value._id);
|
|
15578
|
+
if (value.user)
|
|
15579
|
+
value.user = new import_mongodb20.ObjectId(value.user);
|
|
15580
|
+
if (value.org)
|
|
15581
|
+
value.org = new import_mongodb20.ObjectId(value.org);
|
|
15582
|
+
const createdAt = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
15583
|
+
const nextBillingDate = new Date(createdAt);
|
|
15584
|
+
if (value.billingCycle === "monthly") {
|
|
15585
|
+
nextBillingDate.setMonth(nextBillingDate.getMonth() + 1);
|
|
15586
|
+
} else if (value.billingCycle === "yearly") {
|
|
15587
|
+
nextBillingDate.setFullYear(nextBillingDate.getFullYear() + 1);
|
|
15588
|
+
}
|
|
15589
|
+
nextBillingDate.setDate(nextBillingDate.getDate() + 1);
|
|
15553
15590
|
return {
|
|
15554
15591
|
_id: value._id,
|
|
15555
15592
|
user: value.user ?? "",
|
|
15556
15593
|
org: value.org ?? "",
|
|
15557
|
-
|
|
15594
|
+
customerId: value.customerId,
|
|
15595
|
+
paymentMethodId: value.paymentMethodId,
|
|
15596
|
+
amount: value.amount,
|
|
15597
|
+
currency: value.currency,
|
|
15598
|
+
description: value.description ?? "",
|
|
15599
|
+
type: value.type,
|
|
15600
|
+
promoCode: value.promoCode ?? "",
|
|
15601
|
+
seats: value.seats ?? 0,
|
|
15558
15602
|
status: "active",
|
|
15559
|
-
|
|
15603
|
+
billingCycle: value.billingCycle,
|
|
15604
|
+
nextBillingDate: nextBillingDate.toISOString(),
|
|
15605
|
+
// Fixed nextBillingDate logic
|
|
15606
|
+
lastPaymentStatus: value.lastPaymentStatus ?? "success",
|
|
15607
|
+
failedAttempts: value.failedAttempts ?? 0,
|
|
15608
|
+
createdAt: createdAt.toISOString(),
|
|
15560
15609
|
updatedAt: value.updatedAt ?? "",
|
|
15561
15610
|
deletedAt: value.deletedAt ?? ""
|
|
15562
15611
|
};
|
|
@@ -15565,6 +15614,7 @@ function MSubscription(value) {
|
|
|
15565
15614
|
// src/repositories/subscription.repository.ts
|
|
15566
15615
|
var import_utils28 = require("@goweekdays/utils");
|
|
15567
15616
|
var import_mongodb21 = require("mongodb");
|
|
15617
|
+
var import_joi12 = __toESM(require("joi"));
|
|
15568
15618
|
function useSubscriptionRepo() {
|
|
15569
15619
|
const db = import_utils28.useAtlas.getDb();
|
|
15570
15620
|
if (!db) {
|
|
@@ -15584,7 +15634,10 @@ function useSubscriptionRepo() {
|
|
|
15584
15634
|
}
|
|
15585
15635
|
async function createUniqueIndex() {
|
|
15586
15636
|
try {
|
|
15587
|
-
await collection.createIndex(
|
|
15637
|
+
await collection.createIndex(
|
|
15638
|
+
{ user: 1, org: 1, status: 1 },
|
|
15639
|
+
{ unique: true }
|
|
15640
|
+
);
|
|
15588
15641
|
} catch (error) {
|
|
15589
15642
|
throw new import_utils28.BadRequestError(
|
|
15590
15643
|
"Failed to create unique index on subscription."
|
|
@@ -15597,6 +15650,7 @@ function useSubscriptionRepo() {
|
|
|
15597
15650
|
const res = await collection.insertOne(value, { session });
|
|
15598
15651
|
return res.insertedId;
|
|
15599
15652
|
} catch (error) {
|
|
15653
|
+
console.log(error);
|
|
15600
15654
|
throw new import_utils28.BadRequestError("Failed to create subscription.");
|
|
15601
15655
|
}
|
|
15602
15656
|
}
|
|
@@ -15624,6 +15678,36 @@ function useSubscriptionRepo() {
|
|
|
15624
15678
|
throw new import_utils28.BadRequestError("Failed to get subscription by ID.");
|
|
15625
15679
|
}
|
|
15626
15680
|
}
|
|
15681
|
+
async function getByAffiliateUserId(user) {
|
|
15682
|
+
try {
|
|
15683
|
+
user = new import_mongodb21.ObjectId(user);
|
|
15684
|
+
} catch (error) {
|
|
15685
|
+
throw new import_utils28.BadRequestError("Invalid user ID.");
|
|
15686
|
+
}
|
|
15687
|
+
try {
|
|
15688
|
+
return await collection.findOne({
|
|
15689
|
+
user,
|
|
15690
|
+
type: "affiliate"
|
|
15691
|
+
});
|
|
15692
|
+
} catch (error) {
|
|
15693
|
+
throw new import_utils28.BadRequestError("Failed to get subscription by ID.");
|
|
15694
|
+
}
|
|
15695
|
+
}
|
|
15696
|
+
async function getByOrgId(org) {
|
|
15697
|
+
try {
|
|
15698
|
+
org = new import_mongodb21.ObjectId(org);
|
|
15699
|
+
} catch (error) {
|
|
15700
|
+
throw new import_utils28.BadRequestError("Invalid org ID.");
|
|
15701
|
+
}
|
|
15702
|
+
try {
|
|
15703
|
+
return await collection.findOne({
|
|
15704
|
+
org,
|
|
15705
|
+
type: "organization"
|
|
15706
|
+
});
|
|
15707
|
+
} catch (error) {
|
|
15708
|
+
throw new import_utils28.BadRequestError("Failed to get subscription by ID.");
|
|
15709
|
+
}
|
|
15710
|
+
}
|
|
15627
15711
|
async function getBySubscriptionId(subscriptionId) {
|
|
15628
15712
|
try {
|
|
15629
15713
|
return await collection.findOne({ subscriptionId });
|
|
@@ -15673,6 +15757,112 @@ function useSubscriptionRepo() {
|
|
|
15673
15757
|
throw new import_utils28.BadRequestError("Failed to update subscription status.");
|
|
15674
15758
|
}
|
|
15675
15759
|
}
|
|
15760
|
+
async function getDueSubscriptions(BATCH_SIZE = 100) {
|
|
15761
|
+
const today = /* @__PURE__ */ new Date();
|
|
15762
|
+
today.setUTCHours(0, 0, 0, 0);
|
|
15763
|
+
try {
|
|
15764
|
+
return await collection.find({
|
|
15765
|
+
status: "active",
|
|
15766
|
+
nextBillingDate: { $lte: today }
|
|
15767
|
+
}).sort({ nextBillingDate: 1 }).limit(BATCH_SIZE).toArray();
|
|
15768
|
+
} catch (error) {
|
|
15769
|
+
throw new import_utils28.BadRequestError("Failed to get due subscriptions.");
|
|
15770
|
+
}
|
|
15771
|
+
}
|
|
15772
|
+
async function getFailedSubscriptions(BATCH_SIZE = 100, maxAttempts = 3) {
|
|
15773
|
+
try {
|
|
15774
|
+
return await collection.find({
|
|
15775
|
+
lastPaymentStatus: "failed",
|
|
15776
|
+
failedAttempts: { $lt: maxAttempts }
|
|
15777
|
+
}).limit(BATCH_SIZE).toArray();
|
|
15778
|
+
} catch (error) {
|
|
15779
|
+
throw new import_utils28.BadRequestError("Failed to get failed subscriptions.");
|
|
15780
|
+
}
|
|
15781
|
+
}
|
|
15782
|
+
async function processSuccessfulPayment(value, session) {
|
|
15783
|
+
const schema3 = import_joi12.default.object({
|
|
15784
|
+
_id: import_joi12.default.string().hex().required(),
|
|
15785
|
+
nextBillingDate: import_joi12.default.date().required()
|
|
15786
|
+
});
|
|
15787
|
+
const { error } = schema3.validate(value);
|
|
15788
|
+
if (error) {
|
|
15789
|
+
throw new import_utils28.BadRequestError(error.message);
|
|
15790
|
+
}
|
|
15791
|
+
try {
|
|
15792
|
+
value._id = new import_mongodb21.ObjectId(value._id);
|
|
15793
|
+
} catch (error2) {
|
|
15794
|
+
throw new import_utils28.BadRequestError("Invalid ID.");
|
|
15795
|
+
}
|
|
15796
|
+
const date = value.nextBillingDate;
|
|
15797
|
+
try {
|
|
15798
|
+
await collection.updateOne(
|
|
15799
|
+
{ _id: value._id },
|
|
15800
|
+
{
|
|
15801
|
+
$set: {
|
|
15802
|
+
nextBillingDate: new Date(
|
|
15803
|
+
new Date(date).setMonth(new Date(date).getMonth() + 1)
|
|
15804
|
+
).toISOString(),
|
|
15805
|
+
lastPaymentStatus: "success",
|
|
15806
|
+
failedAttempts: 0
|
|
15807
|
+
}
|
|
15808
|
+
},
|
|
15809
|
+
{ session }
|
|
15810
|
+
);
|
|
15811
|
+
return "Successfully updated subscription.";
|
|
15812
|
+
} catch (_) {
|
|
15813
|
+
throw new import_utils28.BadRequestError("Failed to update subscription.");
|
|
15814
|
+
}
|
|
15815
|
+
}
|
|
15816
|
+
async function markSubscriptionAsFailed({ _id, failed } = {}, session) {
|
|
15817
|
+
const schema3 = import_joi12.default.object({
|
|
15818
|
+
_id: import_joi12.default.string().hex().required()
|
|
15819
|
+
});
|
|
15820
|
+
const { error } = schema3.validate({ _id });
|
|
15821
|
+
if (error) {
|
|
15822
|
+
throw new import_utils28.BadRequestError(error.message);
|
|
15823
|
+
}
|
|
15824
|
+
try {
|
|
15825
|
+
_id = new import_mongodb21.ObjectId(_id);
|
|
15826
|
+
} catch (error2) {
|
|
15827
|
+
throw new import_utils28.BadRequestError("Invalid ID.");
|
|
15828
|
+
}
|
|
15829
|
+
const updateOptions = {
|
|
15830
|
+
$inc: { failedAttempts: 1 }
|
|
15831
|
+
};
|
|
15832
|
+
if (failed) {
|
|
15833
|
+
updateOptions.$set = { lastPaymentStatus: "failed" };
|
|
15834
|
+
}
|
|
15835
|
+
try {
|
|
15836
|
+
return await collection.updateOne({ _id }, updateOptions, { session });
|
|
15837
|
+
} catch (error2) {
|
|
15838
|
+
throw new import_utils28.BadRequestError("Failed to update subscription.");
|
|
15839
|
+
}
|
|
15840
|
+
}
|
|
15841
|
+
async function markSubscriptionAsCanceled(_id, session) {
|
|
15842
|
+
const schema3 = import_joi12.default.object({
|
|
15843
|
+
_id: import_joi12.default.string().hex().required()
|
|
15844
|
+
});
|
|
15845
|
+
const { error } = schema3.validate({ _id });
|
|
15846
|
+
if (error) {
|
|
15847
|
+
throw new import_utils28.BadRequestError(error.message);
|
|
15848
|
+
}
|
|
15849
|
+
try {
|
|
15850
|
+
_id = new import_mongodb21.ObjectId(_id);
|
|
15851
|
+
} catch (error2) {
|
|
15852
|
+
throw new import_utils28.BadRequestError("Invalid ID.");
|
|
15853
|
+
}
|
|
15854
|
+
try {
|
|
15855
|
+
return await collection.updateOne(
|
|
15856
|
+
{ _id },
|
|
15857
|
+
{
|
|
15858
|
+
$set: { status: "canceled" }
|
|
15859
|
+
},
|
|
15860
|
+
{ session }
|
|
15861
|
+
);
|
|
15862
|
+
} catch (error2) {
|
|
15863
|
+
throw new import_utils28.BadRequestError("Failed to update subscription.");
|
|
15864
|
+
}
|
|
15865
|
+
}
|
|
15676
15866
|
return {
|
|
15677
15867
|
createIndex,
|
|
15678
15868
|
createUniqueIndex,
|
|
@@ -15681,12 +15871,19 @@ function useSubscriptionRepo() {
|
|
|
15681
15871
|
getBySubscriptionId,
|
|
15682
15872
|
getByUserId,
|
|
15683
15873
|
getSubscriptions,
|
|
15684
|
-
updateStatus
|
|
15874
|
+
updateStatus,
|
|
15875
|
+
getByOrgId,
|
|
15876
|
+
getByAffiliateUserId,
|
|
15877
|
+
getDueSubscriptions,
|
|
15878
|
+
getFailedSubscriptions,
|
|
15879
|
+
processSuccessfulPayment,
|
|
15880
|
+
markSubscriptionAsFailed,
|
|
15881
|
+
markSubscriptionAsCanceled
|
|
15685
15882
|
};
|
|
15686
15883
|
}
|
|
15687
15884
|
|
|
15688
15885
|
// src/services/subscription.service.ts
|
|
15689
|
-
var
|
|
15886
|
+
var import_utils64 = require("@goweekdays/utils");
|
|
15690
15887
|
|
|
15691
15888
|
// node_modules/axios/lib/helpers/bind.js
|
|
15692
15889
|
function bind(fn, thisArg) {
|
|
@@ -18560,7 +18757,7 @@ validators.spelling = function spelling(correctSpelling) {
|
|
|
18560
18757
|
return true;
|
|
18561
18758
|
};
|
|
18562
18759
|
};
|
|
18563
|
-
function assertOptions(options,
|
|
18760
|
+
function assertOptions(options, schema3, allowUnknown) {
|
|
18564
18761
|
if (typeof options !== "object") {
|
|
18565
18762
|
throw new AxiosError_default("options must be an object", AxiosError_default.ERR_BAD_OPTION_VALUE);
|
|
18566
18763
|
}
|
|
@@ -18568,7 +18765,7 @@ function assertOptions(options, schema, allowUnknown) {
|
|
|
18568
18765
|
let i = keys.length;
|
|
18569
18766
|
while (i-- > 0) {
|
|
18570
18767
|
const opt = keys[i];
|
|
18571
|
-
const validator =
|
|
18768
|
+
const validator = schema3[opt];
|
|
18572
18769
|
if (validator) {
|
|
18573
18770
|
const value = options[opt];
|
|
18574
18771
|
const result = value === void 0 || validator(value, opt, options);
|
|
@@ -18992,6 +19189,7 @@ var {
|
|
|
18992
19189
|
// src/services/xendit.service.ts
|
|
18993
19190
|
var import_utils55 = require("@goweekdays/utils");
|
|
18994
19191
|
var import_mongodb22 = require("mongodb");
|
|
19192
|
+
var import_joi13 = __toESM(require("joi"));
|
|
18995
19193
|
function useXenditService() {
|
|
18996
19194
|
const basicAuth = Buffer.from(`${XENDIT_SECRET_KEY}:`).toString("base64");
|
|
18997
19195
|
const axios2 = axios_default.create({
|
|
@@ -19150,7 +19348,8 @@ function useXenditService() {
|
|
|
19150
19348
|
amount = 0,
|
|
19151
19349
|
paymentMethod = "",
|
|
19152
19350
|
description = "",
|
|
19153
|
-
interval = "MONTH"
|
|
19351
|
+
interval = "MONTH",
|
|
19352
|
+
seats = 1
|
|
19154
19353
|
} = {}) {
|
|
19155
19354
|
try {
|
|
19156
19355
|
const res = await axios2.post("/recurring/plans", {
|
|
@@ -19183,7 +19382,9 @@ function useXenditService() {
|
|
|
19183
19382
|
},
|
|
19184
19383
|
failed_cycle_action: "STOP",
|
|
19185
19384
|
immediate_action_type: "FULL_AMOUNT",
|
|
19186
|
-
metadata:
|
|
19385
|
+
metadata: {
|
|
19386
|
+
seats
|
|
19387
|
+
},
|
|
19187
19388
|
description
|
|
19188
19389
|
});
|
|
19189
19390
|
return res.data;
|
|
@@ -19210,6 +19411,52 @@ function useXenditService() {
|
|
|
19210
19411
|
throw new import_utils55.BadRequestError("Failed to get subscription status.");
|
|
19211
19412
|
}
|
|
19212
19413
|
}
|
|
19414
|
+
async function getSubscription(id) {
|
|
19415
|
+
try {
|
|
19416
|
+
const res = await axios2.get(`/recurring/plans/${id}`);
|
|
19417
|
+
return res.data;
|
|
19418
|
+
} catch (error) {
|
|
19419
|
+
throw new import_utils55.BadRequestError("Failed to get subscription.");
|
|
19420
|
+
}
|
|
19421
|
+
}
|
|
19422
|
+
async function getSubscriptionCycles(id) {
|
|
19423
|
+
try {
|
|
19424
|
+
const res = await axios2.get(`/recurring/plans/${id}/cycles`);
|
|
19425
|
+
return res.data;
|
|
19426
|
+
} catch (error) {
|
|
19427
|
+
throw new import_utils55.BadRequestError("Failed to get subscription cycles.");
|
|
19428
|
+
}
|
|
19429
|
+
}
|
|
19430
|
+
async function pay(value) {
|
|
19431
|
+
try {
|
|
19432
|
+
const schema3 = import_joi13.default.object({
|
|
19433
|
+
amount: import_joi13.default.number().positive().min(0).required(),
|
|
19434
|
+
currency: import_joi13.default.string().required(),
|
|
19435
|
+
payment_method_id: import_joi13.default.string().required(),
|
|
19436
|
+
customer_id: import_joi13.default.string().required(),
|
|
19437
|
+
description: import_joi13.default.string().optional().allow("", null),
|
|
19438
|
+
metadata: import_joi13.default.object().optional()
|
|
19439
|
+
});
|
|
19440
|
+
const { error } = schema3.validate(value);
|
|
19441
|
+
if (error) {
|
|
19442
|
+
throw new import_utils55.BadRequestError(error.message);
|
|
19443
|
+
}
|
|
19444
|
+
const res = await axios2.post("/payment_requests", {
|
|
19445
|
+
amount: value.amount,
|
|
19446
|
+
currency: value.currency,
|
|
19447
|
+
payment_method_id: value.payment_method_id,
|
|
19448
|
+
customer_id: value.customer_id,
|
|
19449
|
+
description: value.description ?? "",
|
|
19450
|
+
metadata: value.metadata ?? {}
|
|
19451
|
+
});
|
|
19452
|
+
return res.data;
|
|
19453
|
+
} catch (error) {
|
|
19454
|
+
if (error instanceof import_utils55.AppError) {
|
|
19455
|
+
throw error;
|
|
19456
|
+
}
|
|
19457
|
+
throw new import_utils55.BadRequestError("Failed to initiate payment request.");
|
|
19458
|
+
}
|
|
19459
|
+
}
|
|
19213
19460
|
return {
|
|
19214
19461
|
createCustomer,
|
|
19215
19462
|
linkPaymentMethodEWallet,
|
|
@@ -19218,7 +19465,10 @@ function useXenditService() {
|
|
|
19218
19465
|
linkPaymentMethodCard,
|
|
19219
19466
|
eWalletSubsequentPayment,
|
|
19220
19467
|
checkSubscriptionStatus,
|
|
19221
|
-
cancelSubscription
|
|
19468
|
+
cancelSubscription,
|
|
19469
|
+
getSubscription,
|
|
19470
|
+
getSubscriptionCycles,
|
|
19471
|
+
pay
|
|
19222
19472
|
};
|
|
19223
19473
|
}
|
|
19224
19474
|
|
|
@@ -19253,7 +19503,8 @@ function MPaymentMethod(value) {
|
|
|
19253
19503
|
paymentId: value.paymentId ?? "",
|
|
19254
19504
|
customerId: value.customerId ?? "",
|
|
19255
19505
|
number: value.number,
|
|
19256
|
-
|
|
19506
|
+
month_expiry: value.month_expiry ?? "",
|
|
19507
|
+
year_expiry: value.year_expiry ?? "",
|
|
19257
19508
|
cvv: value.cvv ?? "",
|
|
19258
19509
|
status: value.status ?? "active",
|
|
19259
19510
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -19405,23 +19656,23 @@ var import_utils59 = require("@goweekdays/utils");
|
|
|
19405
19656
|
|
|
19406
19657
|
// src/models/organization.model.ts
|
|
19407
19658
|
var import_utils58 = require("@goweekdays/utils");
|
|
19408
|
-
var
|
|
19659
|
+
var import_joi14 = __toESM(require("joi"));
|
|
19409
19660
|
var import_mongodb25 = require("mongodb");
|
|
19410
19661
|
function MOrg(value) {
|
|
19411
|
-
const
|
|
19412
|
-
_id:
|
|
19413
|
-
name:
|
|
19414
|
-
email:
|
|
19415
|
-
contact:
|
|
19416
|
-
type:
|
|
19417
|
-
busInst:
|
|
19418
|
-
description:
|
|
19419
|
-
status:
|
|
19420
|
-
createdAt:
|
|
19421
|
-
updatedAt:
|
|
19422
|
-
deletedAt:
|
|
19662
|
+
const schema3 = import_joi14.default.object({
|
|
19663
|
+
_id: import_joi14.default.string().hex().optional().allow("", null),
|
|
19664
|
+
name: import_joi14.default.string().required(),
|
|
19665
|
+
email: import_joi14.default.string().email().required(),
|
|
19666
|
+
contact: import_joi14.default.string().required(),
|
|
19667
|
+
type: import_joi14.default.string().required(),
|
|
19668
|
+
busInst: import_joi14.default.string().optional().allow("", null),
|
|
19669
|
+
description: import_joi14.default.string().optional().allow("", null),
|
|
19670
|
+
status: import_joi14.default.string().optional().allow("", null),
|
|
19671
|
+
createdAt: import_joi14.default.string().optional().allow("", null),
|
|
19672
|
+
updatedAt: import_joi14.default.string().optional().allow("", null),
|
|
19673
|
+
deletedAt: import_joi14.default.string().optional().allow("", null)
|
|
19423
19674
|
});
|
|
19424
|
-
const { error } =
|
|
19675
|
+
const { error } = schema3.validate(value);
|
|
19425
19676
|
if (error) {
|
|
19426
19677
|
throw new import_utils58.BadRequestError(error.message);
|
|
19427
19678
|
}
|
|
@@ -19710,27 +19961,198 @@ function useAddressRepo() {
|
|
|
19710
19961
|
};
|
|
19711
19962
|
}
|
|
19712
19963
|
|
|
19964
|
+
// src/repositories/order.repository.ts
|
|
19965
|
+
var import_utils63 = require("@goweekdays/utils");
|
|
19966
|
+
|
|
19967
|
+
// src/models/order.model.ts
|
|
19968
|
+
var import_mongodb29 = require("mongodb");
|
|
19969
|
+
|
|
19970
|
+
// src/validations/order.schema.ts
|
|
19971
|
+
var import_joi15 = __toESM(require("joi"));
|
|
19972
|
+
var schema = import_joi15.default.object({
|
|
19973
|
+
_id: import_joi15.default.string().hex().optional().allow("", null),
|
|
19974
|
+
payment: import_joi15.default.string().required(),
|
|
19975
|
+
user: import_joi15.default.string().hex().required(),
|
|
19976
|
+
org: import_joi15.default.string().hex().optional().allow("", null),
|
|
19977
|
+
type: import_joi15.default.string().required(),
|
|
19978
|
+
amount: import_joi15.default.number().positive().min(0).required(),
|
|
19979
|
+
currency: import_joi15.default.string().required(),
|
|
19980
|
+
description: import_joi15.default.string().optional().allow("", null),
|
|
19981
|
+
metadata: import_joi15.default.object({
|
|
19982
|
+
subscriptionId: import_joi15.default.string().hex().optional().allow("", null),
|
|
19983
|
+
cycle: import_joi15.default.number().optional().allow("", null),
|
|
19984
|
+
seats: import_joi15.default.number().optional().allow("", null),
|
|
19985
|
+
promoCode: import_joi15.default.string().optional().allow("", null)
|
|
19986
|
+
}).optional().allow("", null),
|
|
19987
|
+
status: import_joi15.default.string().optional().allow("", null),
|
|
19988
|
+
createdAt: import_joi15.default.string().optional().allow("", null),
|
|
19989
|
+
updatedAt: import_joi15.default.string().optional().allow("", null),
|
|
19990
|
+
deletedAt: import_joi15.default.string().optional().allow("", null)
|
|
19991
|
+
});
|
|
19992
|
+
|
|
19993
|
+
// src/models/order.model.ts
|
|
19994
|
+
var import_utils62 = require("@goweekdays/utils");
|
|
19995
|
+
function MOrder(value) {
|
|
19996
|
+
const { error } = schema.validate(value);
|
|
19997
|
+
if (error) {
|
|
19998
|
+
throw new import_utils62.BadRequestError(error.message);
|
|
19999
|
+
}
|
|
20000
|
+
if (value._id) {
|
|
20001
|
+
try {
|
|
20002
|
+
value._id = new import_mongodb29.ObjectId(value._id);
|
|
20003
|
+
} catch (error2) {
|
|
20004
|
+
throw new import_utils62.BadRequestError("Invalid ID.");
|
|
20005
|
+
}
|
|
20006
|
+
}
|
|
20007
|
+
if (value.user) {
|
|
20008
|
+
try {
|
|
20009
|
+
value.user = new import_mongodb29.ObjectId(value.user);
|
|
20010
|
+
} catch (error2) {
|
|
20011
|
+
throw new import_utils62.BadRequestError("Invalid user ID.");
|
|
20012
|
+
}
|
|
20013
|
+
}
|
|
20014
|
+
if (value.org) {
|
|
20015
|
+
try {
|
|
20016
|
+
value.org = new import_mongodb29.ObjectId(value.org);
|
|
20017
|
+
} catch (error2) {
|
|
20018
|
+
throw new import_utils62.BadRequestError("Invalid org ID.");
|
|
20019
|
+
}
|
|
20020
|
+
}
|
|
20021
|
+
if (value.metadata?.subscriptionId) {
|
|
20022
|
+
try {
|
|
20023
|
+
value.metadata.subscriptionId = new import_mongodb29.ObjectId(
|
|
20024
|
+
value.metadata.subscriptionId
|
|
20025
|
+
);
|
|
20026
|
+
} catch (error2) {
|
|
20027
|
+
throw new import_utils62.BadRequestError("Invalid subscription ID.");
|
|
20028
|
+
}
|
|
20029
|
+
}
|
|
20030
|
+
return {
|
|
20031
|
+
_id: value._id,
|
|
20032
|
+
payment: value.payment,
|
|
20033
|
+
user: value.user ?? "",
|
|
20034
|
+
org: value.org ?? "",
|
|
20035
|
+
type: value.type,
|
|
20036
|
+
amount: value.amount,
|
|
20037
|
+
currency: value.currency,
|
|
20038
|
+
description: value.description ?? "",
|
|
20039
|
+
metadata: value.metadata ?? {},
|
|
20040
|
+
status: value.status ?? "succeeded",
|
|
20041
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20042
|
+
updatedAt: value.updatedAt ?? "",
|
|
20043
|
+
deletedAt: value.deletedAt ?? ""
|
|
20044
|
+
};
|
|
20045
|
+
}
|
|
20046
|
+
|
|
20047
|
+
// src/repositories/order.repository.ts
|
|
20048
|
+
var import_mongodb30 = require("mongodb");
|
|
20049
|
+
function useOrderRepo() {
|
|
20050
|
+
const db = import_utils63.useAtlas.getDb();
|
|
20051
|
+
if (!db) {
|
|
20052
|
+
throw new import_utils63.InternalServerError("Unable to connect to server.");
|
|
20053
|
+
}
|
|
20054
|
+
const collection = db.collection("orders");
|
|
20055
|
+
function createIndex() {
|
|
20056
|
+
try {
|
|
20057
|
+
collection.createIndexes([
|
|
20058
|
+
{ key: { "metadata.subscriptionId": 1 } },
|
|
20059
|
+
{ key: { status: 1 } },
|
|
20060
|
+
{ key: { type: 1 } }
|
|
20061
|
+
]);
|
|
20062
|
+
} catch (error) {
|
|
20063
|
+
throw new Error("Failed to create index for promo code.");
|
|
20064
|
+
}
|
|
20065
|
+
}
|
|
20066
|
+
function add(value, session) {
|
|
20067
|
+
try {
|
|
20068
|
+
value = MOrder(value);
|
|
20069
|
+
collection.insertOne(value, { session });
|
|
20070
|
+
} catch (error) {
|
|
20071
|
+
import_utils63.logger.log({ level: "error", message: `${error}` });
|
|
20072
|
+
if (error instanceof import_utils63.AppError) {
|
|
20073
|
+
throw error;
|
|
20074
|
+
}
|
|
20075
|
+
throw new import_utils63.InternalServerError("Internal server error.");
|
|
20076
|
+
}
|
|
20077
|
+
}
|
|
20078
|
+
async function getOrders({
|
|
20079
|
+
search = "",
|
|
20080
|
+
page = 1,
|
|
20081
|
+
limit = 10,
|
|
20082
|
+
sort = {},
|
|
20083
|
+
status = "active",
|
|
20084
|
+
type = "",
|
|
20085
|
+
id = ""
|
|
20086
|
+
} = {}) {
|
|
20087
|
+
page = page > 0 ? page - 1 : 0;
|
|
20088
|
+
const query = { status };
|
|
20089
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
20090
|
+
if (search) {
|
|
20091
|
+
query.$text = { $search: search };
|
|
20092
|
+
}
|
|
20093
|
+
if (type) {
|
|
20094
|
+
query.type = type;
|
|
20095
|
+
}
|
|
20096
|
+
if (id) {
|
|
20097
|
+
try {
|
|
20098
|
+
query["metadata.subscriptionId"] = new import_mongodb30.ObjectId(id);
|
|
20099
|
+
} catch (error) {
|
|
20100
|
+
throw new import_utils63.BadRequestError("Invalid subscription ID.");
|
|
20101
|
+
}
|
|
20102
|
+
}
|
|
20103
|
+
try {
|
|
20104
|
+
const items = await collection.aggregate([
|
|
20105
|
+
{ $match: query },
|
|
20106
|
+
{ $sort: sort },
|
|
20107
|
+
{ $skip: page * limit },
|
|
20108
|
+
{ $limit: limit }
|
|
20109
|
+
]).toArray();
|
|
20110
|
+
const length = await collection.countDocuments(query);
|
|
20111
|
+
return (0, import_utils63.paginate)(items, page, limit, length);
|
|
20112
|
+
} catch (error) {
|
|
20113
|
+
import_utils63.logger.log({ level: "error", message: `${error}` });
|
|
20114
|
+
throw new import_utils63.InternalServerError("Internal server error.");
|
|
20115
|
+
}
|
|
20116
|
+
}
|
|
20117
|
+
return {
|
|
20118
|
+
createIndex,
|
|
20119
|
+
add,
|
|
20120
|
+
getOrders
|
|
20121
|
+
};
|
|
20122
|
+
}
|
|
20123
|
+
|
|
19713
20124
|
// src/services/subscription.service.ts
|
|
19714
20125
|
function useSubscriptionService() {
|
|
19715
|
-
const {
|
|
20126
|
+
const {
|
|
20127
|
+
getByUserId: _getByUserId,
|
|
20128
|
+
add,
|
|
20129
|
+
getByOrgId: _getByOrgId,
|
|
20130
|
+
getDueSubscriptions,
|
|
20131
|
+
processSuccessfulPayment,
|
|
20132
|
+
markSubscriptionAsFailed,
|
|
20133
|
+
getFailedSubscriptions,
|
|
20134
|
+
markSubscriptionAsCanceled
|
|
20135
|
+
} = useSubscriptionRepo();
|
|
19716
20136
|
const { getUserById: _getUserByUserId, updateUserFieldById } = useUserRepo();
|
|
19717
|
-
const {
|
|
19718
|
-
|
|
20137
|
+
const {
|
|
20138
|
+
checkSubscriptionStatus,
|
|
20139
|
+
getSubscription,
|
|
20140
|
+
getSubscriptionCycles,
|
|
20141
|
+
pay
|
|
20142
|
+
} = useXenditService();
|
|
20143
|
+
const { add: addPaymentMethod } = usePaymentMethodRepo();
|
|
19719
20144
|
const { add: addOrg } = useOrgRepo();
|
|
19720
20145
|
const { add: addAddress } = useAddressRepo();
|
|
19721
20146
|
const { addRole } = useRoleRepo();
|
|
19722
20147
|
const { add: addMember } = useMemberRepo();
|
|
20148
|
+
const { add: addOrder } = useOrderRepo();
|
|
19723
20149
|
async function createOrgSubscription(value) {
|
|
19724
|
-
const session =
|
|
20150
|
+
const session = import_utils64.useAtlas.getClient()?.startSession();
|
|
19725
20151
|
session?.startTransaction();
|
|
19726
20152
|
try {
|
|
19727
20153
|
const _user = await _getUserByUserId(value.user);
|
|
19728
20154
|
if (!_user) {
|
|
19729
|
-
throw new
|
|
19730
|
-
}
|
|
19731
|
-
const payment = await getByPaymentMethodId(value.payment_method_id);
|
|
19732
|
-
if (!payment) {
|
|
19733
|
-
throw new import_utils62.BadRequestError("Payment method not found.");
|
|
20155
|
+
throw new import_utils64.BadRequestError("User not found.");
|
|
19734
20156
|
}
|
|
19735
20157
|
const org = await addOrg(value.organization, session);
|
|
19736
20158
|
const role = await addRole(
|
|
@@ -19759,64 +20181,118 @@ function useSubscriptionService() {
|
|
|
19759
20181
|
session
|
|
19760
20182
|
);
|
|
19761
20183
|
}
|
|
19762
|
-
|
|
19763
|
-
payment.org = org;
|
|
19764
|
-
delete payment._id;
|
|
19765
|
-
await addPaymentMethod(payment, session);
|
|
19766
|
-
value.billingAddress.org = org;
|
|
19767
|
-
await addAddress(value.billingAddress, session);
|
|
19768
|
-
const subscription = await initSubscription({
|
|
19769
|
-
customer: value.customer_id,
|
|
19770
|
-
paymentMethod: value.payment_method_id,
|
|
19771
|
-
amount: value.amount,
|
|
19772
|
-
description: "GoWeekdays Organization Monthly Subscription."
|
|
19773
|
-
});
|
|
19774
|
-
await add(
|
|
20184
|
+
await addPaymentMethod(
|
|
19775
20185
|
{
|
|
19776
20186
|
org,
|
|
19777
|
-
|
|
20187
|
+
paymentId: value.payment_method_id,
|
|
20188
|
+
customerId: value.customer_id,
|
|
20189
|
+
type: value.payment_method_type,
|
|
20190
|
+
name: value.payment_method_channel,
|
|
20191
|
+
number: value.payment_method_number,
|
|
20192
|
+
month_expiry: value.payment_method_expiry_month,
|
|
20193
|
+
year_expiry: value.payment_method_expiry_year,
|
|
20194
|
+
cvv: value.payment_method_cvv
|
|
19778
20195
|
},
|
|
19779
20196
|
session
|
|
19780
20197
|
);
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
|
|
20198
|
+
value.billingAddress.org = org;
|
|
20199
|
+
await addAddress(value.billingAddress, session);
|
|
20200
|
+
const description = "GoWeekdays Organization Monthly Subscription.";
|
|
20201
|
+
const subscription = await add(
|
|
20202
|
+
{
|
|
20203
|
+
org: org.toString(),
|
|
20204
|
+
customerId: value.customer_id,
|
|
20205
|
+
paymentMethodId: value.payment_method_id,
|
|
20206
|
+
amount: value.amount,
|
|
20207
|
+
currency: value.currency,
|
|
20208
|
+
type: "organization",
|
|
20209
|
+
description,
|
|
20210
|
+
seats: value.seats,
|
|
20211
|
+
billingCycle: "monthly"
|
|
20212
|
+
},
|
|
20213
|
+
session
|
|
20214
|
+
);
|
|
20215
|
+
const payment = await pay({
|
|
20216
|
+
customer_id: value.customer_id,
|
|
20217
|
+
payment_method_id: value.payment_method_id,
|
|
20218
|
+
amount: value.amount,
|
|
20219
|
+
currency: value.currency,
|
|
20220
|
+
description
|
|
20221
|
+
});
|
|
20222
|
+
await addOrder(
|
|
20223
|
+
{
|
|
20224
|
+
payment: payment.id,
|
|
20225
|
+
user: value.user,
|
|
20226
|
+
org: org.toString(),
|
|
20227
|
+
type: "organization",
|
|
20228
|
+
amount: value.amount,
|
|
20229
|
+
currency: value.currency,
|
|
20230
|
+
description,
|
|
20231
|
+
metadata: { subscriptionId: subscription.toString() }
|
|
20232
|
+
},
|
|
20233
|
+
session
|
|
20234
|
+
);
|
|
20235
|
+
await session?.commitTransaction();
|
|
20236
|
+
return {
|
|
20237
|
+
message: "Subscription created successfully.",
|
|
20238
|
+
data: { org: org.toString() }
|
|
20239
|
+
};
|
|
20240
|
+
} catch (error) {
|
|
19784
20241
|
await session?.abortTransaction();
|
|
19785
20242
|
throw error;
|
|
19786
20243
|
} finally {
|
|
19787
20244
|
session?.endSession();
|
|
19788
20245
|
}
|
|
19789
20246
|
}
|
|
19790
|
-
async function createAffiliateSubscription({
|
|
19791
|
-
|
|
19792
|
-
amount = 0,
|
|
19793
|
-
payment_method_id = "",
|
|
19794
|
-
customer_id = ""
|
|
19795
|
-
} = {}) {
|
|
19796
|
-
const session = import_utils62.useAtlas.getClient()?.startSession();
|
|
20247
|
+
async function createAffiliateSubscription(value) {
|
|
20248
|
+
const session = import_utils64.useAtlas.getClient()?.startSession();
|
|
19797
20249
|
session?.startTransaction();
|
|
19798
20250
|
try {
|
|
19799
|
-
const _user = await _getUserByUserId(user);
|
|
20251
|
+
const _user = await _getUserByUserId(value.user);
|
|
19800
20252
|
if (!_user) {
|
|
19801
|
-
throw new
|
|
20253
|
+
throw new import_utils64.BadRequestError("User not found.");
|
|
19802
20254
|
}
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
amount,
|
|
19807
|
-
description: "GoWeekdays Affiliate Annual Subscription.",
|
|
19808
|
-
interval: "YEAR"
|
|
19809
|
-
});
|
|
19810
|
-
await add(
|
|
20255
|
+
await addAddress(value.billingAddress, session);
|
|
20256
|
+
const description = "GoWeekdays affiliate yearly Subscription.";
|
|
20257
|
+
const subscription = await add(
|
|
19811
20258
|
{
|
|
19812
|
-
user,
|
|
19813
|
-
|
|
20259
|
+
user: value.user,
|
|
20260
|
+
customerId: value.customer_id,
|
|
20261
|
+
paymentMethodId: value.payment_method_id,
|
|
20262
|
+
amount: value.amount,
|
|
20263
|
+
currency: value.currency,
|
|
20264
|
+
type: "affiliate",
|
|
20265
|
+
description,
|
|
20266
|
+
billingCycle: "yearly"
|
|
20267
|
+
},
|
|
20268
|
+
session
|
|
20269
|
+
);
|
|
20270
|
+
let payment = {};
|
|
20271
|
+
if (value.amount) {
|
|
20272
|
+
payment = await pay({
|
|
20273
|
+
customer_id: value.customer_id,
|
|
20274
|
+
payment_method_id: value.payment_method_id,
|
|
20275
|
+
amount: value.amount,
|
|
20276
|
+
currency: value.currency,
|
|
20277
|
+
description
|
|
20278
|
+
});
|
|
20279
|
+
}
|
|
20280
|
+
await addOrder(
|
|
20281
|
+
{
|
|
20282
|
+
payment: payment.id,
|
|
20283
|
+
user: value.user,
|
|
20284
|
+
type: "affiliate",
|
|
20285
|
+
amount: value.amount,
|
|
20286
|
+
currency: value.currency,
|
|
20287
|
+
description,
|
|
20288
|
+
metadata: { subscriptionId: subscription.toString() }
|
|
19814
20289
|
},
|
|
19815
20290
|
session
|
|
19816
20291
|
);
|
|
19817
20292
|
await session?.commitTransaction();
|
|
19818
20293
|
return "Subscription created successfully.";
|
|
19819
20294
|
} catch (error) {
|
|
20295
|
+
console.log(error);
|
|
19820
20296
|
await session?.abortTransaction();
|
|
19821
20297
|
throw error;
|
|
19822
20298
|
} finally {
|
|
@@ -19827,9 +20303,10 @@ function useSubscriptionService() {
|
|
|
19827
20303
|
try {
|
|
19828
20304
|
const subscription = await _getByUserId(id);
|
|
19829
20305
|
if (!subscription) {
|
|
19830
|
-
throw new
|
|
20306
|
+
throw new import_utils64.BadRequestError("Subscription not found.");
|
|
19831
20307
|
}
|
|
19832
|
-
|
|
20308
|
+
const customerSubscription = await getSubscription(id);
|
|
20309
|
+
return customerSubscription;
|
|
19833
20310
|
} catch (error) {
|
|
19834
20311
|
throw error;
|
|
19835
20312
|
}
|
|
@@ -19842,57 +20319,204 @@ function useSubscriptionService() {
|
|
|
19842
20319
|
);
|
|
19843
20320
|
return status;
|
|
19844
20321
|
} catch (error) {
|
|
19845
|
-
throw new
|
|
20322
|
+
throw new import_utils64.BadRequestError("Failed to fetch subscription status");
|
|
19846
20323
|
}
|
|
19847
20324
|
}
|
|
20325
|
+
async function processSubscriptions(batchSize = 100) {
|
|
20326
|
+
while (true) {
|
|
20327
|
+
const subscriptions = await getDueSubscriptions(batchSize);
|
|
20328
|
+
if (subscriptions.length === 0) {
|
|
20329
|
+
import_utils64.logger.log({
|
|
20330
|
+
level: "info",
|
|
20331
|
+
message: "No more subscriptions to process."
|
|
20332
|
+
});
|
|
20333
|
+
break;
|
|
20334
|
+
}
|
|
20335
|
+
await Promise.allSettled(
|
|
20336
|
+
subscriptions.map(async (sub) => {
|
|
20337
|
+
const session = import_utils64.useAtlas.getClient()?.startSession();
|
|
20338
|
+
session?.startTransaction();
|
|
20339
|
+
try {
|
|
20340
|
+
const payment = await pay({
|
|
20341
|
+
customer_id: sub.customerId,
|
|
20342
|
+
payment_method_id: sub.paymentMethodId,
|
|
20343
|
+
amount: sub.amount,
|
|
20344
|
+
currency: sub.currency,
|
|
20345
|
+
description: "GoWeekdays Monthly Subscription"
|
|
20346
|
+
});
|
|
20347
|
+
await addOrder(
|
|
20348
|
+
{
|
|
20349
|
+
payment: payment.id,
|
|
20350
|
+
user: sub.user,
|
|
20351
|
+
org: sub.org,
|
|
20352
|
+
type: "organization",
|
|
20353
|
+
amount: sub.amount,
|
|
20354
|
+
currency: sub.currency,
|
|
20355
|
+
description: "GoWeekdays Monthly Subscription",
|
|
20356
|
+
metadata: { subscriptionId: sub._id }
|
|
20357
|
+
},
|
|
20358
|
+
session
|
|
20359
|
+
);
|
|
20360
|
+
await processSuccessfulPayment(
|
|
20361
|
+
{ _id: sub._id, nextBillingDate: sub.nextBillingDate },
|
|
20362
|
+
session
|
|
20363
|
+
);
|
|
20364
|
+
await session?.commitTransaction();
|
|
20365
|
+
import_utils64.logger.log({
|
|
20366
|
+
level: "info",
|
|
20367
|
+
message: `Processed subscription ${sub._id} successfully.`
|
|
20368
|
+
});
|
|
20369
|
+
} catch (error) {
|
|
20370
|
+
await session?.abortTransaction();
|
|
20371
|
+
import_utils64.logger.log({
|
|
20372
|
+
level: "error",
|
|
20373
|
+
message: `Failed to process ${sub._id}: ${error}`
|
|
20374
|
+
});
|
|
20375
|
+
await markSubscriptionAsFailed({
|
|
20376
|
+
_id: String(sub._id),
|
|
20377
|
+
failed: true
|
|
20378
|
+
});
|
|
20379
|
+
} finally {
|
|
20380
|
+
session?.endSession();
|
|
20381
|
+
}
|
|
20382
|
+
})
|
|
20383
|
+
);
|
|
20384
|
+
import_utils64.logger.log({
|
|
20385
|
+
level: "info",
|
|
20386
|
+
message: "Processed a batch of subscriptions."
|
|
20387
|
+
});
|
|
20388
|
+
}
|
|
20389
|
+
}
|
|
20390
|
+
async function retryFailedPayments(batchSize = 100) {
|
|
20391
|
+
let hasMore = true;
|
|
20392
|
+
while (hasMore) {
|
|
20393
|
+
const failedSubs = await getFailedSubscriptions(batchSize);
|
|
20394
|
+
if (failedSubs.length === 0) {
|
|
20395
|
+
hasMore = false;
|
|
20396
|
+
break;
|
|
20397
|
+
}
|
|
20398
|
+
await Promise.allSettled(
|
|
20399
|
+
failedSubs.map(async (sub) => {
|
|
20400
|
+
const session = import_utils64.useAtlas.getClient()?.startSession();
|
|
20401
|
+
session?.startTransaction();
|
|
20402
|
+
try {
|
|
20403
|
+
const payment = await pay({
|
|
20404
|
+
customer_id: sub.customerId,
|
|
20405
|
+
payment_method_id: sub.paymentMethodId,
|
|
20406
|
+
amount: sub.amount,
|
|
20407
|
+
currency: sub.currency,
|
|
20408
|
+
description: "GoWeekdays Monthly Subscription - Retry"
|
|
20409
|
+
});
|
|
20410
|
+
await addOrder(
|
|
20411
|
+
{
|
|
20412
|
+
payment: payment.id,
|
|
20413
|
+
user: sub.user,
|
|
20414
|
+
org: sub.org,
|
|
20415
|
+
type: "organization",
|
|
20416
|
+
amount: sub.amount,
|
|
20417
|
+
currency: sub.currency,
|
|
20418
|
+
description: "GoWeekdays Monthly Subscription",
|
|
20419
|
+
metadata: { subscriptionId: sub._id }
|
|
20420
|
+
},
|
|
20421
|
+
session
|
|
20422
|
+
);
|
|
20423
|
+
await processSuccessfulPayment(
|
|
20424
|
+
{ _id: sub._id, nextBillingDate: sub.nextBillingDate },
|
|
20425
|
+
session
|
|
20426
|
+
);
|
|
20427
|
+
await session?.commitTransaction();
|
|
20428
|
+
import_utils64.logger.log({
|
|
20429
|
+
level: "info",
|
|
20430
|
+
message: `Successfully retried subscription ${sub._id}.`
|
|
20431
|
+
});
|
|
20432
|
+
} catch (error) {
|
|
20433
|
+
await session?.abortTransaction();
|
|
20434
|
+
import_utils64.logger.log({
|
|
20435
|
+
level: "error",
|
|
20436
|
+
message: `Retry failed for ${sub._id}: ${error}`
|
|
20437
|
+
});
|
|
20438
|
+
await markSubscriptionAsFailed({ _id: String(sub._id) });
|
|
20439
|
+
if (sub.failedAttempts && sub.failedAttempts + 1 >= 3) {
|
|
20440
|
+
await markSubscriptionAsCanceled(String(sub._id));
|
|
20441
|
+
import_utils64.logger.log({
|
|
20442
|
+
level: "info",
|
|
20443
|
+
message: `Subscription ${sub._id} canceled after max retry attempts.`
|
|
20444
|
+
});
|
|
20445
|
+
}
|
|
20446
|
+
} finally {
|
|
20447
|
+
session?.endSession();
|
|
20448
|
+
}
|
|
20449
|
+
})
|
|
20450
|
+
);
|
|
20451
|
+
import_utils64.logger.log({
|
|
20452
|
+
level: "info",
|
|
20453
|
+
message: `Processed batch of ${failedSubs.length}.`
|
|
20454
|
+
});
|
|
20455
|
+
}
|
|
20456
|
+
import_utils64.logger.log({ level: "info", message: "All failed payments retried." });
|
|
20457
|
+
}
|
|
19848
20458
|
return {
|
|
19849
20459
|
getByUserId,
|
|
19850
20460
|
getStatusByUser,
|
|
19851
20461
|
createAffiliateSubscription,
|
|
19852
|
-
createOrgSubscription
|
|
20462
|
+
createOrgSubscription,
|
|
20463
|
+
processSubscriptions,
|
|
20464
|
+
retryFailedPayments
|
|
19853
20465
|
};
|
|
19854
20466
|
}
|
|
19855
20467
|
|
|
19856
20468
|
// src/controllers/subscription.controller.ts
|
|
19857
|
-
var
|
|
19858
|
-
var
|
|
20469
|
+
var import_joi17 = __toESM(require("joi"));
|
|
20470
|
+
var import_utils65 = require("@goweekdays/utils");
|
|
19859
20471
|
|
|
19860
20472
|
// src/validations/subscription.schema.ts
|
|
19861
|
-
var
|
|
20473
|
+
var import_joi16 = __toESM(require("joi"));
|
|
19862
20474
|
function useSubscriptionSchema() {
|
|
19863
|
-
const
|
|
19864
|
-
user:
|
|
19865
|
-
amount:
|
|
19866
|
-
customer_id:
|
|
19867
|
-
payment_method_id:
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
|
|
19874
|
-
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
|
|
19878
|
-
|
|
19879
|
-
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
20475
|
+
const schema3 = import_joi16.default.object({
|
|
20476
|
+
user: import_joi16.default.string().required().min(0),
|
|
20477
|
+
amount: import_joi16.default.number().required(),
|
|
20478
|
+
customer_id: import_joi16.default.string().required(),
|
|
20479
|
+
payment_method_id: import_joi16.default.string().required(),
|
|
20480
|
+
payment_method_type: import_joi16.default.string().required(),
|
|
20481
|
+
payment_method_number: import_joi16.default.string().required(),
|
|
20482
|
+
payment_method_channel: import_joi16.default.string().required(),
|
|
20483
|
+
payment_method_month_expiry: import_joi16.default.string().optional().allow(null, ""),
|
|
20484
|
+
payment_method_year_expiry: import_joi16.default.string().optional().allow(null, ""),
|
|
20485
|
+
payment_method_cvv: import_joi16.default.string().optional().allow(null, ""),
|
|
20486
|
+
currency: import_joi16.default.string().optional().allow("", null),
|
|
20487
|
+
seats: import_joi16.default.number().optional().min(0).allow(null),
|
|
20488
|
+
organization: import_joi16.default.object({
|
|
20489
|
+
name: import_joi16.default.string().required(),
|
|
20490
|
+
description: import_joi16.default.string().optional().allow("", null),
|
|
20491
|
+
type: import_joi16.default.string().allow("personal", "business").required(),
|
|
20492
|
+
email: import_joi16.default.string().email().required(),
|
|
20493
|
+
contact: import_joi16.default.string().required(),
|
|
20494
|
+
busInst: import_joi16.default.string().optional().allow(null, "")
|
|
20495
|
+
}).optional().allow({}),
|
|
20496
|
+
billingAddress: import_joi16.default.object({
|
|
20497
|
+
type: import_joi16.default.string().required(),
|
|
20498
|
+
country: import_joi16.default.string().required(),
|
|
20499
|
+
address: import_joi16.default.string().required(),
|
|
20500
|
+
continuedAddress: import_joi16.default.string().optional().allow(null, ""),
|
|
20501
|
+
city: import_joi16.default.string().required(),
|
|
20502
|
+
province: import_joi16.default.string().required(),
|
|
20503
|
+
postalCode: import_joi16.default.string().required(),
|
|
20504
|
+
taxId: import_joi16.default.string().optional().allow(null, "")
|
|
19886
20505
|
}).required()
|
|
19887
20506
|
});
|
|
19888
20507
|
return {
|
|
19889
|
-
schema
|
|
20508
|
+
schema: schema3
|
|
19890
20509
|
};
|
|
19891
20510
|
}
|
|
19892
20511
|
|
|
19893
20512
|
// src/controllers/subscription.controller.ts
|
|
19894
20513
|
function useSubscriptionController() {
|
|
19895
|
-
const {
|
|
20514
|
+
const {
|
|
20515
|
+
add: _add,
|
|
20516
|
+
getSubscriptions: _getSubscriptions,
|
|
20517
|
+
getByAffiliateUserId: _getByAffiliateUserId,
|
|
20518
|
+
getByOrgId: _getByOrgId
|
|
20519
|
+
} = useSubscriptionRepo();
|
|
19896
20520
|
const {
|
|
19897
20521
|
getByUserId: _getByUserId,
|
|
19898
20522
|
getStatusByUser: _getStatusByUser,
|
|
@@ -19901,13 +20525,13 @@ function useSubscriptionController() {
|
|
|
19901
20525
|
} = useSubscriptionService();
|
|
19902
20526
|
async function add(req, res, next) {
|
|
19903
20527
|
const value = req.body;
|
|
19904
|
-
const validation =
|
|
19905
|
-
user:
|
|
19906
|
-
subscriptionId:
|
|
20528
|
+
const validation = import_joi17.default.object({
|
|
20529
|
+
user: import_joi17.default.string().required(),
|
|
20530
|
+
subscriptionId: import_joi17.default.string().required()
|
|
19907
20531
|
});
|
|
19908
20532
|
const { error } = validation.validate(value);
|
|
19909
20533
|
if (error) {
|
|
19910
|
-
next(new
|
|
20534
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
19911
20535
|
}
|
|
19912
20536
|
try {
|
|
19913
20537
|
const value2 = req.body;
|
|
@@ -19920,10 +20544,10 @@ function useSubscriptionController() {
|
|
|
19920
20544
|
}
|
|
19921
20545
|
async function getByUserId(req, res, next) {
|
|
19922
20546
|
const id = req.params.id;
|
|
19923
|
-
const validation =
|
|
20547
|
+
const validation = import_joi17.default.string().required();
|
|
19924
20548
|
const { error } = validation.validate(id);
|
|
19925
20549
|
if (error) {
|
|
19926
|
-
next(new
|
|
20550
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
19927
20551
|
}
|
|
19928
20552
|
try {
|
|
19929
20553
|
const subscription = await _getByUserId(id);
|
|
@@ -19933,18 +20557,48 @@ function useSubscriptionController() {
|
|
|
19933
20557
|
next(error2);
|
|
19934
20558
|
}
|
|
19935
20559
|
}
|
|
20560
|
+
async function getByAffiliateUserId(req, res, next) {
|
|
20561
|
+
const id = req.params.id;
|
|
20562
|
+
const validation = import_joi17.default.string().required();
|
|
20563
|
+
const { error } = validation.validate(id);
|
|
20564
|
+
if (error) {
|
|
20565
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
20566
|
+
}
|
|
20567
|
+
try {
|
|
20568
|
+
const subscription = await _getByAffiliateUserId(id);
|
|
20569
|
+
res.json(subscription);
|
|
20570
|
+
return;
|
|
20571
|
+
} catch (error2) {
|
|
20572
|
+
next(error2);
|
|
20573
|
+
}
|
|
20574
|
+
}
|
|
20575
|
+
async function getByOrgId(req, res, next) {
|
|
20576
|
+
const id = req.params.id;
|
|
20577
|
+
const validation = import_joi17.default.string().required();
|
|
20578
|
+
const { error } = validation.validate(id);
|
|
20579
|
+
if (error) {
|
|
20580
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
20581
|
+
}
|
|
20582
|
+
try {
|
|
20583
|
+
const subscription = await _getByOrgId(id);
|
|
20584
|
+
res.json(subscription);
|
|
20585
|
+
return;
|
|
20586
|
+
} catch (error2) {
|
|
20587
|
+
next(error2);
|
|
20588
|
+
}
|
|
20589
|
+
}
|
|
19936
20590
|
async function getSubscriptions(req, res, next) {
|
|
19937
20591
|
const status = req.query.status ?? "";
|
|
19938
20592
|
const search = req.query.search ?? "";
|
|
19939
20593
|
const page = Number(req.query.page) ?? 1;
|
|
19940
|
-
const validation =
|
|
19941
|
-
status:
|
|
19942
|
-
search:
|
|
19943
|
-
page:
|
|
20594
|
+
const validation = import_joi17.default.object({
|
|
20595
|
+
status: import_joi17.default.string().required(),
|
|
20596
|
+
search: import_joi17.default.string().optional().allow("", null),
|
|
20597
|
+
page: import_joi17.default.number().required()
|
|
19944
20598
|
});
|
|
19945
20599
|
const { error } = validation.validate({ status, search, page });
|
|
19946
20600
|
if (error) {
|
|
19947
|
-
next(new
|
|
20601
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
19948
20602
|
}
|
|
19949
20603
|
try {
|
|
19950
20604
|
const subscriptions = await _getSubscriptions({ status, search, page });
|
|
@@ -19956,10 +20610,10 @@ function useSubscriptionController() {
|
|
|
19956
20610
|
}
|
|
19957
20611
|
async function getSubscriptionStatus(req, res, next) {
|
|
19958
20612
|
const id = req.params.id;
|
|
19959
|
-
const validation =
|
|
20613
|
+
const validation = import_joi17.default.string().required();
|
|
19960
20614
|
const { error } = validation.validate(id);
|
|
19961
20615
|
if (error) {
|
|
19962
|
-
next(new
|
|
20616
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
19963
20617
|
}
|
|
19964
20618
|
try {
|
|
19965
20619
|
const status = await _getStatusByUser(id);
|
|
@@ -19969,37 +20623,17 @@ function useSubscriptionController() {
|
|
|
19969
20623
|
next(error2);
|
|
19970
20624
|
}
|
|
19971
20625
|
}
|
|
20626
|
+
const { schema: subscriptionSchema } = useSubscriptionSchema();
|
|
19972
20627
|
async function createAffiliateSubscription(req, res, next) {
|
|
19973
|
-
const
|
|
19974
|
-
|
|
19975
|
-
const
|
|
19976
|
-
const currency = req.body.currency ?? "PHP";
|
|
19977
|
-
const user = req.headers["user"];
|
|
19978
|
-
const validation = import_joi13.default.object({
|
|
19979
|
-
user: import_joi13.default.string().required(),
|
|
19980
|
-
amount: import_joi13.default.number().required(),
|
|
19981
|
-
customer_id: import_joi13.default.string().required(),
|
|
19982
|
-
payment_method_id: import_joi13.default.string().required(),
|
|
19983
|
-
currency: import_joi13.default.string().optional().allow("", null)
|
|
19984
|
-
});
|
|
19985
|
-
const { error } = validation.validate({
|
|
19986
|
-
user,
|
|
19987
|
-
amount,
|
|
19988
|
-
customer_id,
|
|
19989
|
-
payment_method_id,
|
|
19990
|
-
currency
|
|
19991
|
-
});
|
|
20628
|
+
const value = req.body;
|
|
20629
|
+
value.user = req.headers["user"];
|
|
20630
|
+
const { error } = subscriptionSchema.validate(value);
|
|
19992
20631
|
if (error) {
|
|
19993
|
-
next(new
|
|
20632
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
19994
20633
|
return;
|
|
19995
20634
|
}
|
|
19996
20635
|
try {
|
|
19997
|
-
const id = await _createAffiliateSubscription(
|
|
19998
|
-
user,
|
|
19999
|
-
amount,
|
|
20000
|
-
customer_id,
|
|
20001
|
-
payment_method_id
|
|
20002
|
-
});
|
|
20636
|
+
const id = await _createAffiliateSubscription(value);
|
|
20003
20637
|
res.json({ message: "Successfully added subscription.", id });
|
|
20004
20638
|
return;
|
|
20005
20639
|
} catch (error2) {
|
|
@@ -20008,18 +20642,17 @@ function useSubscriptionController() {
|
|
|
20008
20642
|
return;
|
|
20009
20643
|
}
|
|
20010
20644
|
}
|
|
20011
|
-
const { schema: subscriptionSchema } = useSubscriptionSchema();
|
|
20012
20645
|
async function createOrgSubscription(req, res, next) {
|
|
20013
20646
|
const value = req.body;
|
|
20014
20647
|
value.user = req.headers["user"];
|
|
20015
20648
|
const { error } = subscriptionSchema.validate(value);
|
|
20016
20649
|
if (error) {
|
|
20017
|
-
next(new
|
|
20650
|
+
next(new import_utils65.BadRequestError(error.message));
|
|
20018
20651
|
return;
|
|
20019
20652
|
}
|
|
20020
20653
|
try {
|
|
20021
|
-
const
|
|
20022
|
-
res.json(
|
|
20654
|
+
const _res = await _createOrgSubscription(value);
|
|
20655
|
+
res.json(_res);
|
|
20023
20656
|
return;
|
|
20024
20657
|
} catch (error2) {
|
|
20025
20658
|
next(error2);
|
|
@@ -20029,6 +20662,8 @@ function useSubscriptionController() {
|
|
|
20029
20662
|
return {
|
|
20030
20663
|
add,
|
|
20031
20664
|
getByUserId,
|
|
20665
|
+
getByOrgId,
|
|
20666
|
+
getByAffiliateUserId,
|
|
20032
20667
|
getSubscriptions,
|
|
20033
20668
|
getSubscriptionStatus,
|
|
20034
20669
|
createAffiliateSubscription,
|
|
@@ -20037,7 +20672,7 @@ function useSubscriptionController() {
|
|
|
20037
20672
|
}
|
|
20038
20673
|
|
|
20039
20674
|
// src/services/payment-method.service.ts
|
|
20040
|
-
var
|
|
20675
|
+
var import_utils66 = require("@goweekdays/utils");
|
|
20041
20676
|
function usePaymentMethodService() {
|
|
20042
20677
|
const { createCustomer, linkPaymentMethodEWallet, linkPaymentMethodCard } = useXenditService();
|
|
20043
20678
|
const { getUserById } = useUserRepo();
|
|
@@ -20090,7 +20725,7 @@ function usePaymentMethodService() {
|
|
|
20090
20725
|
failure_return_url = "",
|
|
20091
20726
|
cancel_return_url = ""
|
|
20092
20727
|
} = {}) {
|
|
20093
|
-
const session =
|
|
20728
|
+
const session = import_utils66.useAtlas.getClient()?.startSession();
|
|
20094
20729
|
session?.startTransaction();
|
|
20095
20730
|
try {
|
|
20096
20731
|
const customerData = {
|
|
@@ -20100,10 +20735,10 @@ function usePaymentMethodService() {
|
|
|
20100
20735
|
if (user) {
|
|
20101
20736
|
const _user = await getUserById(user);
|
|
20102
20737
|
if (!_user) {
|
|
20103
|
-
throw new
|
|
20738
|
+
throw new import_utils66.BadRequestError("User not found.");
|
|
20104
20739
|
}
|
|
20105
20740
|
if (!_user._id) {
|
|
20106
|
-
throw new
|
|
20741
|
+
throw new import_utils66.BadRequestError("Invalid user ID.");
|
|
20107
20742
|
}
|
|
20108
20743
|
customerData.email = _user.email;
|
|
20109
20744
|
customerData.given_names = _user.firstName;
|
|
@@ -20112,7 +20747,7 @@ function usePaymentMethodService() {
|
|
|
20112
20747
|
if (org) {
|
|
20113
20748
|
const _org = await getOrgById(org);
|
|
20114
20749
|
if (!_org) {
|
|
20115
|
-
throw new
|
|
20750
|
+
throw new import_utils66.BadRequestError("Organization not found.");
|
|
20116
20751
|
}
|
|
20117
20752
|
customerData.email = _org.email;
|
|
20118
20753
|
customerData.given_names = _org.name;
|
|
@@ -20126,20 +20761,6 @@ function usePaymentMethodService() {
|
|
|
20126
20761
|
failure_return_url,
|
|
20127
20762
|
cancel_return_url
|
|
20128
20763
|
});
|
|
20129
|
-
await add(
|
|
20130
|
-
{
|
|
20131
|
-
user,
|
|
20132
|
-
org,
|
|
20133
|
-
type,
|
|
20134
|
-
status: "active",
|
|
20135
|
-
paymentId: paymentMethod.id,
|
|
20136
|
-
customerId: customer.id,
|
|
20137
|
-
name: paymentMethod.type,
|
|
20138
|
-
number: mobile_number
|
|
20139
|
-
},
|
|
20140
|
-
session
|
|
20141
|
-
);
|
|
20142
|
-
await session?.commitTransaction();
|
|
20143
20764
|
return {
|
|
20144
20765
|
paymentMethod: paymentMethod.id,
|
|
20145
20766
|
customer: customer.id,
|
|
@@ -20164,15 +20785,15 @@ function usePaymentMethodService() {
|
|
|
20164
20785
|
cardholder_name = "",
|
|
20165
20786
|
currency = "PHP"
|
|
20166
20787
|
} = {}) {
|
|
20167
|
-
const session =
|
|
20788
|
+
const session = import_utils66.useAtlas.getClient()?.startSession();
|
|
20168
20789
|
session?.startTransaction();
|
|
20169
20790
|
try {
|
|
20170
20791
|
const _user = await getUserById(user);
|
|
20171
20792
|
if (!_user) {
|
|
20172
|
-
throw new
|
|
20793
|
+
throw new import_utils66.BadRequestError("User not found.");
|
|
20173
20794
|
}
|
|
20174
20795
|
if (!_user._id) {
|
|
20175
|
-
throw new
|
|
20796
|
+
throw new import_utils66.BadRequestError("Invalid user ID.");
|
|
20176
20797
|
}
|
|
20177
20798
|
const result = await linkPaymentMethodCard({
|
|
20178
20799
|
card_number,
|
|
@@ -20212,8 +20833,8 @@ function usePaymentMethodService() {
|
|
|
20212
20833
|
}
|
|
20213
20834
|
|
|
20214
20835
|
// src/controllers/payment-method.controller.ts
|
|
20215
|
-
var
|
|
20216
|
-
var
|
|
20836
|
+
var import_joi18 = __toESM(require("joi"));
|
|
20837
|
+
var import_utils67 = require("@goweekdays/utils");
|
|
20217
20838
|
function usePaymentMethodController() {
|
|
20218
20839
|
const { linkEWallet: _linkEWallet, linkCard: _linkCard } = usePaymentMethodService();
|
|
20219
20840
|
async function linkEWallet(req, res, next) {
|
|
@@ -20224,14 +20845,14 @@ function usePaymentMethodController() {
|
|
|
20224
20845
|
const success_return_url = req.body.success_return_url ?? "";
|
|
20225
20846
|
const failure_return_url = req.body.failure_return_url ?? "";
|
|
20226
20847
|
const cancel_return_url = req.body.cancel_return_url ?? "";
|
|
20227
|
-
const validation =
|
|
20228
|
-
user:
|
|
20229
|
-
org:
|
|
20230
|
-
mobile_number:
|
|
20231
|
-
type:
|
|
20232
|
-
success_return_url:
|
|
20233
|
-
failure_return_url:
|
|
20234
|
-
cancel_return_url:
|
|
20848
|
+
const validation = import_joi18.default.object({
|
|
20849
|
+
user: import_joi18.default.string().hex().optional().allow("", null),
|
|
20850
|
+
org: import_joi18.default.string().hex().optional().allow("", null),
|
|
20851
|
+
mobile_number: import_joi18.default.string().required(),
|
|
20852
|
+
type: import_joi18.default.string().valid("GCASH", "PAYMAYA").required(),
|
|
20853
|
+
success_return_url: import_joi18.default.string().uri().required(),
|
|
20854
|
+
failure_return_url: import_joi18.default.string().uri().required(),
|
|
20855
|
+
cancel_return_url: import_joi18.default.string().uri().required()
|
|
20235
20856
|
}).custom((value, helpers) => {
|
|
20236
20857
|
if (!value.user && !value.org) {
|
|
20237
20858
|
return helpers.error("any.invalid", {
|
|
@@ -20250,7 +20871,7 @@ function usePaymentMethodController() {
|
|
|
20250
20871
|
cancel_return_url
|
|
20251
20872
|
});
|
|
20252
20873
|
if (error) {
|
|
20253
|
-
next(new
|
|
20874
|
+
next(new import_utils67.BadRequestError(error.message));
|
|
20254
20875
|
}
|
|
20255
20876
|
try {
|
|
20256
20877
|
const result = await _linkEWallet({
|
|
@@ -20279,17 +20900,17 @@ function usePaymentMethodController() {
|
|
|
20279
20900
|
const failure_return_url = req.body.failure_return_url ?? "";
|
|
20280
20901
|
const cardType = req.body.cardType ?? "";
|
|
20281
20902
|
const user = req.headers["user"] ?? "";
|
|
20282
|
-
const validation =
|
|
20283
|
-
cardNumber:
|
|
20284
|
-
expiryMonth:
|
|
20285
|
-
expiryYear:
|
|
20286
|
-
cvv:
|
|
20287
|
-
cardholderName:
|
|
20288
|
-
currency:
|
|
20289
|
-
success_return_url:
|
|
20290
|
-
failure_return_url:
|
|
20291
|
-
cardType:
|
|
20292
|
-
user:
|
|
20903
|
+
const validation = import_joi18.default.object({
|
|
20904
|
+
cardNumber: import_joi18.default.string().required(),
|
|
20905
|
+
expiryMonth: import_joi18.default.string().required(),
|
|
20906
|
+
expiryYear: import_joi18.default.string().required(),
|
|
20907
|
+
cvv: import_joi18.default.string().required(),
|
|
20908
|
+
cardholderName: import_joi18.default.string().required(),
|
|
20909
|
+
currency: import_joi18.default.string().optional().allow("", null),
|
|
20910
|
+
success_return_url: import_joi18.default.string().uri().required(),
|
|
20911
|
+
failure_return_url: import_joi18.default.string().uri().required(),
|
|
20912
|
+
cardType: import_joi18.default.string().required(),
|
|
20913
|
+
user: import_joi18.default.string().hex().required()
|
|
20293
20914
|
});
|
|
20294
20915
|
const { error } = validation.validate({
|
|
20295
20916
|
user,
|
|
@@ -20304,7 +20925,7 @@ function usePaymentMethodController() {
|
|
|
20304
20925
|
failure_return_url
|
|
20305
20926
|
});
|
|
20306
20927
|
if (error) {
|
|
20307
|
-
next(new
|
|
20928
|
+
next(new import_utils67.BadRequestError(error.message));
|
|
20308
20929
|
}
|
|
20309
20930
|
try {
|
|
20310
20931
|
const result = await _linkCard({
|
|
@@ -20328,12 +20949,12 @@ function usePaymentMethodController() {
|
|
|
20328
20949
|
const { getByUser: _getByUser, getByOrg: _getByOrg } = usePaymentMethodRepo();
|
|
20329
20950
|
async function getByUser(req, res, next) {
|
|
20330
20951
|
const user = req.params.user ?? "";
|
|
20331
|
-
const validation =
|
|
20332
|
-
user:
|
|
20952
|
+
const validation = import_joi18.default.object({
|
|
20953
|
+
user: import_joi18.default.string().hex().required()
|
|
20333
20954
|
});
|
|
20334
20955
|
const { error } = validation.validate({ user });
|
|
20335
20956
|
if (error) {
|
|
20336
|
-
next(new
|
|
20957
|
+
next(new import_utils67.BadRequestError(error.message));
|
|
20337
20958
|
}
|
|
20338
20959
|
try {
|
|
20339
20960
|
const result = await _getByUser(user);
|
|
@@ -20344,12 +20965,12 @@ function usePaymentMethodController() {
|
|
|
20344
20965
|
}
|
|
20345
20966
|
async function getByOrg(req, res, next) {
|
|
20346
20967
|
const org = req.params.org ?? "";
|
|
20347
|
-
const validation =
|
|
20348
|
-
org:
|
|
20968
|
+
const validation = import_joi18.default.object({
|
|
20969
|
+
org: import_joi18.default.string().hex().required()
|
|
20349
20970
|
});
|
|
20350
20971
|
const { error } = validation.validate({ org });
|
|
20351
20972
|
if (error) {
|
|
20352
|
-
next(new
|
|
20973
|
+
next(new import_utils67.BadRequestError(error.message));
|
|
20353
20974
|
}
|
|
20354
20975
|
try {
|
|
20355
20976
|
const result = await _getByOrg(org);
|
|
@@ -20367,27 +20988,27 @@ function usePaymentMethodController() {
|
|
|
20367
20988
|
}
|
|
20368
20989
|
|
|
20369
20990
|
// src/controllers/address.controller.ts
|
|
20370
|
-
var
|
|
20371
|
-
var
|
|
20991
|
+
var import_utils68 = require("@goweekdays/utils");
|
|
20992
|
+
var import_joi19 = __toESM(require("joi"));
|
|
20372
20993
|
function useAddressController() {
|
|
20373
20994
|
const { add: _add, getByUserId: _getByUserId } = useAddressRepo();
|
|
20374
20995
|
async function add(req, res, next) {
|
|
20375
20996
|
const value = req.body;
|
|
20376
|
-
const validation =
|
|
20377
|
-
type:
|
|
20378
|
-
user:
|
|
20379
|
-
org:
|
|
20380
|
-
country:
|
|
20381
|
-
address:
|
|
20382
|
-
continuedAddress:
|
|
20383
|
-
city:
|
|
20384
|
-
province:
|
|
20385
|
-
postalCode:
|
|
20386
|
-
taxId:
|
|
20997
|
+
const validation = import_joi19.default.object({
|
|
20998
|
+
type: import_joi19.default.string().required(),
|
|
20999
|
+
user: import_joi19.default.string().hex().optional().allow("", null),
|
|
21000
|
+
org: import_joi19.default.string().hex().optional().allow("", null),
|
|
21001
|
+
country: import_joi19.default.string().required(),
|
|
21002
|
+
address: import_joi19.default.string().required(),
|
|
21003
|
+
continuedAddress: import_joi19.default.string().optional().allow("", null),
|
|
21004
|
+
city: import_joi19.default.string().required(),
|
|
21005
|
+
province: import_joi19.default.string().required(),
|
|
21006
|
+
postalCode: import_joi19.default.string().required(),
|
|
21007
|
+
taxId: import_joi19.default.string().optional().allow("", null)
|
|
20387
21008
|
});
|
|
20388
21009
|
const { error } = validation.validate(value);
|
|
20389
21010
|
if (error) {
|
|
20390
|
-
next(new
|
|
21011
|
+
next(new import_utils68.BadRequestError(error.message));
|
|
20391
21012
|
}
|
|
20392
21013
|
try {
|
|
20393
21014
|
const value2 = req.body;
|
|
@@ -20400,15 +21021,15 @@ function useAddressController() {
|
|
|
20400
21021
|
}
|
|
20401
21022
|
async function getByUserId(req, res, next) {
|
|
20402
21023
|
const user = req.params.user;
|
|
20403
|
-
const validation =
|
|
21024
|
+
const validation = import_joi19.default.string().hex().required();
|
|
20404
21025
|
const { error } = validation.validate(user);
|
|
20405
21026
|
if (error) {
|
|
20406
|
-
next(new
|
|
21027
|
+
next(new import_utils68.BadRequestError(error.message));
|
|
20407
21028
|
}
|
|
20408
21029
|
try {
|
|
20409
21030
|
const address = await _getByUserId(user);
|
|
20410
21031
|
if (!address) {
|
|
20411
|
-
next(new
|
|
21032
|
+
next(new import_utils68.NotFoundError("Address not found."));
|
|
20412
21033
|
return;
|
|
20413
21034
|
}
|
|
20414
21035
|
res.json(address);
|
|
@@ -20424,19 +21045,19 @@ function useAddressController() {
|
|
|
20424
21045
|
}
|
|
20425
21046
|
|
|
20426
21047
|
// src/services/organization.service.ts
|
|
20427
|
-
var
|
|
21048
|
+
var import_utils69 = require("@goweekdays/utils");
|
|
20428
21049
|
function useOrgService() {
|
|
20429
21050
|
const { add: addOrg } = useOrgRepo();
|
|
20430
21051
|
const { addRole } = useRoleRepo();
|
|
20431
21052
|
const { add: addMember } = useMemberRepo();
|
|
20432
21053
|
const { getUserById } = useUserRepo();
|
|
20433
21054
|
async function createOrg({ user = "", name = "", description = "" } = {}) {
|
|
20434
|
-
const session =
|
|
21055
|
+
const session = import_utils69.useAtlas.getClient()?.startSession();
|
|
20435
21056
|
session?.startTransaction();
|
|
20436
21057
|
try {
|
|
20437
21058
|
const _user = await getUserById(user);
|
|
20438
21059
|
if (!_user) {
|
|
20439
|
-
throw new
|
|
21060
|
+
throw new import_utils69.NotFoundError("User not found.");
|
|
20440
21061
|
}
|
|
20441
21062
|
const org = await addOrg(
|
|
20442
21063
|
{
|
|
@@ -20479,25 +21100,25 @@ function useOrgService() {
|
|
|
20479
21100
|
}
|
|
20480
21101
|
|
|
20481
21102
|
// src/controllers/organization.controller.ts
|
|
20482
|
-
var
|
|
20483
|
-
var
|
|
21103
|
+
var import_utils70 = require("@goweekdays/utils");
|
|
21104
|
+
var import_joi20 = __toESM(require("joi"));
|
|
20484
21105
|
function useOrgController() {
|
|
20485
21106
|
const { createOrg: _createOrg } = useOrgService();
|
|
20486
21107
|
const { getByUserId: _getByUserId } = useMemberRepo();
|
|
20487
21108
|
const { getByName: _getByName } = useOrgRepo();
|
|
20488
21109
|
async function createOrg(req, res, next) {
|
|
20489
21110
|
const value = req.body;
|
|
20490
|
-
const validation =
|
|
20491
|
-
name:
|
|
20492
|
-
type:
|
|
20493
|
-
email:
|
|
20494
|
-
contact:
|
|
20495
|
-
description:
|
|
20496
|
-
user:
|
|
21111
|
+
const validation = import_joi20.default.object({
|
|
21112
|
+
name: import_joi20.default.string().required(),
|
|
21113
|
+
type: import_joi20.default.string().required(),
|
|
21114
|
+
email: import_joi20.default.string().email().required(),
|
|
21115
|
+
contact: import_joi20.default.string().required(),
|
|
21116
|
+
description: import_joi20.default.string().required(),
|
|
21117
|
+
user: import_joi20.default.string().hex().required()
|
|
20497
21118
|
});
|
|
20498
21119
|
const { error } = validation.validate(value);
|
|
20499
21120
|
if (error) {
|
|
20500
|
-
next(new
|
|
21121
|
+
next(new import_utils70.BadRequestError(error.message));
|
|
20501
21122
|
return;
|
|
20502
21123
|
}
|
|
20503
21124
|
try {
|
|
@@ -20515,23 +21136,23 @@ function useOrgController() {
|
|
|
20515
21136
|
const user = req.headers["user"];
|
|
20516
21137
|
const isPageNumber = isFinite(page);
|
|
20517
21138
|
if (!isPageNumber) {
|
|
20518
|
-
next(new
|
|
21139
|
+
next(new import_utils70.BadRequestError("Invalid page number."));
|
|
20519
21140
|
return;
|
|
20520
21141
|
}
|
|
20521
21142
|
const isLimitNumber = isFinite(limit);
|
|
20522
21143
|
if (!isLimitNumber) {
|
|
20523
|
-
next(new
|
|
21144
|
+
next(new import_utils70.BadRequestError("Invalid limit number."));
|
|
20524
21145
|
return;
|
|
20525
21146
|
}
|
|
20526
|
-
const validation =
|
|
20527
|
-
user:
|
|
20528
|
-
page:
|
|
20529
|
-
limit:
|
|
20530
|
-
search:
|
|
21147
|
+
const validation = import_joi20.default.object({
|
|
21148
|
+
user: import_joi20.default.string().hex().required(),
|
|
21149
|
+
page: import_joi20.default.number().min(1).optional().allow("", null),
|
|
21150
|
+
limit: import_joi20.default.number().min(1).optional().allow("", null),
|
|
21151
|
+
search: import_joi20.default.string().optional().allow("", null)
|
|
20531
21152
|
});
|
|
20532
21153
|
const { error } = validation.validate({ user, page, limit, search });
|
|
20533
21154
|
if (error) {
|
|
20534
|
-
next(new
|
|
21155
|
+
next(new import_utils70.BadRequestError(error.message));
|
|
20535
21156
|
return;
|
|
20536
21157
|
}
|
|
20537
21158
|
try {
|
|
@@ -20544,12 +21165,12 @@ function useOrgController() {
|
|
|
20544
21165
|
}
|
|
20545
21166
|
async function getByName(req, res, next) {
|
|
20546
21167
|
const name = req.params.name;
|
|
20547
|
-
const validation =
|
|
20548
|
-
name:
|
|
21168
|
+
const validation = import_joi20.default.object({
|
|
21169
|
+
name: import_joi20.default.string().required()
|
|
20549
21170
|
});
|
|
20550
21171
|
const { error } = validation.validate({ name });
|
|
20551
21172
|
if (error) {
|
|
20552
|
-
next(new
|
|
21173
|
+
next(new import_utils70.BadRequestError(error.message));
|
|
20553
21174
|
return;
|
|
20554
21175
|
}
|
|
20555
21176
|
try {
|
|
@@ -20566,6 +21187,274 @@ function useOrgController() {
|
|
|
20566
21187
|
getByName
|
|
20567
21188
|
};
|
|
20568
21189
|
}
|
|
21190
|
+
|
|
21191
|
+
// src/validations/promo-code.schema.ts
|
|
21192
|
+
var import_joi21 = __toESM(require("joi"));
|
|
21193
|
+
var promoTypeSchema = import_joi21.default.string().valid("tiered", "fixed").required();
|
|
21194
|
+
var promoTierSchema = import_joi21.default.object({
|
|
21195
|
+
min: import_joi21.default.number().integer().min(1).required(),
|
|
21196
|
+
max: import_joi21.default.number().integer().min(import_joi21.default.ref("min")).allow(0).required(),
|
|
21197
|
+
price: import_joi21.default.number().positive().required()
|
|
21198
|
+
});
|
|
21199
|
+
var schema2 = import_joi21.default.object({
|
|
21200
|
+
code: import_joi21.default.string().trim().uppercase().required(),
|
|
21201
|
+
description: import_joi21.default.string().trim().optional(),
|
|
21202
|
+
type: promoTypeSchema,
|
|
21203
|
+
tiers: import_joi21.default.alternatives().conditional("type", {
|
|
21204
|
+
is: "tiered",
|
|
21205
|
+
then: import_joi21.default.array().items(promoTierSchema).min(1).required(),
|
|
21206
|
+
otherwise: import_joi21.default.forbidden()
|
|
21207
|
+
}),
|
|
21208
|
+
fixed_rate: import_joi21.default.alternatives().conditional("type", {
|
|
21209
|
+
is: "fixed",
|
|
21210
|
+
then: import_joi21.default.number().required().min(0),
|
|
21211
|
+
otherwise: import_joi21.default.number().integer().allow(0)
|
|
21212
|
+
}),
|
|
21213
|
+
expiresAt: import_joi21.default.string().optional().allow(null, "")
|
|
21214
|
+
});
|
|
21215
|
+
|
|
21216
|
+
// src/models/promo-code.model.ts
|
|
21217
|
+
var import_utils71 = require("@goweekdays/utils");
|
|
21218
|
+
function MPromoCode(data) {
|
|
21219
|
+
const { error } = schema2.validate(data);
|
|
21220
|
+
if (error) {
|
|
21221
|
+
throw new import_utils71.BadRequestError(error.message);
|
|
21222
|
+
}
|
|
21223
|
+
return {
|
|
21224
|
+
_id: data._id,
|
|
21225
|
+
code: data.code,
|
|
21226
|
+
description: data.description ?? "",
|
|
21227
|
+
type: data.type,
|
|
21228
|
+
tiers: data.tiers ?? [],
|
|
21229
|
+
fixed_rate: data.fixed_rate ?? 0,
|
|
21230
|
+
appliesTo: data.appliesTo ?? "",
|
|
21231
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21232
|
+
expiresAt: data.expiresAt ?? "",
|
|
21233
|
+
assignedTo: data.assignedTo,
|
|
21234
|
+
status: data.status ?? "active"
|
|
21235
|
+
};
|
|
21236
|
+
}
|
|
21237
|
+
|
|
21238
|
+
// src/repositories/promo-code.repository.ts
|
|
21239
|
+
var import_utils72 = require("@goweekdays/utils");
|
|
21240
|
+
var import_joi22 = __toESM(require("joi"));
|
|
21241
|
+
function usePromoCodeRepo() {
|
|
21242
|
+
const db = import_utils72.useAtlas.getDb();
|
|
21243
|
+
if (!db) {
|
|
21244
|
+
throw new import_utils72.InternalServerError("Unable to connect to server.");
|
|
21245
|
+
}
|
|
21246
|
+
const collection = db.collection("promo-codes");
|
|
21247
|
+
async function createIndex() {
|
|
21248
|
+
try {
|
|
21249
|
+
await collection.createIndexes([
|
|
21250
|
+
{ key: { code: 1 } },
|
|
21251
|
+
{ key: { type: 1 } }
|
|
21252
|
+
]);
|
|
21253
|
+
} catch (error) {
|
|
21254
|
+
throw new Error("Failed to create index for promo code.");
|
|
21255
|
+
}
|
|
21256
|
+
}
|
|
21257
|
+
async function createUniqueIndex() {
|
|
21258
|
+
try {
|
|
21259
|
+
await collection.createIndexes([
|
|
21260
|
+
{ key: { code: 1, type: 1 }, unique: true }
|
|
21261
|
+
]);
|
|
21262
|
+
} catch (error) {
|
|
21263
|
+
throw new Error("Failed to create unique index for promo code.");
|
|
21264
|
+
}
|
|
21265
|
+
}
|
|
21266
|
+
async function add(value) {
|
|
21267
|
+
try {
|
|
21268
|
+
value = MPromoCode(value);
|
|
21269
|
+
await collection.insertOne(value);
|
|
21270
|
+
} catch (error) {
|
|
21271
|
+
import_utils72.logger.log({ level: "error", message: `${error}` });
|
|
21272
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
21273
|
+
if (isDuplicated) {
|
|
21274
|
+
throw new import_utils72.BadRequestError("Promo code already exists.");
|
|
21275
|
+
}
|
|
21276
|
+
throw new import_utils72.InternalServerError("Internal server error.");
|
|
21277
|
+
}
|
|
21278
|
+
}
|
|
21279
|
+
async function getByCode(code) {
|
|
21280
|
+
const schema3 = import_joi22.default.object({
|
|
21281
|
+
code: import_joi22.default.string().trim().required()
|
|
21282
|
+
});
|
|
21283
|
+
const { error } = schema3.validate({ code });
|
|
21284
|
+
if (error) {
|
|
21285
|
+
throw new import_utils72.BadRequestError(error.message);
|
|
21286
|
+
}
|
|
21287
|
+
try {
|
|
21288
|
+
return await collection.findOne({ code });
|
|
21289
|
+
} catch (error2) {
|
|
21290
|
+
throw new import_utils72.InternalServerError("Internal server error.");
|
|
21291
|
+
}
|
|
21292
|
+
}
|
|
21293
|
+
async function getPromoCodes({
|
|
21294
|
+
search = "",
|
|
21295
|
+
page = 1,
|
|
21296
|
+
limit = 10,
|
|
21297
|
+
sort = {},
|
|
21298
|
+
status = "active",
|
|
21299
|
+
type = ""
|
|
21300
|
+
} = {}) {
|
|
21301
|
+
page = page > 0 ? page - 1 : 0;
|
|
21302
|
+
const query = { status };
|
|
21303
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
21304
|
+
if (search) {
|
|
21305
|
+
query.$text = { $search: search };
|
|
21306
|
+
}
|
|
21307
|
+
if (type) {
|
|
21308
|
+
query.type = type;
|
|
21309
|
+
}
|
|
21310
|
+
try {
|
|
21311
|
+
const items = await collection.aggregate([
|
|
21312
|
+
{ $match: query },
|
|
21313
|
+
{ $sort: sort },
|
|
21314
|
+
{ $skip: page * limit },
|
|
21315
|
+
{ $limit: limit }
|
|
21316
|
+
]).toArray();
|
|
21317
|
+
const length = await collection.countDocuments(query);
|
|
21318
|
+
return (0, import_utils72.paginate)(items, page, limit, length);
|
|
21319
|
+
} catch (error) {
|
|
21320
|
+
import_utils72.logger.log({ level: "error", message: `${error}` });
|
|
21321
|
+
throw new import_utils72.InternalServerError("Internal server error.");
|
|
21322
|
+
}
|
|
21323
|
+
}
|
|
21324
|
+
return {
|
|
21325
|
+
createIndex,
|
|
21326
|
+
createUniqueIndex,
|
|
21327
|
+
add,
|
|
21328
|
+
getByCode,
|
|
21329
|
+
getPromoCodes
|
|
21330
|
+
};
|
|
21331
|
+
}
|
|
21332
|
+
|
|
21333
|
+
// src/controllers/promo-code.controller.ts
|
|
21334
|
+
var import_utils73 = require("@goweekdays/utils");
|
|
21335
|
+
var import_joi23 = __toESM(require("joi"));
|
|
21336
|
+
function usePromoCodeController() {
|
|
21337
|
+
const {
|
|
21338
|
+
add: _add,
|
|
21339
|
+
getByCode: _getByCode,
|
|
21340
|
+
getPromoCodes: _getPromoCodes
|
|
21341
|
+
} = usePromoCodeRepo();
|
|
21342
|
+
async function add(req, res, next) {
|
|
21343
|
+
const data = req.body;
|
|
21344
|
+
const { error } = schema2.validate(data);
|
|
21345
|
+
if (error) {
|
|
21346
|
+
next(new import_utils73.BadRequestError(error.message));
|
|
21347
|
+
return;
|
|
21348
|
+
}
|
|
21349
|
+
try {
|
|
21350
|
+
await _add(data);
|
|
21351
|
+
res.json({ message: "Successfully added promo code." });
|
|
21352
|
+
return;
|
|
21353
|
+
} catch (error2) {
|
|
21354
|
+
if (error2 instanceof import_utils73.AppError) {
|
|
21355
|
+
next(error2);
|
|
21356
|
+
} else {
|
|
21357
|
+
next(new import_utils73.InternalServerError(error2));
|
|
21358
|
+
}
|
|
21359
|
+
}
|
|
21360
|
+
}
|
|
21361
|
+
async function getByCode(req, res, next) {
|
|
21362
|
+
const code = req.params.code;
|
|
21363
|
+
const validation = import_joi23.default.string().required();
|
|
21364
|
+
const { error } = validation.validate(code);
|
|
21365
|
+
if (error) {
|
|
21366
|
+
next(new import_utils73.BadRequestError(error.message));
|
|
21367
|
+
return;
|
|
21368
|
+
}
|
|
21369
|
+
try {
|
|
21370
|
+
const promoCode = await _getByCode(code);
|
|
21371
|
+
res.json({ promoCode });
|
|
21372
|
+
return;
|
|
21373
|
+
} catch (error2) {
|
|
21374
|
+
if (error2 instanceof import_utils73.AppError) {
|
|
21375
|
+
next(error2);
|
|
21376
|
+
} else {
|
|
21377
|
+
next(new import_utils73.InternalServerError(error2));
|
|
21378
|
+
}
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
async function getPromoCodes(req, res, next) {
|
|
21382
|
+
const page = req.query.page ? Number(req.query.page) : 1;
|
|
21383
|
+
const limit = req.query.limit ? Number(req.query.limit) : 10;
|
|
21384
|
+
const search = req.query.search;
|
|
21385
|
+
const status = req.query.status;
|
|
21386
|
+
const validation = import_joi23.default.object({
|
|
21387
|
+
page: import_joi23.default.number().required(),
|
|
21388
|
+
limit: import_joi23.default.number().integer().optional().min(10).max(100),
|
|
21389
|
+
search: import_joi23.default.string().optional().allow(""),
|
|
21390
|
+
status: import_joi23.default.string().required()
|
|
21391
|
+
});
|
|
21392
|
+
const { error } = validation.validate({ page, limit, search, status });
|
|
21393
|
+
if (error) {
|
|
21394
|
+
next(new import_utils73.BadRequestError(error.message));
|
|
21395
|
+
return;
|
|
21396
|
+
}
|
|
21397
|
+
try {
|
|
21398
|
+
const promoCodes = await _getPromoCodes({
|
|
21399
|
+
page,
|
|
21400
|
+
limit,
|
|
21401
|
+
search,
|
|
21402
|
+
status
|
|
21403
|
+
});
|
|
21404
|
+
res.json(promoCodes);
|
|
21405
|
+
return;
|
|
21406
|
+
} catch (error2) {
|
|
21407
|
+
next(error2);
|
|
21408
|
+
}
|
|
21409
|
+
}
|
|
21410
|
+
return {
|
|
21411
|
+
add,
|
|
21412
|
+
getByCode,
|
|
21413
|
+
getPromoCodes
|
|
21414
|
+
};
|
|
21415
|
+
}
|
|
21416
|
+
|
|
21417
|
+
// src/controllers/order.controller.ts
|
|
21418
|
+
var import_utils74 = require("@goweekdays/utils");
|
|
21419
|
+
var import_joi24 = __toESM(require("joi"));
|
|
21420
|
+
function useOrderController() {
|
|
21421
|
+
const { getOrders: _getOrders } = useOrderRepo();
|
|
21422
|
+
async function getOrders(req, res, next) {
|
|
21423
|
+
const page = req.query.page ?? 1;
|
|
21424
|
+
const limit = req.query.limit ?? 10;
|
|
21425
|
+
const search = req.query.search ?? "";
|
|
21426
|
+
const status = req.query.status ?? "succeeded";
|
|
21427
|
+
const id = req.query.id ?? "";
|
|
21428
|
+
const validation = import_joi24.default.object({
|
|
21429
|
+
page: import_joi24.default.number().required(),
|
|
21430
|
+
limit: import_joi24.default.number().required().min(10),
|
|
21431
|
+
search: import_joi24.default.string().optional().allow("", null),
|
|
21432
|
+
status: import_joi24.default.string().optional().allow("", null),
|
|
21433
|
+
id: import_joi24.default.string().hex().optional().allow("", null)
|
|
21434
|
+
});
|
|
21435
|
+
const { error } = validation.validate({ page, limit, search, status, id });
|
|
21436
|
+
if (error) {
|
|
21437
|
+
next(new import_utils74.BadRequestError(error.message));
|
|
21438
|
+
return;
|
|
21439
|
+
}
|
|
21440
|
+
try {
|
|
21441
|
+
const orders = await _getOrders({
|
|
21442
|
+
page: parseInt(page),
|
|
21443
|
+
limit: parseInt(limit),
|
|
21444
|
+
search,
|
|
21445
|
+
status,
|
|
21446
|
+
id
|
|
21447
|
+
});
|
|
21448
|
+
res.json(orders);
|
|
21449
|
+
return;
|
|
21450
|
+
} catch (error2) {
|
|
21451
|
+
next(error2);
|
|
21452
|
+
}
|
|
21453
|
+
}
|
|
21454
|
+
return {
|
|
21455
|
+
getOrders
|
|
21456
|
+
};
|
|
21457
|
+
}
|
|
20569
21458
|
// Annotate the CommonJS export names for ESM import in node:
|
|
20570
21459
|
0 && (module.exports = {
|
|
20571
21460
|
ACCESS_TOKEN_EXPIRY,
|
|
@@ -20589,8 +21478,10 @@ function useOrgController() {
|
|
|
20589
21478
|
MMember,
|
|
20590
21479
|
MONGO_DB,
|
|
20591
21480
|
MONGO_URI,
|
|
21481
|
+
MOrder,
|
|
20592
21482
|
MOrg,
|
|
20593
21483
|
MPaymentMethod,
|
|
21484
|
+
MPromoCode,
|
|
20594
21485
|
MRole,
|
|
20595
21486
|
MSubscription,
|
|
20596
21487
|
MToken,
|
|
@@ -20618,6 +21509,7 @@ function useOrgController() {
|
|
|
20618
21509
|
XENDIT_BASE_URL,
|
|
20619
21510
|
XENDIT_SECRET_KEY,
|
|
20620
21511
|
isDev,
|
|
21512
|
+
schema,
|
|
20621
21513
|
useAddressController,
|
|
20622
21514
|
useAddressRepo,
|
|
20623
21515
|
useAuthController,
|
|
@@ -20635,12 +21527,16 @@ function useOrgController() {
|
|
|
20635
21527
|
useFileRepo,
|
|
20636
21528
|
useFileService,
|
|
20637
21529
|
useMemberRepo,
|
|
21530
|
+
useOrderController,
|
|
21531
|
+
useOrderRepo,
|
|
20638
21532
|
useOrgController,
|
|
20639
21533
|
useOrgRepo,
|
|
20640
21534
|
useOrgService,
|
|
20641
21535
|
usePaymentMethodController,
|
|
20642
21536
|
usePaymentMethodRepo,
|
|
20643
21537
|
usePaymentMethodService,
|
|
21538
|
+
usePromoCodeController,
|
|
21539
|
+
usePromoCodeRepo,
|
|
20644
21540
|
useRoleController,
|
|
20645
21541
|
useRoleRepo,
|
|
20646
21542
|
useRoleService,
|