@7365admin1/core 3.7.1 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -33394,6 +33394,176 @@ var KeyRepo = class {
33394
33394
  }
33395
33395
  };
33396
33396
 
33397
+ // src/services/notification.service.ts
33398
+ import { sendExpoPushNotifications } from "iservice365-expo-notifications";
33399
+
33400
+ // src/repositories/push-token.repository.ts
33401
+ var PushTokenRepo = class {
33402
+ static collection() {
33403
+ return getDB().collection("push_tokens");
33404
+ }
33405
+ static async createIndexes() {
33406
+ await Promise.all([
33407
+ this.collection().createIndex({ token: 1 }, { unique: true }),
33408
+ this.collection().createIndex({ userId: 1, platform: 1 }),
33409
+ this.collection().createIndex({ siteId: 1 })
33410
+ ]);
33411
+ }
33412
+ static async upsert(userId, token, platform, siteId, projectId, appSlug) {
33413
+ const now = /* @__PURE__ */ new Date();
33414
+ const p = platform;
33415
+ const existing = await this.collection().findOne({ token });
33416
+ if (existing) {
33417
+ await this.collection().updateOne(
33418
+ { token },
33419
+ {
33420
+ $set: {
33421
+ userId,
33422
+ platform: p,
33423
+ siteId,
33424
+ projectId,
33425
+ appSlug,
33426
+ updatedAt: now
33427
+ }
33428
+ }
33429
+ );
33430
+ return;
33431
+ }
33432
+ await this.collection().deleteMany({ userId, platform: p });
33433
+ await this.collection().insertOne({
33434
+ userId,
33435
+ siteId,
33436
+ token,
33437
+ platform: p,
33438
+ projectId,
33439
+ appSlug,
33440
+ createdAt: now,
33441
+ updatedAt: now
33442
+ });
33443
+ }
33444
+ static async remove(token) {
33445
+ await this.collection().deleteMany({ token });
33446
+ }
33447
+ static async findTokensByUserIds(userIds, appSlug) {
33448
+ const docs = await this.collection().find({ userId: { $in: userIds }, appSlug: { $eq: appSlug } }).toArray();
33449
+ return docs.map((d) => d.token);
33450
+ }
33451
+ };
33452
+
33453
+ // src/services/notification.service.ts
33454
+ function toStringArray(recipient) {
33455
+ const arr = Array.isArray(recipient) ? recipient : [recipient];
33456
+ return arr.map((r) => r.toString());
33457
+ }
33458
+ async function send(userIds, title, body, data, isForMAMobileApp = false, appSlug) {
33459
+ try {
33460
+ let tokens = [];
33461
+ if (isForMAMobileApp) {
33462
+ tokens = await PushTokenRepo.findTokensByUserIds(userIds, appSlug);
33463
+ } else {
33464
+ tokens = await PushTokenRepo.findTokensByUserIds(userIds);
33465
+ }
33466
+ if (!tokens.length)
33467
+ return;
33468
+ for (const token of tokens) {
33469
+ await sendExpoPushNotifications([token], { title, body, data });
33470
+ }
33471
+ } catch (error) {
33472
+ console.warn("[NotificationService]", error);
33473
+ }
33474
+ }
33475
+ var NotificationService = class {
33476
+ static async bulletinBoardCreated(payload) {
33477
+ await send(
33478
+ toStringArray(payload.to),
33479
+ "Bulletin Board",
33480
+ `There is new ${payload.status} bulletin board.`,
33481
+ {
33482
+ bulletinId: payload.bulletinId.toString(),
33483
+ status: payload.status,
33484
+ module: "feedback",
33485
+ screen: "/(user)/bulletinInfo",
33486
+ params: {
33487
+ id: payload.bulletinId.toString()
33488
+ }
33489
+ },
33490
+ false,
33491
+ "iservice365-resident-mobile-app"
33492
+ );
33493
+ }
33494
+ static async prelovedMarketplacePostCreation(payload) {
33495
+ await send(
33496
+ toStringArray(payload.to),
33497
+ "Preloved Marketplace",
33498
+ `New preloved marketplace post added.`,
33499
+ {
33500
+ prelovedId: payload.prelovedId.toString(),
33501
+ status: payload.status,
33502
+ module: "prelovedMarketplace",
33503
+ screen: "/(user)/(marketplace)/prelovedPostInfo",
33504
+ params: {
33505
+ id: payload.prelovedId.toString()
33506
+ }
33507
+ },
33508
+ false,
33509
+ "iservice365-resident-mobile-app"
33510
+ );
33511
+ }
33512
+ static async bulletinBoardCreatedForMA(payload) {
33513
+ await send(
33514
+ toStringArray(payload.to),
33515
+ "Bulletin Board",
33516
+ `There is new ${payload.status} bulletin board.`,
33517
+ {
33518
+ bulletinId: payload.bulletinId.toString(),
33519
+ status: payload.status,
33520
+ module: "feedback",
33521
+ screen: "/(user)/(bulletin-board)",
33522
+ params: {
33523
+ id: payload.bulletinId.toString()
33524
+ }
33525
+ },
33526
+ true,
33527
+ "iservice365-ma-mobile-app"
33528
+ );
33529
+ }
33530
+ static async eventCreatedForMA(payload) {
33531
+ await send(
33532
+ toStringArray(payload.to),
33533
+ "Event",
33534
+ `There is new ${payload.status} event.`,
33535
+ {
33536
+ eventId: payload.eventId.toString(),
33537
+ status: payload.status,
33538
+ module: "event",
33539
+ screen: "/(user)/(events)",
33540
+ params: {
33541
+ id: payload.eventId.toString()
33542
+ }
33543
+ },
33544
+ true,
33545
+ "iservice365-ma-mobile-app"
33546
+ );
33547
+ }
33548
+ static async invitedVisitorCheckOutForMa(payload) {
33549
+ await send(
33550
+ toStringArray(payload.to),
33551
+ "Invited Visitor Check Out",
33552
+ `The invited visitor ${payload.name}, has been checked out.`,
33553
+ {
33554
+ visitorTransactionId: payload._id.toString(),
33555
+ module: "visitors",
33556
+ screen: "/(user)/visitor-management",
33557
+ params: {
33558
+ id: payload._id.toString()
33559
+ }
33560
+ },
33561
+ true,
33562
+ "iservice365-ma-mobile-app"
33563
+ );
33564
+ }
33565
+ };
33566
+
33397
33567
  // src/services/visitor-transaction.service.ts
33398
33568
  function useVisitorTransactionService() {
33399
33569
  const MailerConfig = {
@@ -33432,6 +33602,7 @@ function useVisitorTransactionService() {
33432
33602
  getBlocklistedVehicleByPlateNumber: _getBlocklistedVehicleByPlateNumber
33433
33603
  } = useVehicleRepo();
33434
33604
  const { getById: _getUnitById } = useBuildingUnitRepo();
33605
+ const { getUsersBySiteId } = useMemberRepo();
33435
33606
  function extractKeyId(item) {
33436
33607
  if (!item)
33437
33608
  return null;
@@ -33580,7 +33751,10 @@ function useVisitorTransactionService() {
33580
33751
  for (let i = 0; i < value.members.length; i += chunkSize) {
33581
33752
  const chunk = value.members.slice(i, i + chunkSize);
33582
33753
  for (const member of chunk) {
33583
- await KeyRepo.checkPassKeyAvailability(member.visitorPass, member.passKeys);
33754
+ await KeyRepo.checkPassKeyAvailability(
33755
+ member.visitorPass,
33756
+ member.passKeys
33757
+ );
33584
33758
  if (member.visitorPass && Array.isArray(member.visitorPass) && member.visitorPass.length > 0) {
33585
33759
  for (const vp of member.visitorPass) {
33586
33760
  try {
@@ -33869,6 +34043,28 @@ function useVisitorTransactionService() {
33869
34043
  }
33870
34044
  }
33871
34045
  console.log("Open barrier response:", openBarrier);
34046
+ const visitorTransaction = await _getVisitorTransactionById(
34047
+ id.toString()
34048
+ );
34049
+ if (!visitorTransaction) {
34050
+ throw new Error("Visitor transaction not found.");
34051
+ }
34052
+ if (value.checkOut && visitorTransaction.type === "guest" /* GUEST */) {
34053
+ const users = await getUsersBySiteId({
34054
+ status: "active",
34055
+ siteId: visitorTransaction.site.toString()
34056
+ });
34057
+ if (users?.length > 0) {
34058
+ const userIds = Array.from(
34059
+ new Set(users.map((item) => item.user.toString()))
34060
+ );
34061
+ NotificationService.invitedVisitorCheckOutForMa({
34062
+ to: userIds,
34063
+ name: visitorTransaction.name,
34064
+ _id: id.toString()
34065
+ });
34066
+ }
34067
+ }
33872
34068
  await session?.commitTransaction();
33873
34069
  return "Successfully updated visitor transaction.";
33874
34070
  } catch (error) {
@@ -41032,120 +41228,6 @@ function useBulletinBoardRepo() {
41032
41228
  // src/services/bulletin-board.service.ts
41033
41229
  import { useAtlas as useAtlas68, NotFoundError as NotFoundError30 } from "@7365admin1/node-server-utils";
41034
41230
  import { ObjectId as ObjectId85 } from "mongodb";
41035
-
41036
- // src/services/notification.service.ts
41037
- import { sendExpoPushNotifications } from "iservice365-expo-notifications";
41038
-
41039
- // src/repositories/push-token.repository.ts
41040
- var PushTokenRepo = class {
41041
- static collection() {
41042
- return getDB().collection("push_tokens");
41043
- }
41044
- static async createIndexes() {
41045
- await Promise.all([
41046
- this.collection().createIndex({ token: 1 }, { unique: true }),
41047
- this.collection().createIndex({ userId: 1, platform: 1 }),
41048
- this.collection().createIndex({ siteId: 1 })
41049
- ]);
41050
- }
41051
- static async upsert(userId, token, platform, siteId, projectId, appSlug) {
41052
- const now = /* @__PURE__ */ new Date();
41053
- const p = platform;
41054
- const existing = await this.collection().findOne({ token });
41055
- if (existing) {
41056
- await this.collection().updateOne(
41057
- { token },
41058
- {
41059
- $set: {
41060
- userId,
41061
- platform: p,
41062
- siteId,
41063
- projectId,
41064
- appSlug,
41065
- updatedAt: now
41066
- }
41067
- }
41068
- );
41069
- return;
41070
- }
41071
- await this.collection().deleteMany({ userId, platform: p });
41072
- await this.collection().insertOne({
41073
- userId,
41074
- siteId,
41075
- token,
41076
- platform: p,
41077
- projectId,
41078
- appSlug,
41079
- createdAt: now,
41080
- updatedAt: now
41081
- });
41082
- }
41083
- static async remove(token) {
41084
- await this.collection().deleteMany({ token });
41085
- }
41086
- static async findTokensByUserIds(userIds, appSlug) {
41087
- const docs = await this.collection().find({ userId: { $in: userIds }, appSlug: { $eq: appSlug } }).toArray();
41088
- return docs.map((d) => d.token);
41089
- }
41090
- };
41091
-
41092
- // src/services/notification.service.ts
41093
- function toStringArray(recipient) {
41094
- const arr = Array.isArray(recipient) ? recipient : [recipient];
41095
- return arr.map((r) => r.toString());
41096
- }
41097
- async function send(userIds, title, body, data, appSlug) {
41098
- try {
41099
- const tokens = Array.from(
41100
- new Set(await PushTokenRepo.findTokensByUserIds(userIds, appSlug))
41101
- );
41102
- if (!tokens.length)
41103
- return;
41104
- for (const token of tokens) {
41105
- await sendExpoPushNotifications([token], { title, body, data });
41106
- }
41107
- } catch (error) {
41108
- console.warn("[NotificationService]", error);
41109
- }
41110
- }
41111
- var NotificationService = class {
41112
- static async bulletinBoardCreated(payload) {
41113
- await send(
41114
- toStringArray(payload.to),
41115
- "Bulletin Board",
41116
- `There is new ${payload.status} bulletin board.`,
41117
- {
41118
- bulletinId: payload.bulletinId.toString(),
41119
- status: payload.status,
41120
- module: "feedback",
41121
- screen: "/(user)/bulletinInfo",
41122
- params: {
41123
- id: payload.bulletinId.toString()
41124
- }
41125
- },
41126
- "iservice365-resident-mobile-app"
41127
- );
41128
- }
41129
- static async prelovedMarketplacePostCreation(payload) {
41130
- await send(
41131
- toStringArray(payload.to),
41132
- "Preloved Marketplace",
41133
- `New preloved marketplace post added.`,
41134
- {
41135
- prelovedId: payload.prelovedId.toString(),
41136
- status: payload.status,
41137
- module: "prelovedMarketplace",
41138
- screen: "/(user)/(marketplace)/prelovedPostInfo",
41139
- params: {
41140
- id: payload.prelovedId.toString()
41141
- }
41142
- },
41143
- "iservice365-resident-mobile-app"
41144
- );
41145
- }
41146
- };
41147
-
41148
- // src/services/bulletin-board.service.ts
41149
41231
  function useBulletinBoardService() {
41150
41232
  const {
41151
41233
  add: _add,
@@ -41212,6 +41294,12 @@ function useBulletinBoardService() {
41212
41294
  status: bulletinBoardStatus
41213
41295
  });
41214
41296
  }
41297
+ NotificationService.bulletinBoardCreatedForMA({
41298
+ to: userIds,
41299
+ bulletinId: bulletinBoardId,
41300
+ subject: "Bulletin Board",
41301
+ status: bulletinBoardStatus
41302
+ });
41215
41303
  }
41216
41304
  await session?.commitTransaction();
41217
41305
  return "Successfully added bulletin board.";
@@ -43174,11 +43262,27 @@ function useEventManagementService() {
43174
43262
  updateEventManagementById: _updateEventManagementById,
43175
43263
  processCompletedEvents: _processCompletedEvents
43176
43264
  } = useEventManagementRepo();
43265
+ const { getUsersBySiteId } = useMemberRepo();
43177
43266
  async function add(value) {
43178
43267
  const session = useAtlas74.getClient()?.startSession();
43179
43268
  try {
43180
43269
  session?.startTransaction();
43181
- await _add(value, session);
43270
+ const response = await _add(value, session);
43271
+ console.log("response", response);
43272
+ const users = await getUsersBySiteId({
43273
+ status: "active",
43274
+ siteId: value.site
43275
+ });
43276
+ if (users?.length > 0) {
43277
+ const userIds = Array.from(
43278
+ new Set(users.map((item) => item.user.toString()))
43279
+ );
43280
+ NotificationService.eventCreatedForMA({
43281
+ to: userIds,
43282
+ eventId: response,
43283
+ status: value.status
43284
+ });
43285
+ }
43182
43286
  await session?.commitTransaction();
43183
43287
  return "Successfully added event.";
43184
43288
  } catch (error) {
@@ -56685,73 +56789,6 @@ var Period = /* @__PURE__ */ ((Period2) => {
56685
56789
  Period2["THIS_MONTH"] = "thisMonth";
56686
56790
  return Period2;
56687
56791
  })(Period || {});
56688
- function getPeriodRangeWithPrevious(period) {
56689
- const now = /* @__PURE__ */ new Date();
56690
- let currentStart = /* @__PURE__ */ new Date();
56691
- let currentEnd = /* @__PURE__ */ new Date();
56692
- let previousStart = /* @__PURE__ */ new Date();
56693
- let previousEnd = /* @__PURE__ */ new Date();
56694
- if (period === "today" /* TODAY */) {
56695
- currentStart.setHours(0, 0, 0, 0);
56696
- currentEnd.setHours(23, 59, 59, 999);
56697
- previousStart = new Date(currentStart);
56698
- previousStart.setDate(previousStart.getDate() - 1);
56699
- previousEnd = new Date(currentEnd);
56700
- previousEnd.setDate(previousEnd.getDate() - 1);
56701
- } else if (period === "thisWeek" /* THIS_WEEK */) {
56702
- const day = now.getDay();
56703
- const diffToMonday = day === 0 ? -6 : 1 - day;
56704
- currentStart = new Date(now);
56705
- currentStart.setDate(now.getDate() + diffToMonday);
56706
- currentStart.setHours(0, 0, 0, 0);
56707
- currentEnd = new Date(currentStart);
56708
- currentEnd.setDate(currentStart.getDate() + 6);
56709
- currentEnd.setHours(23, 59, 59, 999);
56710
- previousStart = new Date(currentStart);
56711
- previousStart.setDate(previousStart.getDate() - 7);
56712
- previousEnd = new Date(currentEnd);
56713
- previousEnd.setDate(previousEnd.getDate() - 7);
56714
- } else if (period === "thisMonth" /* THIS_MONTH */) {
56715
- currentStart = new Date(now.getFullYear(), now.getMonth(), 1);
56716
- currentEnd = new Date(
56717
- now.getFullYear(),
56718
- now.getMonth() + 1,
56719
- 0,
56720
- 23,
56721
- 59,
56722
- 59,
56723
- 999
56724
- );
56725
- previousStart = new Date(now.getFullYear(), now.getMonth() - 1, 1);
56726
- previousEnd = new Date(
56727
- now.getFullYear(),
56728
- now.getMonth(),
56729
- 0,
56730
- 23,
56731
- 59,
56732
- 59,
56733
- 999
56734
- );
56735
- } else {
56736
- throw new BadRequestError182("Invalid period.");
56737
- }
56738
- return {
56739
- current: {
56740
- start: currentStart.toISOString(),
56741
- end: currentEnd.toISOString()
56742
- },
56743
- previous: {
56744
- start: previousStart.toISOString(),
56745
- end: previousEnd.toISOString()
56746
- }
56747
- };
56748
- }
56749
- function calculatePercentage(current, previous) {
56750
- if (previous === 0) {
56751
- return current === 0 ? 0 : 100;
56752
- }
56753
- return Number(((current - previous) / previous * 100).toFixed(2));
56754
- }
56755
56792
  function useNewDashboardRepo() {
56756
56793
  const db = useAtlas100.getDb();
56757
56794
  if (!db) {
@@ -57260,7 +57297,8 @@ function useNewDashboardRepo() {
57260
57297
  currentlyOnSiteCount,
57261
57298
  facilityReport,
57262
57299
  yesterdayFacilityReport,
57263
- todayFacilityReport
57300
+ todayFacilityReport,
57301
+ workOrderStatusReport
57264
57302
  ] = await Promise.all([
57265
57303
  workOrderCollection.aggregate([
57266
57304
  {
@@ -57450,6 +57488,20 @@ function useNewDashboardRepo() {
57450
57488
  }
57451
57489
  },
57452
57490
  { $count: "count" }
57491
+ ]).toArray(),
57492
+ workOrderCollection.aggregate([
57493
+ {
57494
+ $match: {
57495
+ site: { $in: [siteIdObj, siteId] },
57496
+ createdAt: periodRange
57497
+ }
57498
+ },
57499
+ {
57500
+ $group: {
57501
+ _id: "$status",
57502
+ count: { $sum: 1 }
57503
+ }
57504
+ }
57453
57505
  ]).toArray()
57454
57506
  ]);
57455
57507
  const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
@@ -57458,6 +57510,23 @@ function useNewDashboardRepo() {
57458
57510
  ongoing: [],
57459
57511
  waitingApproval: []
57460
57512
  };
57513
+ const workOrderStatus = {
57514
+ pending: 0,
57515
+ inProgress: 0,
57516
+ completed: 0
57517
+ };
57518
+ for (const item of workOrderStatusReport || []) {
57519
+ const rawStatus = String(item._id || "").toLowerCase().trim();
57520
+ if (rawStatus === "to-do" || rawStatus === "for-review") {
57521
+ workOrderStatus.pending += item.count || 0;
57522
+ } else if (rawStatus === "in-progress") {
57523
+ workOrderStatus.inProgress += item.count || 0;
57524
+ } else if (rawStatus === "completed") {
57525
+ workOrderStatus.completed += item.count || 0;
57526
+ } else {
57527
+ workOrderStatus.pending += item.count || 0;
57528
+ }
57529
+ }
57461
57530
  const data = {
57462
57531
  openWorkOrder: {
57463
57532
  count: wFacet.total[0]?.count ?? 0,
@@ -57492,6 +57561,7 @@ function useNewDashboardRepo() {
57492
57561
  yesterdayFacilityReport[0]?.count ?? 0
57493
57562
  )
57494
57563
  },
57564
+ workOrderStatus,
57495
57565
  upcomingEvents,
57496
57566
  todayReminders,
57497
57567
  todayAttentions
@@ -66191,7 +66261,8 @@ var schemaUpdateChatPreloved = Joi141.object({
66191
66261
  reactions: Joi141.string().optional().allow("", null)
66192
66262
  });
66193
66263
  var schemaChatPreloved = Joi141.object({
66194
- channelId: Joi141.string().hex().length(24).required(),
66264
+ channelId: Joi141.string().hex().length(24).optional().allow("", null),
66265
+ receiverId: Joi141.string().hex().length(24).optional().allow("", null),
66195
66266
  senderId: Joi141.string().hex().length(24).required(),
66196
66267
  postId: Joi141.string().hex().length(24).optional().allow("", null),
66197
66268
  message: schemaMessage.required(),
@@ -66238,7 +66309,7 @@ function MChatPreloved(value) {
66238
66309
  }
66239
66310
  return {
66240
66311
  _id: new ObjectId145(),
66241
- channelId: value.channelId ?? "",
66312
+ channelId: value.channelId ?? null,
66242
66313
  senderId: value.senderId ?? "",
66243
66314
  postId: value.postId ?? null,
66244
66315
  message: {
@@ -66477,7 +66548,130 @@ function useChannelPrelovedRepo() {
66477
66548
  throw error;
66478
66549
  }
66479
66550
  }
66480
- return { add, getByParticipants, getChannelMessages };
66551
+ async function getChatLists(currentUserId, page = 1, limit = 10, search) {
66552
+ const normalizedPage = page > 0 ? page - 1 : 0;
66553
+ const normalizedLimit = limit || 10;
66554
+ const _currentUserId = new ObjectId148(currentUserId);
66555
+ const escapedSearch = search ? search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") : null;
66556
+ const pipeline = [
66557
+ {
66558
+ $match: {
66559
+ $or: [{ receiverId: _currentUserId }, { senderId: _currentUserId }]
66560
+ }
66561
+ },
66562
+ {
66563
+ $lookup: {
66564
+ from: "users",
66565
+ localField: "senderId",
66566
+ foreignField: "_id",
66567
+ pipeline: [
66568
+ {
66569
+ $project: {
66570
+ name: 1,
66571
+ profile: 1,
66572
+ type: 1
66573
+ }
66574
+ }
66575
+ ],
66576
+ as: "senderId"
66577
+ }
66578
+ },
66579
+ { $unwind: { path: "$senderId", preserveNullAndEmptyArrays: true } },
66580
+ {
66581
+ $lookup: {
66582
+ from: "post-preloved",
66583
+ localField: "postId",
66584
+ foreignField: "_id",
66585
+ pipeline: [
66586
+ {
66587
+ $project: {
66588
+ title: 1,
66589
+ description: 1,
66590
+ attachments: 1,
66591
+ price: 1,
66592
+ status: 1,
66593
+ createdBy: 1,
66594
+ reserverId: 1
66595
+ }
66596
+ }
66597
+ ],
66598
+ as: "postDetails"
66599
+ }
66600
+ },
66601
+ { $unwind: { path: "$postDetails", preserveNullAndEmptyArrays: true } },
66602
+ ...escapedSearch ? [
66603
+ {
66604
+ $match: {
66605
+ $or: [
66606
+ {
66607
+ "senderId.name": {
66608
+ $regex: new RegExp(escapedSearch, "i")
66609
+ }
66610
+ },
66611
+ {
66612
+ "postDetails.title": {
66613
+ $regex: new RegExp(escapedSearch, "i")
66614
+ }
66615
+ }
66616
+ ]
66617
+ }
66618
+ }
66619
+ ] : [],
66620
+ {
66621
+ $lookup: {
66622
+ from: "chat-preloved",
66623
+ localField: "_id",
66624
+ foreignField: "channelId",
66625
+ pipeline: [
66626
+ { $match: { deletedAt: null } },
66627
+ { $sort: { createdAt: -1 } },
66628
+ { $limit: 1 }
66629
+ ],
66630
+ as: "latestChat"
66631
+ }
66632
+ },
66633
+ { $unwind: { path: "$latestChat", preserveNullAndEmptyArrays: true } },
66634
+ { $addFields: { lastMessageDate: "$latestChat.createdAt" } },
66635
+ {
66636
+ $lookup: {
66637
+ from: "bid-preloved",
66638
+ localField: "postId",
66639
+ foreignField: "postId",
66640
+ pipeline: [
66641
+ { $sort: { createdAt: -1 } },
66642
+ { $limit: 1 },
66643
+ { $project: { price: 1, message: 1, status: 1, type: 1 } }
66644
+ ],
66645
+ as: "latestBidDetails"
66646
+ }
66647
+ },
66648
+ {
66649
+ $unwind: {
66650
+ path: "$latestBidDetails",
66651
+ preserveNullAndEmptyArrays: true
66652
+ }
66653
+ },
66654
+ { $sort: { lastMessageDate: -1 } },
66655
+ {
66656
+ $facet: {
66657
+ totalCount: [{ $count: "count" }],
66658
+ items: [
66659
+ { $skip: normalizedPage * normalizedLimit },
66660
+ { $limit: normalizedLimit }
66661
+ ]
66662
+ }
66663
+ }
66664
+ ];
66665
+ try {
66666
+ const result = await collection.aggregate(pipeline).toArray();
66667
+ const totalCount = result[0].totalCount[0]?.count ?? 0;
66668
+ const items = result[0].items;
66669
+ return paginate63(items, normalizedPage, normalizedLimit, totalCount);
66670
+ } catch (error) {
66671
+ throw error;
66672
+ }
66673
+ }
66674
+ return { add, getByParticipants, getChatLists, getChannelMessages };
66481
66675
  }
66482
66676
 
66483
66677
  // src/services/chat-preloved.service.ts
@@ -66595,7 +66789,12 @@ function useChatPrelovedController() {
66595
66789
  import { BadRequestError as BadRequestError223, logger as logger193 } from "@7365admin1/node-server-utils";
66596
66790
  import Joi144 from "joi";
66597
66791
  function useChannelPrelovedController() {
66598
- const { add: _add, getChannelMessages: _getChannelMessages } = useChannelPrelovedRepo();
66792
+ const {
66793
+ add: _add,
66794
+ getByParticipants: _getByParticipants,
66795
+ getChatLists: _getChatLists,
66796
+ getChannelMessages: _getChannelMessages
66797
+ } = useChannelPrelovedRepo();
66599
66798
  async function add(req, res, next) {
66600
66799
  const { error, value } = schemaChannelPreloved.validate(req.body, {
66601
66800
  abortEarly: false
@@ -66632,9 +66831,7 @@ function useChannelPrelovedController() {
66632
66831
  next(new BadRequestError223(paramError.message));
66633
66832
  return;
66634
66833
  }
66635
- const { error: queryError, value: query } = querySchema.validate(
66636
- req.query
66637
- );
66834
+ const { error: queryError, value: query } = querySchema.validate(req.query);
66638
66835
  if (queryError) {
66639
66836
  logger193.log({ level: "error", message: queryError.message });
66640
66837
  next(new BadRequestError223(queryError.message));
@@ -66654,7 +66851,57 @@ function useChannelPrelovedController() {
66654
66851
  next(error);
66655
66852
  }
66656
66853
  }
66657
- return { add, getChannelMessages };
66854
+ async function getChannel(req, res, next) {
66855
+ const querySchema = Joi144.object({
66856
+ postId: Joi144.string().hex().length(24).required(),
66857
+ receiverId: Joi144.string().hex().length(24).required(),
66858
+ senderId: Joi144.string().hex().length(24).required()
66859
+ });
66860
+ const { error, value } = querySchema.validate(req.query);
66861
+ if (error) {
66862
+ logger193.log({ level: "error", message: error.message });
66863
+ next(new BadRequestError223(error.message));
66864
+ return;
66865
+ }
66866
+ try {
66867
+ const data = await _getByParticipants(
66868
+ value.senderId,
66869
+ value.receiverId,
66870
+ value.postId
66871
+ );
66872
+ res.status(200).json(data);
66873
+ } catch (error2) {
66874
+ logger193.log({ level: "error", message: error2.message });
66875
+ next(error2);
66876
+ }
66877
+ }
66878
+ async function getChatLists(req, res, next) {
66879
+ const querySchema = Joi144.object({
66880
+ currentUserId: Joi144.string().hex().length(24).required(),
66881
+ page: Joi144.number().integer().min(1).default(1),
66882
+ limit: Joi144.number().integer().min(1).max(100).default(10),
66883
+ search: Joi144.string().optional().allow("", null)
66884
+ });
66885
+ const { error, value } = querySchema.validate(req.query);
66886
+ if (error) {
66887
+ logger193.log({ level: "error", message: error.message });
66888
+ next(new BadRequestError223(error.message));
66889
+ return;
66890
+ }
66891
+ try {
66892
+ const data = await _getChatLists(
66893
+ value.currentUserId,
66894
+ value.page,
66895
+ value.limit,
66896
+ value.search || void 0
66897
+ );
66898
+ res.status(200).json(data);
66899
+ } catch (error2) {
66900
+ logger193.log({ level: "error", message: error2.message });
66901
+ next(error2);
66902
+ }
66903
+ }
66904
+ return { add, getChannel, getChatLists, getChannelMessages };
66658
66905
  }
66659
66906
 
66660
66907
  // src/models/online-forms-v2.model.ts
@@ -66887,7 +67134,23 @@ function useFormEntryRepo() {
66887
67134
  { $match: query },
66888
67135
  { $sort: sort },
66889
67136
  { $skip: page * limit },
66890
- { $limit: limit }
67137
+ { $limit: limit },
67138
+ {
67139
+ $lookup: {
67140
+ from: "users",
67141
+ localField: "userId",
67142
+ foreignField: "_id",
67143
+ as: "user",
67144
+ pipeline: [{ $project: { name: 1 } }]
67145
+ }
67146
+ },
67147
+ { $unwind: { path: "$user", preserveNullAndEmptyArrays: true } },
67148
+ {
67149
+ $addFields: {
67150
+ name: { $ifNull: ["$user.name", "$name"] }
67151
+ }
67152
+ },
67153
+ { $project: { user: 0 } }
66891
67154
  ]).toArray();
66892
67155
  const length = await collection.countDocuments(query);
66893
67156
  const data = paginate64(items, page, limit, length);
@@ -67657,7 +67920,6 @@ export {
67657
67920
  building_units_namespace_collection,
67658
67921
  buildings_namespace_collection,
67659
67922
  bulletin_boards_namespace_collection,
67660
- calculatePercentage,
67661
67923
  chatSchema,
67662
67924
  createManpowerRemarksDaily,
67663
67925
  customerSchema,
@@ -67668,7 +67930,6 @@ export {
67668
67930
  feedbacks2_namespace_collection,
67669
67931
  feedbacks_namespace_collection,
67670
67932
  formatDahuaDate,
67671
- getPeriodRangeWithPrevious,
67672
67933
  guests_namespace_collection,
67673
67934
  incidentReportLog,
67674
67935
  incidents_namespace_collection,