@7365admin1/core 2.47.0 → 2.49.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.js CHANGED
@@ -452,6 +452,7 @@ __export(src_exports, {
452
452
  vehicles_namespace_collection: () => vehicles_namespace_collection,
453
453
  visitors_namespace_collection: () => visitors_namespace_collection,
454
454
  workOrderSchema: () => workOrderSchema,
455
+ work_orders2_namespace_collection: () => work_orders2_namespace_collection,
455
456
  work_orders_namespace_collection: () => work_orders_namespace_collection
456
457
  });
457
458
  module.exports = __toCommonJS(src_exports);
@@ -1363,12 +1364,16 @@ function MWorkOrder(value) {
1363
1364
  // src/repositories/work-order.repo.ts
1364
1365
  var import_node_server_utils7 = require("@7365admin1/node-server-utils");
1365
1366
  var work_orders_namespace_collection = "work-orders";
1367
+ var work_orders2_namespace_collection = "work-orders2";
1366
1368
  function useWorkOrderRepo() {
1367
1369
  const db = import_node_server_utils7.useAtlas.getDb();
1368
1370
  if (!db) {
1369
1371
  throw new import_node_server_utils7.InternalServerError("Unable to connect to server.");
1370
1372
  }
1371
1373
  const collection = db.collection(work_orders_namespace_collection);
1374
+ const workOrders2Collection = db.collection(
1375
+ work_orders2_namespace_collection
1376
+ );
1372
1377
  async function createIndex() {
1373
1378
  try {
1374
1379
  await collection.createIndexes([
@@ -1400,6 +1405,12 @@ function useWorkOrderRepo() {
1400
1405
  const { delNamespace, setCache, getCache, delCache } = (0, import_node_server_utils7.useCache)(
1401
1406
  work_orders_namespace_collection
1402
1407
  );
1408
+ const {
1409
+ delNamespace: delNamespaceWorkOrders2,
1410
+ setCache: setCacheWorkOrders2,
1411
+ getCache: getCacheWorkOrders2,
1412
+ delCache: delCacheWorkOrders2
1413
+ } = (0, import_node_server_utils7.useCache)(work_orders2_namespace_collection);
1403
1414
  const { delNamespace: _delDashboardNameSpace } = (0, import_node_server_utils7.useCache)("dashboard");
1404
1415
  async function createWorkOrder(value, session) {
1405
1416
  try {
@@ -1801,7 +1812,7 @@ function useWorkOrderRepo() {
1801
1812
  updatedAt: /* @__PURE__ */ new Date(),
1802
1813
  deletedAt: /* @__PURE__ */ new Date()
1803
1814
  };
1804
- const res = await collection.updateOne(
1815
+ const res = await workOrders2Collection.updateOne(
1805
1816
  { _id },
1806
1817
  { $set: updateValue },
1807
1818
  { session }
@@ -1809,13 +1820,13 @@ function useWorkOrderRepo() {
1809
1820
  if (res.modifiedCount === 0) {
1810
1821
  throw new import_node_server_utils7.InternalServerError("Unable to delete work order.");
1811
1822
  }
1812
- delNamespace().then(() => {
1823
+ delNamespaceWorkOrders2().then(() => {
1813
1824
  import_node_server_utils7.logger.info(
1814
- `Cache cleared for namespace: ${work_orders_namespace_collection}`
1825
+ `Cache cleared for namespace: ${work_orders2_namespace_collection}`
1815
1826
  );
1816
1827
  }).catch((err) => {
1817
1828
  import_node_server_utils7.logger.error(
1818
- `Failed to clear cache for namespace: ${work_orders_namespace_collection}`,
1829
+ `Failed to clear cache for namespace: ${work_orders2_namespace_collection}`,
1819
1830
  err
1820
1831
  );
1821
1832
  });
@@ -2445,7 +2456,7 @@ function useOccurrenceEntryRepo() {
2445
2456
  import_node_server_utils8.logger.info(`Cache hit for key: ${cacheKey}`);
2446
2457
  return cached;
2447
2458
  }
2448
- const bookId = new import_mongodb7.ObjectId(dailyOccurrenceBookId);
2459
+ const bookId = typeof dailyOccurrenceBookId === "string" ? new import_mongodb7.ObjectId(dailyOccurrenceBookId) : dailyOccurrenceBookId;
2449
2460
  const data = await collection.findOne(
2450
2461
  { dailyOccurrenceBookId: bookId },
2451
2462
  {
@@ -2460,6 +2471,16 @@ function useOccurrenceEntryRepo() {
2460
2471
  });
2461
2472
  return serialNumber;
2462
2473
  }
2474
+ async function getLatestSerialNumberInGroup(bookId, group) {
2475
+ const latestEntry = await collection.findOne(
2476
+ {
2477
+ dailyOccurrenceBookId: bookId,
2478
+ serialNumber: { $regex: `^${group}(\\.|$)` }
2479
+ },
2480
+ { sort: { serialNumber: -1 } }
2481
+ );
2482
+ return latestEntry ? Number(latestEntry.serialNumber) : group;
2483
+ }
2463
2484
  async function updateUserNameBySignatureId(_id, value, session) {
2464
2485
  try {
2465
2486
  const updateValue = {
@@ -2495,7 +2516,8 @@ function useOccurrenceEntryRepo() {
2495
2516
  createIndexes,
2496
2517
  createTextIndex,
2497
2518
  getLatestSerialNumber,
2498
- updateOccurrenceEntryByBookId
2519
+ updateOccurrenceEntryByBookId,
2520
+ getLatestSerialNumberInGroup
2499
2521
  };
2500
2522
  }
2501
2523
 
@@ -3155,6 +3177,7 @@ var APP_POOL_MAINTENANCE = process.env.APP_POOL_MAINTENANCE ?? "http://localhost
3155
3177
  var ENCRYPTION_KEY = process.env.ENCRYPTION_KEY ?? "";
3156
3178
  var DOMAIN = process.env.DOMAIN ?? "localhost";
3157
3179
  var OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
3180
+ var STORAGE_API = process.env.STORAGE_API;
3158
3181
 
3159
3182
  // src/services/auth.service.ts
3160
3183
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
@@ -5502,6 +5525,39 @@ function useVerificationRepoV2() {
5502
5525
  throw new import_node_server_utils20.InternalServerError("Error updating verification status.");
5503
5526
  }
5504
5527
  }
5528
+ async function countPendingOrgInvites(orgId) {
5529
+ try {
5530
+ orgId = new import_mongodb18.ObjectId(orgId);
5531
+ } catch (error) {
5532
+ throw new import_node_server_utils20.BadRequestError("Invalid organization ID format.");
5533
+ }
5534
+ const query = {
5535
+ status: "pending" /* PENDING */,
5536
+ type: { $in: ["user-invite", "member-invite"] },
5537
+ "metadata.org": orgId
5538
+ };
5539
+ const cacheKey = (0, import_node_server_utils20.makeCacheKey)(namespace_collection, {
5540
+ status: "pending" /* PENDING */,
5541
+ type: JSON.stringify(["user-invite", "member-invite"]),
5542
+ org: orgId.toString()
5543
+ });
5544
+ const cachedData = await getCache(cacheKey);
5545
+ if (typeof cachedData === "number") {
5546
+ import_node_server_utils20.logger.info(`Cache hit for key: ${cacheKey}`);
5547
+ return cachedData;
5548
+ }
5549
+ try {
5550
+ const count = await collection.countDocuments(query);
5551
+ setCache(cacheKey, count, 15 * 60).then(() => {
5552
+ import_node_server_utils20.logger.info(`Cache set for key: ${cacheKey}`);
5553
+ }).catch((err) => {
5554
+ import_node_server_utils20.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
5555
+ });
5556
+ return count;
5557
+ } catch (error) {
5558
+ throw new import_node_server_utils20.InternalServerError("Failed to count pending invitations.");
5559
+ }
5560
+ }
5505
5561
  return {
5506
5562
  createIndex,
5507
5563
  createTextIndex,
@@ -5510,7 +5566,8 @@ function useVerificationRepoV2() {
5510
5566
  getByVerificationCode,
5511
5567
  getVerificationById,
5512
5568
  getVerifications,
5513
- updateStatusById
5569
+ updateStatusById,
5570
+ countPendingOrgInvites
5514
5571
  };
5515
5572
  }
5516
5573
 
@@ -5588,6 +5645,46 @@ function useVerificationService() {
5588
5645
  throw error;
5589
5646
  }
5590
5647
  }
5648
+ async function createSimpleUserInvite({
5649
+ email,
5650
+ metadata
5651
+ }) {
5652
+ const type = "user-invite";
5653
+ const value = {
5654
+ type,
5655
+ email,
5656
+ metadata,
5657
+ expireAt: new Date(
5658
+ (/* @__PURE__ */ new Date()).getTime() + 72 * 60 * 60 * 1e3
5659
+ ).toISOString(),
5660
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
5661
+ };
5662
+ if (value.metadata?.org) {
5663
+ await getOrgById(value.metadata?.org);
5664
+ }
5665
+ if (value.metadata?.siteId) {
5666
+ await getSiteById(value.metadata?.siteId);
5667
+ }
5668
+ const res = await add(value);
5669
+ const dir = __dirname;
5670
+ const filePath = (0, import_node_server_utils21.getDirectory)(dir, "./public/handlebars/user-invite");
5671
+ const link = `${APP_MAIN}/verify/invitation/${res}`;
5672
+ const emailContent = (0, import_node_server_utils21.compileHandlebar)({
5673
+ context: {
5674
+ email,
5675
+ validity: VERIFICATION_USER_INVITE_DURATION,
5676
+ link
5677
+ },
5678
+ filePath
5679
+ });
5680
+ mailer.sendMail({
5681
+ to: email,
5682
+ subject: "User Invite",
5683
+ html: emailContent,
5684
+ sender: "iService365"
5685
+ });
5686
+ return res;
5687
+ }
5591
5688
  const {
5592
5689
  add: _add,
5593
5690
  updateVerificationStatusById: _updateVerificationStatusById,
@@ -5881,7 +5978,8 @@ function useVerificationService() {
5881
5978
  cancelUserInvitation,
5882
5979
  updateStatusById,
5883
5980
  signUp,
5884
- checkExpiredInvitation
5981
+ checkExpiredInvitation,
5982
+ createSimpleUserInvite
5885
5983
  };
5886
5984
  }
5887
5985
 
@@ -7102,7 +7200,16 @@ function useUserController() {
7102
7200
  async function updateUserFieldById(req, res, next) {
7103
7201
  const validation = import_joi13.default.object({
7104
7202
  _id: import_joi13.default.string().hex().required(),
7105
- field: import_joi13.default.string().valid("name", "email", "contact", "nric", "dateOfBirth", "profile", "gender", "defaultOrg").required(),
7203
+ field: import_joi13.default.string().valid(
7204
+ "name",
7205
+ "email",
7206
+ "contact",
7207
+ "nric",
7208
+ "dateOfBirth",
7209
+ "profile",
7210
+ "gender",
7211
+ "defaultOrg"
7212
+ ).required(),
7106
7213
  value: import_joi13.default.when("field", {
7107
7214
  switch: [
7108
7215
  { is: "email", then: import_joi13.default.string().email().required() },
@@ -7706,6 +7813,7 @@ var import_joi16 = __toESM(require("joi"));
7706
7813
  function useVerificationController() {
7707
7814
  const {
7708
7815
  createUserInvite: _createUserInvite,
7816
+ createSimpleUserInvite: _createSimpleUserInvite,
7709
7817
  createServiceProviderInvite: _createServiceProviderInvite,
7710
7818
  createForgetPassword: _createForgetPassword,
7711
7819
  verify: _verify,
@@ -7756,6 +7864,58 @@ function useVerificationController() {
7756
7864
  return;
7757
7865
  }
7758
7866
  }
7867
+ async function createSimpleUserInvite(req, res, next) {
7868
+ const payload = { ...req.body };
7869
+ const validation = import_joi16.default.object({
7870
+ email: import_joi16.default.string().email().required(),
7871
+ app: import_joi16.default.string().optional().allow("", null),
7872
+ role: import_joi16.default.string().hex().optional().allow("", null),
7873
+ name: import_joi16.default.string().optional().allow("", null),
7874
+ org: import_joi16.default.string().hex().optional().allow("", null),
7875
+ siteId: import_joi16.default.string().hex().optional().allow("", null),
7876
+ siteName: import_joi16.default.string().optional().allow("", null)
7877
+ });
7878
+ const { error } = validation.validate(payload);
7879
+ if (error) {
7880
+ import_node_server_utils32.logger.log({
7881
+ level: "error",
7882
+ message: `${error.message}`
7883
+ });
7884
+ next(new import_node_server_utils32.BadRequestError(error.message));
7885
+ return;
7886
+ }
7887
+ const email = req.body.email ?? "";
7888
+ const app = req.body.app ?? "";
7889
+ const role = req.body.role ?? "";
7890
+ const name = req.body.name ?? "";
7891
+ const org = req.body.org ?? "";
7892
+ const siteId = req.body.siteId ?? "";
7893
+ const siteName = req.body.siteName ?? "";
7894
+ try {
7895
+ await _createSimpleUserInvite({
7896
+ email,
7897
+ metadata: {
7898
+ app,
7899
+ role,
7900
+ name,
7901
+ org,
7902
+ siteId,
7903
+ siteName
7904
+ }
7905
+ });
7906
+ res.status(201).json({
7907
+ message: "Successfully invited user."
7908
+ });
7909
+ return;
7910
+ } catch (error2) {
7911
+ import_node_server_utils32.logger.log({
7912
+ level: "error",
7913
+ message: `${error2.message}`
7914
+ });
7915
+ next(error2);
7916
+ return;
7917
+ }
7918
+ }
7759
7919
  async function createServiceProviderInvite(req, res, next) {
7760
7920
  const payload = req.body;
7761
7921
  const validation = import_joi16.default.object({
@@ -7897,7 +8057,8 @@ function useVerificationController() {
7897
8057
  createServiceProviderInvite,
7898
8058
  createForgetPassword,
7899
8059
  verify,
7900
- cancelUserInvitation
8060
+ cancelUserInvitation,
8061
+ createSimpleUserInvite
7901
8062
  };
7902
8063
  }
7903
8064
 
@@ -13582,11 +13743,18 @@ function useVisitorTransactionRepo() {
13582
13743
  );
13583
13744
  }
13584
13745
  }
13585
- async function add(value, session) {
13746
+ async function add(value, session, returnValue = false) {
13586
13747
  try {
13587
13748
  value = MVisitorTransaction(value);
13588
13749
  const res = await collection.insertOne(value, { session });
13589
- return res.insertedId;
13750
+ if (returnValue) {
13751
+ return {
13752
+ ...value,
13753
+ _id: res.insertedId
13754
+ };
13755
+ } else {
13756
+ return res.insertedId;
13757
+ }
13590
13758
  } catch (error) {
13591
13759
  console.log("Error in add visitor transaction:", error);
13592
13760
  const isDuplicated = error.message.includes("duplicate");
@@ -14917,7 +15085,11 @@ function usePersonRepo() {
14917
15085
  try {
14918
15086
  await collection.createIndexes([
14919
15087
  { key: { contact: 1 } },
14920
- { key: { nric: 1 } }
15088
+ { key: { nric: 1 } },
15089
+ { key: { user: 1 } },
15090
+ { key: { site: 1, status: 1 } },
15091
+ { key: { "plates.plateNumber": 1, status: 1 } },
15092
+ { key: { unit: 1, status: 1 } }
14921
15093
  ]);
14922
15094
  } catch (error) {
14923
15095
  throw new import_node_server_utils71.InternalServerError("Failed to create index on site people.");
@@ -16885,6 +17057,9 @@ function useVehicleService() {
16885
17057
  const _end = vehicle.end;
16886
17058
  const _recNo = plate.recNo;
16887
17059
  const _type = value.type ? value.type : plate.type;
17060
+ if (value.peopleId) {
17061
+ value.peopleId = new import_mongodb46.ObjectId(value.peopleId);
17062
+ }
16888
17063
  const { name, plateNumber, start, end, recNo, type, unit, site, ...rest } = value;
16889
17064
  const startDahua = value.start ? formatDahuaDate(new Date(value.start)) : formatDahuaDate(new Date(_start));
16890
17065
  const endDahua = value.end ? formatDahuaDate(new Date(value.end)) : formatDahuaDate(new Date(_end));
@@ -16948,6 +17123,17 @@ function useVehicleService() {
16948
17123
  }
16949
17124
  const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
16950
17125
  value.recNo = responseData.split("=")[1]?.trim();
17126
+ const normalizedPlateNumber = Array.isArray(plateNumber) ? plateNumber[0] : plateNumber;
17127
+ if (value.peopleId && value.recNo) {
17128
+ await _pushVehicleById(
17129
+ value.peopleId,
17130
+ {
17131
+ plateNumber: normalizedPlateNumber,
17132
+ recNo: value.recNo
17133
+ },
17134
+ session
17135
+ );
17136
+ }
16951
17137
  } else {
16952
17138
  const dahuaPayload = {
16953
17139
  host,
@@ -16961,6 +17147,17 @@ function useVehicleService() {
16961
17147
  owner: name ? name : _name
16962
17148
  };
16963
17149
  const dahuaResponse = await _updatePlateNumber(dahuaPayload);
17150
+ const normalizedPlateNumber = Array.isArray(plateNumber) ? plateNumber[0] : plateNumber;
17151
+ if (value.peopleId && value.recNo) {
17152
+ await _pushVehicleById(
17153
+ value.peopleId,
17154
+ {
17155
+ plateNumber: normalizedPlateNumber,
17156
+ recNo: _recNo
17157
+ },
17158
+ session
17159
+ );
17160
+ }
16964
17161
  if (dahuaResponse?.statusCode !== 200) {
16965
17162
  throw new import_node_server_utils74.BadRequestError(
16966
17163
  "Failed to update plate number to ANPR"
@@ -17155,7 +17352,7 @@ function useDahuaService() {
17155
17352
  const { createFile: _createFile } = useFileService();
17156
17353
  let currentTransactionId = null;
17157
17354
  let currentSnapshotField = null;
17158
- function useBufferQueue(boundary, site, gate, designation, host, username, password) {
17355
+ function useBufferQueue(boundary, site, gate, designation, host, username, password, onDetected) {
17159
17356
  const queue = [];
17160
17357
  let processing = false;
17161
17358
  let plateNumber = null;
@@ -17188,7 +17385,7 @@ function useDahuaService() {
17188
17385
  );
17189
17386
  streamRef.pause();
17190
17387
  }
17191
- processNext();
17388
+ processNext(onDetected);
17192
17389
  }
17193
17390
  function destroy() {
17194
17391
  queue.length = 0;
@@ -17204,30 +17401,30 @@ function useDahuaService() {
17204
17401
  `[${site}][${gate}] BufferQueue destroyed. Processed=${processedChunks}, Dropped=${droppedChunks}`
17205
17402
  );
17206
17403
  }
17207
- async function processNext() {
17404
+ async function processNext(onDetected2) {
17208
17405
  if (processing || queue.length === 0)
17209
17406
  return;
17210
17407
  processing = true;
17211
17408
  const buffer = queue.shift();
17212
17409
  try {
17213
- await handleBuffer(buffer);
17410
+ await handleBuffer(buffer, onDetected2);
17214
17411
  processedChunks++;
17215
17412
  if (queue.length <= RESUME_THRESHOLD && streamRef && streamRef.isPaused()) {
17216
17413
  loggerDahua.info(
17217
- `[${site}][${gate}] Queue at ${queue.length}/${MAX_QUEUE_SIZE}, resuming stream`
17414
+ `[${host}]Queue at ${queue.length}/${MAX_QUEUE_SIZE}, resuming stream`
17218
17415
  );
17219
17416
  streamRef.resume();
17220
17417
  }
17221
17418
  } catch (err) {
17222
- loggerDahua.error(`[${site}][${gate}] Error processing buffer:`, err);
17419
+ loggerDahua.error(`[${host}] Error processing buffer:`, err);
17223
17420
  } finally {
17224
17421
  processing = false;
17225
- processNext();
17422
+ processNext(onDetected2);
17226
17423
  }
17227
17424
  }
17228
- async function processVehicleTransaction() {
17425
+ async function processVehicleTransaction(onDetected2) {
17229
17426
  loggerDahua.info(
17230
- `[${site}][${gate}] Vehicle transaction: Plate=${plateNumber}, UTC=${UTCData}, UTCMs=${UTCMs}`
17427
+ `[${host}] Vehicle transaction: Plate=${plateNumber}, UTC=${UTCData}, UTCMs=${UTCMs}`
17231
17428
  );
17232
17429
  let org = "";
17233
17430
  try {
@@ -17235,7 +17432,7 @@ function useDahuaService() {
17235
17432
  org = theSite?.orgId.toString() || "unknown";
17236
17433
  } catch (error) {
17237
17434
  loggerDahua.error(
17238
- `[${site}][${gate}] Error fetching site for orgId:`,
17435
+ `[${host}] Error fetching site for orgId:`,
17239
17436
  error
17240
17437
  );
17241
17438
  }
@@ -17255,7 +17452,7 @@ function useDahuaService() {
17255
17452
  }
17256
17453
  } catch (error) {
17257
17454
  loggerDahua.error(
17258
- `[${site}][${gate}] Error closing existing open transaction:`,
17455
+ `[${host}] Error closing existing open transaction:`,
17259
17456
  error
17260
17457
  );
17261
17458
  }
@@ -17305,9 +17502,13 @@ function useDahuaService() {
17305
17502
  }
17306
17503
  try {
17307
17504
  await addPlateNumber(dahuaPayload);
17308
- const transactionId = await add(visitorTransaction);
17309
- currentTransactionId = transactionId.toString();
17505
+ const result = await add(visitorTransaction, void 0, true);
17506
+ const transactionId = result?._id;
17507
+ currentTransactionId = transactionId?.toString();
17310
17508
  currentSnapshotField = "snapshotEntryImage";
17509
+ if (onDetected2) {
17510
+ onDetected2({ _id: transactionId, site: result?.site?.toString(), plateNumber: result.plateNumber });
17511
+ }
17311
17512
  } catch (error) {
17312
17513
  console.log("failed to create visitor transaction", error);
17313
17514
  loggerDahua.error(
@@ -17341,7 +17542,7 @@ function useDahuaService() {
17341
17542
  }
17342
17543
  }
17343
17544
  }
17344
- async function handleBuffer(chunk) {
17545
+ async function handleBuffer(chunk, onDetected2) {
17345
17546
  partialBuffer = Buffer.concat([partialBuffer, chunk]);
17346
17547
  while (true) {
17347
17548
  const boundaryIndex = partialBuffer.indexOf(Buffer.from(boundary));
@@ -17367,7 +17568,7 @@ function useDahuaService() {
17367
17568
  direction = line.split("=")[1].trim();
17368
17569
  });
17369
17570
  if (plateNumber && UTCData) {
17370
- await processVehicleTransaction();
17571
+ await processVehicleTransaction(onDetected2);
17371
17572
  }
17372
17573
  } else if (part.includes("Content-Type: image/jpeg")) {
17373
17574
  const [headers, ...imageParts] = part.split("\r\n\r\n");
@@ -17394,7 +17595,7 @@ function useDahuaService() {
17394
17595
  try {
17395
17596
  await import_fs.promises.mkdir(dir, { recursive: true });
17396
17597
  await import_fs.promises.writeFile(snapFolder, accumulatedImageBuffer);
17397
- loggerDahua.debug(`[${site}][${gate}] Saved image locally: ${filename}`);
17598
+ loggerDahua.debug(`[${host}] Saved image locally: ${filename}`);
17398
17599
  const fileId = await _createFile(
17399
17600
  {
17400
17601
  originalname: filename,
@@ -17404,7 +17605,7 @@ function useDahuaService() {
17404
17605
  `anpr/${site}`
17405
17606
  );
17406
17607
  loggerDahua.info(
17407
- `[${site}][${gate}] Created file record for image: ${fileId.toString()}`
17608
+ `[${host}] Created file record for image: ${fileId.toString()}`
17408
17609
  );
17409
17610
  if (currentTransactionId && currentSnapshotField) {
17410
17611
  await updateById(currentTransactionId, {
@@ -17412,23 +17613,23 @@ function useDahuaService() {
17412
17613
  });
17413
17614
  }
17414
17615
  loggerDahua.info(
17415
- `[${site}][${gate}] Image stored with fileId: ${fileId.toString()}`
17616
+ `[${host}] Image stored with fileId: ${fileId.toString()}`
17416
17617
  );
17417
17618
  await import_fs.promises.unlink(snapFolder);
17418
- loggerDahua.debug(`[${site}][${gate}] Deleted local file: ${filename}`);
17619
+ loggerDahua.info(`[${host}] Deleted local file: ${filename}`);
17419
17620
  } catch (err) {
17420
17621
  loggerDahua.error(
17421
- `[${site}][${gate}] Failed to process image ${filename}:`,
17622
+ `[${host}] Failed to process image ${filename}:`,
17422
17623
  err
17423
17624
  );
17424
17625
  try {
17425
17626
  await import_fs.promises.unlink(snapFolder);
17426
- loggerDahua.debug(
17427
- `[${site}][${gate}] Cleaned up local file after error: ${filename}`
17627
+ loggerDahua.error(
17628
+ `[${host}] Cleaned up local file after error: ${filename}`
17428
17629
  );
17429
17630
  } catch (unlinkErr) {
17430
17631
  loggerDahua.error(
17431
- `[${site}][${gate}] Failed to clean up local file: ${filename}`,
17632
+ `[${host}] Failed to clean up local file: ${filename}`,
17432
17633
  unlinkErr
17433
17634
  );
17434
17635
  }
@@ -17468,7 +17669,7 @@ function useDahuaService() {
17468
17669
  throw error;
17469
17670
  }
17470
17671
  }
17471
- async function listenToCamera(camera) {
17672
+ async function listenToCamera(camera, onDetected) {
17472
17673
  if (!camera?._id) {
17473
17674
  loggerDahua.error(`Camera _id is required to listen to camera.`);
17474
17675
  throw new import_node_server_utils75.BadRequestError("Camera _id is required to listen to camera.");
@@ -17489,10 +17690,11 @@ function useDahuaService() {
17489
17690
  `guard-post-${camera.guardPost}`,
17490
17691
  camera.direction,
17491
17692
  cameraId,
17492
- controller.signal
17693
+ controller.signal,
17694
+ onDetected
17493
17695
  );
17494
17696
  }
17495
- async function getTrafficJunction(host = "", username = "", password = "", site = "", gate = "", designation = "", cameraId, signal) {
17697
+ async function getTrafficJunctionOld(host = "", username = "", password = "", site = "", gate = "", designation = "", cameraId, signal, onDetected) {
17496
17698
  if (signal.aborted)
17497
17699
  return;
17498
17700
  try {
@@ -17515,7 +17717,8 @@ function useDahuaService() {
17515
17717
  designation,
17516
17718
  host,
17517
17719
  username,
17518
- password
17720
+ password,
17721
+ onDetected
17519
17722
  );
17520
17723
  bufferQueue.setStream(response.res);
17521
17724
  const onAbort = () => {
@@ -17569,7 +17772,7 @@ function useDahuaService() {
17569
17772
  await new Promise((res) => setTimeout(res, 5e3));
17570
17773
  if (signal.aborted)
17571
17774
  return;
17572
- getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal);
17775
+ getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal, onDetected);
17573
17776
  };
17574
17777
  response.res.on(
17575
17778
  "end",
@@ -17593,8 +17796,87 @@ function useDahuaService() {
17593
17796
  await new Promise((res) => setTimeout(res, 5e3));
17594
17797
  if (signal.aborted)
17595
17798
  return;
17596
- getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal);
17799
+ getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal, onDetected);
17800
+ }
17801
+ }
17802
+ async function getTrafficJunction(host = "", username = "", password = "", site = "", gate = "", designation = "", cameraId, signal, onDetected) {
17803
+ while (!signal.aborted) {
17804
+ let bufferQueue = null;
17805
+ let response = null;
17806
+ try {
17807
+ response = await useDahuaDigest({
17808
+ host,
17809
+ username,
17810
+ password,
17811
+ endpoint: "/cgi-bin/snapManager.cgi?action=attachFileProc&channel=1&heartbeat=5&Flags[0]=Event&Events=[TrafficJunction]",
17812
+ timeout: 2e4,
17813
+ streaming: true
17814
+ });
17815
+ if ([400, 401, 403, 500].includes(response.statusCode)) {
17816
+ loggerDahua.error(`[${host}] Connection error: ${response.statusCode}`);
17817
+ throw new Error(`Failed to connect to ANPR: ${response.statusCode}`);
17818
+ }
17819
+ loggerDahua.info(`[${host}] Successfully connected to ANPR.`);
17820
+ const contentType = response.res.headers["content-type"];
17821
+ const boundaryMatch = contentType?.match(/boundary=(.*)$/i);
17822
+ const boundary = boundaryMatch ? `--${boundaryMatch[1]}` : "--myboundary";
17823
+ bufferQueue = useBufferQueue(
17824
+ boundary,
17825
+ site,
17826
+ gate,
17827
+ designation,
17828
+ host,
17829
+ username,
17830
+ password,
17831
+ onDetected
17832
+ );
17833
+ bufferQueue.setStream(response.res);
17834
+ await new Promise((resolve, reject) => {
17835
+ const onAbort = () => {
17836
+ loggerDahua.info(`[${site}]-[${host}] Abort triggered. Cleaning up...`);
17837
+ if (response.res && !response.res.destroyed) {
17838
+ response.res.destroy();
17839
+ }
17840
+ resolve("aborted");
17841
+ };
17842
+ signal.addEventListener("abort", onAbort, { once: true });
17843
+ response.res.on("data", (chunk) => {
17844
+ if (signal.aborted) {
17845
+ response.res.destroy();
17846
+ return;
17847
+ }
17848
+ bufferQueue.enqueue(chunk);
17849
+ });
17850
+ response.res.on("end", () => {
17851
+ signal.removeEventListener("abort", onAbort);
17852
+ resolve("ended");
17853
+ });
17854
+ response.res.on("close", () => {
17855
+ signal.removeEventListener("abort", onAbort);
17856
+ resolve("closed");
17857
+ });
17858
+ response.res.on("error", (err) => {
17859
+ signal.removeEventListener("abort", onAbort);
17860
+ reject(err);
17861
+ });
17862
+ });
17863
+ } catch (error) {
17864
+ if (signal.aborted)
17865
+ break;
17866
+ loggerDahua.error(
17867
+ `[${host}] Connection lost or error: ${error.message || error}. Retrying in 5s...`
17868
+ );
17869
+ } finally {
17870
+ if (bufferQueue?.destroy)
17871
+ bufferQueue.destroy();
17872
+ if (response?.res && !response.res.destroyed)
17873
+ response.res.destroy();
17874
+ }
17875
+ if (!signal.aborted) {
17876
+ await new Promise((res) => setTimeout(res, 5e3));
17877
+ }
17597
17878
  }
17879
+ loggerDahua.info(`[${host}] ANPR Listener stopped.`);
17598
17880
  }
17599
17881
  async function addPlateNumber(value) {
17600
17882
  const validation = import_joi40.default.object({
@@ -19701,7 +19983,7 @@ function useVehicleController() {
19701
19983
  next(new import_node_server_utils87.BadRequestError("Spreadsheet file is required."));
19702
19984
  return;
19703
19985
  }
19704
- const { originalname, path: path5 } = req.file;
19986
+ const { originalname, path: path4 } = req.file;
19705
19987
  const lowerName = originalname.toLowerCase();
19706
19988
  const rowSchema = import_joi46.default.object({
19707
19989
  fullName: import_joi46.default.string().trim().required(),
@@ -19740,7 +20022,7 @@ function useVehicleController() {
19740
20022
  let rows = [];
19741
20023
  if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
19742
20024
  const workbook = new import_exceljs.default.Workbook();
19743
- await workbook.xlsx.readFile(path5);
20025
+ await workbook.xlsx.readFile(path4);
19744
20026
  const worksheet = workbook.worksheets[0];
19745
20027
  if (!worksheet) {
19746
20028
  next(
@@ -19766,7 +20048,7 @@ function useVehicleController() {
19766
20048
  } else if (lowerName.endsWith(".csv")) {
19767
20049
  rows = await new Promise((resolve, reject) => {
19768
20050
  const parsed = [];
19769
- import_fs2.default.createReadStream(path5).pipe((0, import_csv_parser.default)()).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
20051
+ import_fs2.default.createReadStream(path4).pipe((0, import_csv_parser.default)()).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
19770
20052
  });
19771
20053
  } else {
19772
20054
  next(
@@ -19805,7 +20087,7 @@ function useVehicleController() {
19805
20087
  validationErrors: invalidRows,
19806
20088
  data
19807
20089
  });
19808
- import_fs2.default.unlink(path5, () => {
20090
+ import_fs2.default.unlink(path4, () => {
19809
20091
  });
19810
20092
  } catch (error) {
19811
20093
  import_node_server_utils87.logger.log({ level: "error", message: error.message });
@@ -19946,7 +20228,9 @@ function useVehicleController() {
19946
20228
  start: import_joi46.default.string().isoDate().optional().allow(null, ""),
19947
20229
  end: import_joi46.default.string().isoDate().optional().allow(null, ""),
19948
20230
  recNo: import_joi46.default.string().optional().allow(null, ""),
19949
- type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)).allow(null, "")
20231
+ type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)).allow(null, ""),
20232
+ peopleId: import_joi46.default.string().hex().length(24).optional().allow(null, ""),
20233
+ seasonPassType: import_joi46.default.string().optional().allow("", null)
19950
20234
  });
19951
20235
  const { error, value } = schema2.validate(
19952
20236
  {
@@ -20180,7 +20464,7 @@ function useSiteCameraService() {
20180
20464
  session.endSession();
20181
20465
  }
20182
20466
  }
20183
- async function listenToCapturedPlateNumber() {
20467
+ async function listenToCapturedPlateNumber(onDetected) {
20184
20468
  const siteCameras = [];
20185
20469
  let page = 1;
20186
20470
  let pages = 1;
@@ -20201,7 +20485,7 @@ function useSiteCameraService() {
20201
20485
  for (let index = 0; index < siteCameras.length; index++) {
20202
20486
  const siteCamera = siteCameras[index];
20203
20487
  if (siteCamera && siteCamera.status === "active" && siteCamera.host && siteCamera.username && siteCamera.password && siteCamera.site && siteCamera.guardPost) {
20204
- dahuaService.listenToCamera(siteCamera);
20488
+ dahuaService.listenToCamera(siteCamera, onDetected);
20205
20489
  }
20206
20490
  }
20207
20491
  }
@@ -24198,7 +24482,6 @@ var import_node_server_utils108 = require("@7365admin1/node-server-utils");
24198
24482
 
24199
24483
  // src/services/person.service.ts
24200
24484
  var import_node_server_utils107 = require("@7365admin1/node-server-utils");
24201
- var import_path = __toESM(require("path"));
24202
24485
  function usePersonService() {
24203
24486
  const MailerConfig = {
24204
24487
  host: MAILER_TRANSPORT_HOST,
@@ -24413,13 +24696,8 @@ function usePersonService() {
24413
24696
  value.status = "active";
24414
24697
  }
24415
24698
  await _reviewResidentPerson(id, value, session);
24416
- const logoPath = import_path.default.join(
24417
- __dirname,
24418
- "public",
24419
- "images",
24420
- "seven-365.svg"
24421
- );
24422
- const statusIconPath = import_path.default.join(__dirname, "public", "icons");
24699
+ const logoPath = `${STORAGE_API}/seven-365.svg`;
24700
+ const statusIconPath = STORAGE_API;
24423
24701
  let title = "";
24424
24702
  let message2 = "";
24425
24703
  let hideLogin = true;
@@ -25302,11 +25580,7 @@ function usePatrolQuestionRepo() {
25302
25580
  const { delNamespace, getCache, setCache } = (0, import_node_server_utils114.useCache)(namespace_collection);
25303
25581
  async function createIndexes() {
25304
25582
  try {
25305
- await collection.createIndexes([
25306
- {
25307
- key: { site: 1 }
25308
- }
25309
- ]);
25583
+ await collection.createIndexes([{ key: { site: 1, status: 1 } }]);
25310
25584
  return `Successfully created indexes for ${namespace_collection}.`;
25311
25585
  } catch (error) {
25312
25586
  import_node_server_utils114.logger.log({
@@ -25742,6 +26016,24 @@ function usePatrolRouteRepo() {
25742
26016
  const namespace_collection = "patrol.route";
25743
26017
  const collection = db.collection(namespace_collection);
25744
26018
  const { delNamespace, getCache, setCache } = (0, import_node_server_utils117.useCache)(namespace_collection);
26019
+ async function createIndexes() {
26020
+ try {
26021
+ await collection.createIndexes([
26022
+ { key: { site: 1, status: 1 } },
26023
+ { key: { site: 1, repeat: 1 } },
26024
+ { key: { assignee: 1 } }
26025
+ ]);
26026
+ return `Successfully created indexes for ${namespace_collection}.`;
26027
+ } catch (error) {
26028
+ import_node_server_utils117.logger.log({
26029
+ level: "error",
26030
+ message: error.message
26031
+ });
26032
+ throw new import_node_server_utils117.InternalServerError(
26033
+ "Failed to create general indexes on patrol routes."
26034
+ );
26035
+ }
26036
+ }
25745
26037
  async function createTextIndex() {
25746
26038
  try {
25747
26039
  await collection.createIndex({
@@ -26115,7 +26407,8 @@ function usePatrolRouteRepo() {
26115
26407
  updateById,
26116
26408
  deleteById,
26117
26409
  getScheduledRoute,
26118
- getById
26410
+ getById,
26411
+ createIndexes
26119
26412
  };
26120
26413
  }
26121
26414
 
@@ -26453,9 +26746,8 @@ function usePatrolLogRepo() {
26453
26746
  async function createIndexes() {
26454
26747
  try {
26455
26748
  await collection.createIndexes([
26456
- {
26457
- key: { site: 1 }
26458
- }
26749
+ { key: { site: 1, createdAt: -1 } },
26750
+ { key: { assignee: 1 } }
26459
26751
  ]);
26460
26752
  return `Successfully created indexes for ${namespace_collection}.`;
26461
26753
  } catch (error) {
@@ -30282,6 +30574,20 @@ function useSiteBillingItemRepo() {
30282
30574
  const namespace_collection = "site.billing.items";
30283
30575
  const collection = db.collection(namespace_collection);
30284
30576
  const { delNamespace, setCache, getCache } = (0, import_node_server_utils139.useCache)(namespace_collection);
30577
+ async function createIndexes() {
30578
+ try {
30579
+ await collection.createIndexes([{ key: { site: 1, status: 1 } }]);
30580
+ return `Successfully created indexes for ${namespace_collection}.`;
30581
+ } catch (error) {
30582
+ import_node_server_utils139.logger.log({
30583
+ level: "error",
30584
+ message: error.message
30585
+ });
30586
+ throw new import_node_server_utils139.InternalServerError(
30587
+ "Failed to create general indexes on billing item."
30588
+ );
30589
+ }
30590
+ }
30285
30591
  async function createTextIndex() {
30286
30592
  try {
30287
30593
  await collection.createIndex({
@@ -30501,7 +30807,8 @@ function useSiteBillingItemRepo() {
30501
30807
  getAll,
30502
30808
  getById,
30503
30809
  updateById,
30504
- deleteById
30810
+ deleteById,
30811
+ createIndexes
30505
30812
  };
30506
30813
  }
30507
30814
 
@@ -30642,6 +30949,20 @@ function useSiteBillingConfigurationRepo() {
30642
30949
  const namespace_collection = "site.billing.configuration";
30643
30950
  const collection = db.collection(namespace_collection);
30644
30951
  const { delNamespace, setCache, getCache } = (0, import_node_server_utils141.useCache)(namespace_collection);
30952
+ async function createIndexes() {
30953
+ try {
30954
+ await collection.createIndexes([{ key: { site: 1, status: 1 } }]);
30955
+ return `Successfully created indexes for ${namespace_collection}.`;
30956
+ } catch (error) {
30957
+ import_node_server_utils141.logger.log({
30958
+ level: "error",
30959
+ message: error.message
30960
+ });
30961
+ throw new import_node_server_utils141.InternalServerError(
30962
+ "Failed to create general indexes on billing configuration."
30963
+ );
30964
+ }
30965
+ }
30645
30966
  async function createTextIndex() {
30646
30967
  try {
30647
30968
  await collection.createIndex({
@@ -30851,7 +31172,8 @@ function useSiteBillingConfigurationRepo() {
30851
31172
  getAll,
30852
31173
  getById,
30853
31174
  updateById,
30854
- deleteById
31175
+ deleteById,
31176
+ createIndexes
30855
31177
  };
30856
31178
  }
30857
31179
 
@@ -31900,9 +32222,8 @@ function useEventManagementController() {
31900
32222
  }
31901
32223
  }
31902
32224
  async function updateEventManagementById(req, res, next) {
31903
- const _id = req.params.id;
31904
- const payload = { _id, ...req.body };
31905
- const { error } = schemaUpdateEventManagement.validate(payload, {
32225
+ const payload = { _id: req.params.id, ...req.body };
32226
+ const { error, value } = schemaUpdateEventManagement.validate(payload, {
31906
32227
  abortEarly: false
31907
32228
  });
31908
32229
  if (error) {
@@ -31911,8 +32232,9 @@ function useEventManagementController() {
31911
32232
  next(new import_node_server_utils148.BadRequestError(messages));
31912
32233
  return;
31913
32234
  }
32235
+ const { _id, ...rest } = value;
31914
32236
  try {
31915
- const result = await _updateEventManagementById(_id, req.body);
32237
+ const result = await _updateEventManagementById(_id, rest);
31916
32238
  res.status(200).json({ message: result });
31917
32239
  return;
31918
32240
  } catch (error2) {
@@ -32132,6 +32454,25 @@ function useSiteUnitBillingRepo() {
32132
32454
  const namespace_collection = "site.unit.billing";
32133
32455
  const collection = db.collection(namespace_collection);
32134
32456
  const { delNamespace, setCache, getCache } = (0, import_node_server_utils150.useCache)(namespace_collection);
32457
+ async function createIndexes() {
32458
+ try {
32459
+ await collection.createIndexes([
32460
+ { key: { site: 1, status: 1, paymentStatus: 1 } },
32461
+ { key: { site: 1, unitId: 1, status: 1, paymentStatus: 1 } },
32462
+ { key: { site: 1, unitId: 1, issueDate: 1 } },
32463
+ { key: { createdAt: -1 } }
32464
+ ]);
32465
+ return `Successfully created indexes for ${namespace_collection}.`;
32466
+ } catch (error) {
32467
+ import_node_server_utils150.logger.log({
32468
+ level: "error",
32469
+ message: error.message
32470
+ });
32471
+ throw new import_node_server_utils150.InternalServerError(
32472
+ "Failed to create general indexes on unit billing."
32473
+ );
32474
+ }
32475
+ }
32135
32476
  async function createTextIndex() {
32136
32477
  try {
32137
32478
  await collection.createIndex({
@@ -32685,7 +33026,8 @@ function useSiteUnitBillingRepo() {
32685
33026
  deleteById,
32686
33027
  getUnitBillingBySite,
32687
33028
  getResidentUserBilling,
32688
- getResidentUserUnsettledBilling
33029
+ getResidentUserUnsettledBilling,
33030
+ createIndexes
32689
33031
  };
32690
33032
  }
32691
33033
 
@@ -33240,7 +33582,7 @@ var import_mongodb90 = require("mongodb");
33240
33582
 
33241
33583
  // src/utils/access-management.ts
33242
33584
  var import_fs3 = __toESM(require("fs"));
33243
- var import_path2 = __toESM(require("path"));
33585
+ var import_path = __toESM(require("path"));
33244
33586
  var import_axios = __toESM(require("axios"));
33245
33587
  var import_xml2js = require("xml2js");
33246
33588
  var import_crypto = __toESM(require("crypto"));
@@ -33270,7 +33612,7 @@ var minifyXml = (xml) => {
33270
33612
  };
33271
33613
  var readTemplate = (name, params) => {
33272
33614
  const template = import_fs3.default.readFileSync(
33273
- import_path2.default.join(__dirname, `../dist/public/xml-templates/${name}.xml`),
33615
+ import_path.default.join(__dirname, `../dist/public/xml-templates/${name}.xml`),
33274
33616
  "utf-8"
33275
33617
  );
33276
33618
  if (!params)
@@ -33401,9 +33743,9 @@ var import_xml2js2 = require("xml2js");
33401
33743
  // src/utils/rsa-encryption.ts
33402
33744
  var crypto2 = __toESM(require("crypto"));
33403
33745
  var import_fs4 = __toESM(require("fs"));
33404
- var import_path3 = __toESM(require("path"));
33405
- var pub = import_path3.default.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_pub.pem");
33406
- var priv = import_path3.default.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_priv.pem");
33746
+ var import_path2 = __toESM(require("path"));
33747
+ var pub = import_path2.default.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_pub.pem");
33748
+ var priv = import_path2.default.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_priv.pem");
33407
33749
  var EncryptionCredentials = class {
33408
33750
  };
33409
33751
  EncryptionCredentials.RAW_PUBLIC_KEY = import_fs4.default.readFileSync(pub, "utf8");
@@ -38499,6 +38841,22 @@ function useStatementOfAccountRepo() {
38499
38841
  const namespace_collection = "site.statement-of-accounts";
38500
38842
  const collection = db.collection(namespace_collection);
38501
38843
  const { delNamespace, getCache, setCache } = (0, import_node_server_utils165.useCache)(namespace_collection);
38844
+ async function createIndexes() {
38845
+ try {
38846
+ await collection.createIndexes([
38847
+ { key: { site: 1, status: 1 } },
38848
+ { key: { site: 1, unitId: 1, status: 1 } },
38849
+ { key: { createdAt: -1 } }
38850
+ ]);
38851
+ return `Successfully created indexes for ${namespace_collection}.`;
38852
+ } catch (error) {
38853
+ import_node_server_utils165.logger.log({
38854
+ level: "error",
38855
+ message: error.message
38856
+ });
38857
+ throw new import_node_server_utils165.InternalServerError("Failed to create general indexes on SOA.");
38858
+ }
38859
+ }
38502
38860
  async function createTextIndex() {
38503
38861
  try {
38504
38862
  await collection.createIndex({
@@ -38849,7 +39207,8 @@ function useStatementOfAccountRepo() {
38849
39207
  deleteById,
38850
39208
  updateStatusById,
38851
39209
  getResidentUserSoa,
38852
- reviewSOA
39210
+ reviewSOA,
39211
+ createIndexes
38853
39212
  };
38854
39213
  }
38855
39214
 
@@ -42404,7 +42763,10 @@ function useOccurrenceEntryService() {
42404
42763
  updateOccurrenceEntryById: _updateOccurrenceEntryById,
42405
42764
  getOccurrenceEntryById: _getOccurrenceEntryById,
42406
42765
  getOccurrenceEntryByBookId: _getOccurrenceEntryByBookId,
42407
- updateOccurrenceEntryByBookId: _updateOccurrenceEntryByBookId
42766
+ updateOccurrenceEntryByBookId: _updateOccurrenceEntryByBookId,
42767
+ deleteOccurrenceEntryById: _deleteOccurrenceEntryById,
42768
+ getLatestSerialNumber: _getLatestSerialNumber,
42769
+ getLatestSerialNumberInGroup: _getLatestSerialNumberInGroup
42408
42770
  } = useOccurrenceEntryRepo();
42409
42771
  const {
42410
42772
  getOccurrenceBookById: _getOccurrenceBookById,
@@ -42456,8 +42818,20 @@ function useOccurrenceEntryService() {
42456
42818
  if (!occurrenceEntry) {
42457
42819
  throw new Error("Occurrence entry not found.");
42458
42820
  }
42459
- const entrySerialNumber = Number(occurrenceEntry.serialNumber);
42460
- const updatedSerialNumber = (entrySerialNumber + 0.1).toFixed(1);
42821
+ const entryCount = await _getLatestSerialNumberInGroup(
42822
+ occurrenceEntry.dailyOccurrenceBookId,
42823
+ Number(occurrenceEntry.serialNumber)
42824
+ );
42825
+ const currentSerial = Number(occurrenceEntry.serialNumber);
42826
+ const latestSerial = Number(entryCount);
42827
+ const currentGroup = Math.floor(currentSerial);
42828
+ const latestGroup = Math.floor(latestSerial);
42829
+ let updatedSerialNumber;
42830
+ if (currentGroup === latestGroup) {
42831
+ updatedSerialNumber = (latestSerial + 0.1).toFixed(1);
42832
+ } else {
42833
+ updatedSerialNumber = (currentSerial + 0.1).toFixed(1);
42834
+ }
42461
42835
  const dobId = occurrenceEntry.dailyOccurrenceBookId;
42462
42836
  const book = await _getOccurrenceBookById(dobId);
42463
42837
  const subject = await _getOccurrenceSubjectById(
@@ -44471,14 +44845,15 @@ async function hrmLabsAuthentication({
44471
44845
  showPassword: false
44472
44846
  },
44473
44847
  {
44474
- headers: { "Content-Type": "application/json" }
44848
+ headers: { "Content-Type": "application/json" },
44849
+ validateStatus: () => true
44475
44850
  }
44476
44851
  );
44477
44852
  if (res.data?.success && res.data.data?.token) {
44478
44853
  return res.data.data.token;
44479
44854
  }
44480
44855
  throw new Error(
44481
- "HRMLabs Authentication failed. Please check your credentials."
44856
+ res.status === 401 || res.status === 403 ? "HRMLabs Authentication failed. Please check your credentials." : `HRMLabs Authentication failed with status ${res.status}.`
44482
44857
  );
44483
44858
  }
44484
44859
  async function fetchAttendanceData({
@@ -44915,7 +45290,9 @@ function useManpowerMonitoringRepo() {
44915
45290
  {
44916
45291
  key: { siteId: 1 }
44917
45292
  },
44918
- { key: { createdAt: 1 } }
45293
+ { key: { createdAt: 1 } },
45294
+ { key: { siteId: 1, serviceProviderId: 1 } },
45295
+ { key: { siteName: 1 } }
44919
45296
  ]);
44920
45297
  return `Successfully created indexes for ${namespace_collection}.`;
44921
45298
  } catch (error) {
@@ -45174,7 +45551,9 @@ function useManpowerRemarksRepo() {
45174
45551
  {
45175
45552
  key: { siteId: 1 }
45176
45553
  },
45177
- { key: { createdAt: 1 } }
45554
+ { key: { createdAt: 1 } },
45555
+ { key: { siteId: 1, serviceProviderId: 1, createdAtSGT: 1 } },
45556
+ { key: { serviceProviderId: 1, status: 1, createdAtSGT: 1 } }
45178
45557
  ]);
45179
45558
  return `Successfully created indexes for ${namespace_collection}.`;
45180
45559
  } catch (error) {
@@ -45603,7 +45982,8 @@ function useManpowerDesignationRepo() {
45603
45982
  {
45604
45983
  key: { siteId: 1 }
45605
45984
  },
45606
- { key: { createdAt: 1 } }
45985
+ { key: { createdAt: 1 } },
45986
+ { key: { siteId: 1, serviceProviderId: 1 } }
45607
45987
  ]);
45608
45988
  return `Successfully created indexes for ${namespace_collection}.`;
45609
45989
  } catch (error) {
@@ -46669,7 +47049,7 @@ function useHrmLabsAttendanceSrvc() {
46669
47049
  } catch (error) {
46670
47050
  import_node_server_utils209.logger.error(error.message || error);
46671
47051
  console.log("Error fetching attendance data:", error);
46672
- throw new Error(error?.message || "Internal Server Error!");
47052
+ return { success: false, message: error?.message || "Internal Server Error!", items: [], pages: 0, pageRange: "0-0 of 0", count: {} };
46673
47053
  }
46674
47054
  }
46675
47055
  async function getAttendanceDataCount(payload) {
@@ -46783,7 +47163,7 @@ function useHrmLabsAttendanceSrvc() {
46783
47163
  } catch (error) {
46784
47164
  import_node_server_utils209.logger.error(error.message || error);
46785
47165
  console.log("Error fetching attendance data count:", error);
46786
- throw new Error(error?.message || "Internal Server Error!");
47166
+ return { success: false, message: error?.message || "Internal Server Error!", totalCount: null };
46787
47167
  }
46788
47168
  }
46789
47169
  async function getAllAttendance(payload) {
@@ -46955,7 +47335,7 @@ function useHrmLabsAttendanceSrvc() {
46955
47335
  } catch (error) {
46956
47336
  import_node_server_utils209.logger.error(error.message || error);
46957
47337
  console.log("Error fetching attendance data:", error);
46958
- throw new Error(error?.message || "Internal Server Error!");
47338
+ return { success: false, message: error?.message || "Internal Server Error!", items: [], count: {}, countPerJobTitle: {}, totalCount: null, countPerStatus: {} };
46959
47339
  }
46960
47340
  }
46961
47341
  async function getChartAttendanceData(payload) {
@@ -47062,7 +47442,7 @@ function useHrmLabsAttendanceSrvc() {
47062
47442
  } catch (error) {
47063
47443
  import_node_server_utils209.logger.error(error.message || error);
47064
47444
  console.log("Error fetching attendance data:", error);
47065
- throw new Error(error?.message || "Internal Server Error!");
47445
+ return { success: false, message: error?.message || "Internal Server Error!", chartCount: null };
47066
47446
  }
47067
47447
  }
47068
47448
  return {
@@ -48692,7 +49072,8 @@ function useVerificationServiceV2() {
48692
49072
  add: _add,
48693
49073
  updateVerificationStatusById: _updateVerificationStatusById,
48694
49074
  getByVerificationCode: _getByVerificationCode,
48695
- updateStatusById: _updateStatusById
49075
+ updateStatusById: _updateStatusById,
49076
+ countPendingOrgInvites: _countPendingOrgInvites
48696
49077
  } = useVerificationRepoV2();
48697
49078
  const {
48698
49079
  getUserByEmailStatus: _getUserByEmailStatus,
@@ -48700,6 +49081,8 @@ function useVerificationServiceV2() {
48700
49081
  } = useUserRepo();
48701
49082
  const { getById: getOrgById, getByEmail: _getByEmail } = useOrgRepo();
48702
49083
  const { getSiteById } = useSiteRepo();
49084
+ const { getByOrgId: _getSubscriptionByOrgId } = useSubscriptionRepo();
49085
+ const { countByOrg: _countMemberByOrg } = useMemberRepo();
48703
49086
  function errorByType(type, status) {
48704
49087
  if ((type === "user-invite" /* USER_INVITE */ || type === "member-invite" /* MEMBER_INVITE */ || type === "service-provider-invite" /* SERVICE_PROVIDER_INVITE */ || type === "service-provider-create-org" /* SERVICE_PROVIDER_CREATE_ORG */) && status === "expired" /* EXPIRED */) {
48705
49088
  throw new import_node_server_utils221.BadRequestError(
@@ -48963,6 +49346,30 @@ function useVerificationServiceV2() {
48963
49346
  throw error2;
48964
49347
  }
48965
49348
  }
49349
+ async function createOrganizationInvite({
49350
+ email,
49351
+ metadata
49352
+ }) {
49353
+ const orgId = metadata.org?.toString() ?? "";
49354
+ if (!orgId) {
49355
+ throw new import_node_server_utils221.BadRequestError("Organization is required.");
49356
+ }
49357
+ await getOrgById(orgId);
49358
+ const [subscription, memberCount, pendingInviteCount] = await Promise.all([
49359
+ _getSubscriptionByOrgId(orgId),
49360
+ _countMemberByOrg(orgId),
49361
+ _countPendingOrgInvites(orgId)
49362
+ ]);
49363
+ const maxSeats = subscription?.maxSeats ?? 0;
49364
+ if (!maxSeats) {
49365
+ throw new import_node_server_utils221.BadRequestError("No seats configured for organization.");
49366
+ }
49367
+ const usedSeats = memberCount + pendingInviteCount;
49368
+ if (usedSeats >= maxSeats) {
49369
+ throw new import_node_server_utils221.BadRequestError("No available seats for new invitation.");
49370
+ }
49371
+ return createUserInvite({ email, metadata });
49372
+ }
48966
49373
  async function createForgetPassword(email) {
48967
49374
  const value = {
48968
49375
  type: "forget-password" /* FORGET_PASSWORD */,
@@ -49013,6 +49420,7 @@ function useVerificationServiceV2() {
49013
49420
  signUp,
49014
49421
  verify,
49015
49422
  createUserInvite,
49423
+ createOrganizationInvite,
49016
49424
  createServiceProviderInvite,
49017
49425
  createForgetPassword,
49018
49426
  cancelUserInvitation
@@ -49026,6 +49434,7 @@ function useVerificationControllerV2() {
49026
49434
  const {
49027
49435
  verify: _verify,
49028
49436
  createUserInvite: _createUserInvite,
49437
+ createOrganizationInvite: _createOrganizationInvite,
49029
49438
  createServiceProviderInvite: _createServiceProviderInvite,
49030
49439
  createForgetPassword: _createForgetPassword,
49031
49440
  cancelUserInvitation: _cancelUserInvitation
@@ -49122,6 +49531,44 @@ function useVerificationControllerV2() {
49122
49531
  return;
49123
49532
  }
49124
49533
  }
49534
+ async function createOrganizationInvite(req, res, next) {
49535
+ const schema2 = import_joi127.default.object({
49536
+ email: import_joi127.default.string().email().lowercase().required(),
49537
+ role: import_joi127.default.string().hex().length(24).required(),
49538
+ org: import_joi127.default.string().hex().length(24).required(),
49539
+ app: import_joi127.default.string().optional().allow("", null).default("organization"),
49540
+ name: import_joi127.default.string().optional().allow("", null),
49541
+ siteId: import_joi127.default.string().hex().length(24).optional().allow("", null),
49542
+ siteName: import_joi127.default.string().optional().allow("", null)
49543
+ });
49544
+ const { error, value } = schema2.validate(req.body, { abortEarly: false });
49545
+ if (error) {
49546
+ const messages = error.details.map((d) => d.message).join(", ");
49547
+ import_node_server_utils222.logger.log({ level: "error", message: messages });
49548
+ next(new import_node_server_utils222.BadRequestError(messages));
49549
+ return;
49550
+ }
49551
+ try {
49552
+ const { email, app, role, name, org, siteId, siteName } = value;
49553
+ await _createOrganizationInvite({
49554
+ email,
49555
+ metadata: {
49556
+ app,
49557
+ role,
49558
+ name,
49559
+ org,
49560
+ siteId,
49561
+ siteName
49562
+ }
49563
+ });
49564
+ res.status(201).json({ message: "Successfully invited user." });
49565
+ return;
49566
+ } catch (error2) {
49567
+ import_node_server_utils222.logger.log({ level: "error", message: `${error2.message}` });
49568
+ next(error2);
49569
+ return;
49570
+ }
49571
+ }
49125
49572
  async function createForgetPassword(req, res, next) {
49126
49573
  const schema2 = import_joi127.default.object({
49127
49574
  email: import_joi127.default.string().email().lowercase().required()
@@ -49207,6 +49654,7 @@ function useVerificationControllerV2() {
49207
49654
  return {
49208
49655
  verify,
49209
49656
  createUserInvite,
49657
+ createOrganizationInvite,
49210
49658
  createServiceProviderInvite,
49211
49659
  createForgetPassword,
49212
49660
  getVerifications,
@@ -50977,6 +51425,7 @@ function useRoleControllerV2() {
50977
51425
  vehicles_namespace_collection,
50978
51426
  visitors_namespace_collection,
50979
51427
  workOrderSchema,
51428
+ work_orders2_namespace_collection,
50980
51429
  work_orders_namespace_collection
50981
51430
  });
50982
51431
  //# sourceMappingURL=index.js.map