@7365admin1/core 2.41.0 → 2.43.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
@@ -842,7 +842,6 @@ function useFeedbackRepo() {
842
842
  cacheOptions.from = from;
843
843
  cacheOptions.to = to;
844
844
  }
845
- console.log("query", JSON.stringify(query));
846
845
  const cacheKey = (0, import_node_server_utils5.makeCacheKey)(feedbacks_namespace_collection, cacheOptions);
847
846
  const cachedData = await getCache(cacheKey);
848
847
  if (cachedData) {
@@ -2293,7 +2292,6 @@ function useOccurrenceEntryRepo() {
2293
2292
  throw new Error("Invalid incident report ID.");
2294
2293
  }
2295
2294
  }
2296
- console.log("Updating occurrence entry:", _id, value);
2297
2295
  try {
2298
2296
  const res = await collection.updateOne(
2299
2297
  { _id },
@@ -5158,7 +5156,10 @@ function useSiteRepo() {
5158
5156
  throw error;
5159
5157
  }
5160
5158
  }
5161
- async function siteInformation({ id, payload }) {
5159
+ async function siteInformation({
5160
+ id,
5161
+ payload
5162
+ }) {
5162
5163
  try {
5163
5164
  const siteId = new import_mongodb17.ObjectId(id);
5164
5165
  const res = await collection.updateOne(
@@ -5178,6 +5179,48 @@ function useSiteRepo() {
5178
5179
  throw error;
5179
5180
  }
5180
5181
  }
5182
+ async function getAllSitesForResidentCreation({
5183
+ search = "",
5184
+ page = 1,
5185
+ limit = 10
5186
+ }) {
5187
+ page = page > 0 ? page - 1 : 0;
5188
+ const query = {
5189
+ status: { $ne: "deleted" }
5190
+ };
5191
+ const cacheOptions = {
5192
+ status: { $ne: "deleted" },
5193
+ page,
5194
+ limit
5195
+ };
5196
+ if (search) {
5197
+ query.$or = [{ name: { $regex: search, $options: "i" } }];
5198
+ cacheOptions.search = search;
5199
+ }
5200
+ const cacheKey = (0, import_node_server_utils19.makeCacheKey)(namespace_collection, cacheOptions);
5201
+ const cachedData = await getCache(cacheKey);
5202
+ if (cachedData) {
5203
+ import_node_server_utils19.logger.info(`Cache hit for key: ${cacheKey}`);
5204
+ return cachedData;
5205
+ }
5206
+ try {
5207
+ const items = await collection.aggregate([
5208
+ { $match: query },
5209
+ { $skip: page * limit },
5210
+ { $limit: limit }
5211
+ ]).toArray();
5212
+ const length = await collection.countDocuments(query);
5213
+ const data = (0, import_node_server_utils19.paginate)(items, page, limit, length);
5214
+ setCache(cacheKey, data, 15 * 60).then(() => {
5215
+ import_node_server_utils19.logger.info(`Cache set for key: ${cacheKey}`);
5216
+ }).catch((err) => {
5217
+ import_node_server_utils19.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
5218
+ });
5219
+ return data;
5220
+ } catch (error) {
5221
+ throw error;
5222
+ }
5223
+ }
5181
5224
  return {
5182
5225
  createIndexes,
5183
5226
  createSite,
@@ -5192,7 +5235,8 @@ function useSiteRepo() {
5192
5235
  updateSiteIncidentCounter,
5193
5236
  updateSiteById,
5194
5237
  getAllSitesUnpaginated,
5195
- siteInformation
5238
+ siteInformation,
5239
+ getAllSitesForResidentCreation
5196
5240
  };
5197
5241
  }
5198
5242
 
@@ -10577,7 +10621,6 @@ function useSubscriptionService() {
10577
10621
  subscription.nextBillingDate,
10578
10622
  "pending"
10579
10623
  );
10580
- console.log("dueInvoice", dueInvoice);
10581
10624
  if (value.promoCode) {
10582
10625
  const promoCode = await getByCode(value.promoCode);
10583
10626
  if (!promoCode) {
@@ -11597,11 +11640,8 @@ function useFeedbackController() {
11597
11640
  (acc, [key, value]) => ({ ...acc, [key]: value }),
11598
11641
  {}
11599
11642
  );
11600
- console.log("cookies", cookies);
11601
11643
  const createdBy = cookies?.["user"].toString() ?? "";
11602
- console.log("createdBy", createdBy);
11603
11644
  const payload = { ...req.body, createdBy };
11604
- console.log("payload", payload);
11605
11645
  const { error } = feedbackSchema.validate(payload);
11606
11646
  if (error) {
11607
11647
  import_node_server_utils57.logger.log({ level: "error", message: error.message });
@@ -12302,7 +12342,7 @@ function useServiceProviderController() {
12302
12342
  const validation = import_joi30.default.object({
12303
12343
  search: import_joi30.default.string().optional().allow("", null),
12304
12344
  page: import_joi30.default.number().integer().min(1).allow("", null).default(1),
12305
- limit: import_joi30.default.number().integer().min(1).max(100).allow("", null).default(10),
12345
+ limit: import_joi30.default.number().integer().min(1).max(1e3).allow("", null).default(10),
12306
12346
  orgId: import_joi30.default.string().hex().optional().allow("", null),
12307
12347
  siteId: import_joi30.default.string().hex().optional().allow("", null),
12308
12348
  serviceProviderOrgId: import_joi30.default.string().hex().optional().allow("", null),
@@ -13501,7 +13541,9 @@ var schemaPerson = import_joi35.default.object({
13501
13541
  plates: import_joi35.default.array().items(schemaPlate).optional().allow(null),
13502
13542
  isOwner: import_joi35.default.boolean().required(),
13503
13543
  files: import_joi35.default.array().items(schemaFiles).optional().allow(null),
13504
- password: import_joi35.default.string().optional().allow(null, "")
13544
+ password: import_joi35.default.string().optional().allow(null, ""),
13545
+ plateNumber: import_joi35.default.string().optional().allow(null, ""),
13546
+ platform: import_joi35.default.string().valid("web", "mobile").optional().allow(null, "")
13505
13547
  });
13506
13548
  var schemaUpdatePerson = import_joi35.default.object({
13507
13549
  _id: import_joi35.default.string().hex().required(),
@@ -13521,12 +13563,14 @@ var schemaUpdatePerson = import_joi35.default.object({
13521
13563
  plates: import_joi35.default.array().items(schemaFiles).optional().allow(null, ""),
13522
13564
  isOwner: import_joi35.default.boolean().optional().allow(null, ""),
13523
13565
  files: import_joi35.default.array().items(schemaFiles).optional().allow(null),
13524
- password: import_joi35.default.string().optional().allow(null, "")
13566
+ password: import_joi35.default.string().optional().allow(null, ""),
13567
+ plateNumber: import_joi35.default.string().optional().allow(null, ""),
13568
+ platform: import_joi35.default.string().valid("web", "mobile").optional().allow(null, "")
13525
13569
  });
13526
13570
  function MPerson(value) {
13527
13571
  const { error } = schemaPerson.validate(value);
13528
13572
  if (error) {
13529
- throw new Error(error.details[0].message);
13573
+ throw new import_node_server_utils68.BadRequestError(error.details[0].message);
13530
13574
  }
13531
13575
  if (value._id && typeof value._id === "string") {
13532
13576
  try {
@@ -13591,6 +13635,8 @@ function MPerson(value) {
13591
13635
  plates: value.plates ?? [],
13592
13636
  isOwner: value.isOwner ?? false,
13593
13637
  files: value.files ?? [],
13638
+ plateNumber: value.plateNumber ?? "",
13639
+ platForm: value.platform ?? "",
13594
13640
  createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
13595
13641
  updatedAt: value.updatedAt,
13596
13642
  deletedAt: value.deletedAt
@@ -13629,8 +13675,8 @@ var schemaVisitorTransaction = import_joi36.default.object({
13629
13675
  contact: import_joi36.default.string().optional().allow(null, ""),
13630
13676
  plateNumber: import_joi36.default.string().optional().allow(null, ""),
13631
13677
  recNo: import_joi36.default.string().optional().allow(null, ""),
13632
- checkIn: import_joi36.default.date().optional().allow(null, ""),
13633
- checkOut: import_joi36.default.date().optional().allow(null, ""),
13678
+ checkIn: import_joi36.default.date().iso().optional().allow(null),
13679
+ checkOut: import_joi36.default.date().iso().optional().allow(null),
13634
13680
  deliveryType: import_joi36.default.string().optional().allow(null, ""),
13635
13681
  status: import_joi36.default.string().optional().valid(...Object.values(VisitorStatus)).default("registered" /* REGISTERED */),
13636
13682
  remarks: import_joi36.default.string().optional().allow(null, ""),
@@ -13694,8 +13740,8 @@ var schemaUpdateVisTrans = import_joi36.default.object({
13694
13740
  contact: import_joi36.default.string().optional().allow(null, ""),
13695
13741
  plateNumber: import_joi36.default.string().optional().allow(null, ""),
13696
13742
  recNo: import_joi36.default.string().optional().allow(null, ""),
13697
- checkIn: import_joi36.default.date().optional().allow(null, ""),
13698
- checkOut: import_joi36.default.date().optional().allow(null, ""),
13743
+ checkIn: import_joi36.default.date().iso().optional().allow(null),
13744
+ checkOut: import_joi36.default.date().iso().optional().allow(null),
13699
13745
  deliveryType: import_joi36.default.string().optional().allow(null, ""),
13700
13746
  status: import_joi36.default.string().optional().allow(null, ""),
13701
13747
  remarks: import_joi36.default.string().optional().allow(null, ""),
@@ -13924,7 +13970,6 @@ function useVisitorTransactionRepo() {
13924
13970
  ...status && { status },
13925
13971
  ...tab == "Overnight Parking" && { isOvernightParking: true }
13926
13972
  };
13927
- console.log(query);
13928
13973
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
13929
13974
  try {
13930
13975
  const basePipeline = [{ $match: query }];
@@ -14397,8 +14442,8 @@ function MVehicle(value) {
14397
14442
  const createdAtDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
14398
14443
  const expiredDate = new Date(createdAtDate);
14399
14444
  expiredDate.setFullYear(expiredDate.getFullYear() + 10);
14400
- const createdAt = createdAtDate.toISOString();
14401
- const expiredAt = value.end ?? expiredDate.toISOString();
14445
+ const createdAt = createdAtDate;
14446
+ const expiredAt = value.end ?? expiredDate;
14402
14447
  return {
14403
14448
  plateNumber: value.plateNumber ?? "",
14404
14449
  type: value.type ?? "",
@@ -14414,8 +14459,8 @@ function MVehicle(value) {
14414
14459
  nric: value.nric ?? "",
14415
14460
  remarks: value.remarks ?? "",
14416
14461
  seasonPassType: value.seasonPassType ?? "",
14417
- start: value.start ?? createdAt,
14418
- end: value.end ?? expiredAt,
14462
+ start: value.start ? new Date(value.start) : createdAt,
14463
+ end: value.end ? new Date(value.end) : expiredAt,
14419
14464
  status: value.status ?? "active" /* ACTIVE */,
14420
14465
  unitName: value.unitName ?? "",
14421
14466
  peopleId: value.peopleId ?? "",
@@ -14544,10 +14589,11 @@ function useVehicleRepo() {
14544
14589
  const baseQuery = {
14545
14590
  ...status && { status },
14546
14591
  ...type && { type },
14547
- ...category && { category },
14548
- ...search && { $text: { search } }
14592
+ ...category && { category }
14549
14593
  };
14550
14594
  let query = { ...baseQuery };
14595
+ if (search)
14596
+ query.$text = { $search: search };
14551
14597
  const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14552
14598
  const buildGroupedPipeline = (matchQuery) => [
14553
14599
  { $match: matchQuery },
@@ -15107,7 +15153,7 @@ function useVehicleRepo() {
15107
15153
  throw error;
15108
15154
  }
15109
15155
  }
15110
- async function bulkUpsertVehicles(values, session) {
15156
+ async function bulkUpsertVehicles(values) {
15111
15157
  try {
15112
15158
  if (!Array.isArray(values) || values.length === 0) {
15113
15159
  return {
@@ -15116,7 +15162,7 @@ function useVehicleRepo() {
15116
15162
  upsertedCount: 0
15117
15163
  };
15118
15164
  }
15119
- const now = (/* @__PURE__ */ new Date()).toISOString();
15165
+ const now = /* @__PURE__ */ new Date();
15120
15166
  const operations = values.map((item) => {
15121
15167
  const vehicle = MVehicle(item);
15122
15168
  const plateNumber = Array.isArray(vehicle.plateNumber) ? vehicle.plateNumber[0] : vehicle.plateNumber;
@@ -15124,7 +15170,7 @@ function useVehicleRepo() {
15124
15170
  return {
15125
15171
  updateOne: {
15126
15172
  filter: {
15127
- site: vehicle.site,
15173
+ site: new import_mongodb43.ObjectId(vehicle.site),
15128
15174
  plateNumber,
15129
15175
  $or: [
15130
15176
  { deletedAt: "" },
@@ -15135,6 +15181,9 @@ function useVehicleRepo() {
15135
15181
  update: {
15136
15182
  $set: {
15137
15183
  ...rest,
15184
+ site: new import_mongodb43.ObjectId(vehicle.site),
15185
+ unit: vehicle.unit ? new import_mongodb43.ObjectId(vehicle.unit) : null,
15186
+ org: vehicle.org ? new import_mongodb43.ObjectId(vehicle.org) : null,
15138
15187
  plateNumber,
15139
15188
  updatedAt: now
15140
15189
  },
@@ -15146,10 +15195,7 @@ function useVehicleRepo() {
15146
15195
  }
15147
15196
  };
15148
15197
  });
15149
- const res = await collection.bulkWrite(operations, {
15150
- ordered: false,
15151
- session
15152
- });
15198
+ const res = await collection.bulkWrite(operations);
15153
15199
  return {
15154
15200
  matchedCount: res.matchedCount,
15155
15201
  modifiedCount: res.modifiedCount,
@@ -15272,7 +15318,7 @@ function usePersonRepo() {
15272
15318
  ]
15273
15319
  } : void 0;
15274
15320
  const query = {
15275
- status,
15321
+ ...status && status !== "all" ? { status } : { status: { $nin: ["deleted", "rejected"] } },
15276
15322
  ...start && { start },
15277
15323
  ...end,
15278
15324
  ...search && {
@@ -15310,12 +15356,29 @@ function usePersonRepo() {
15310
15356
  return cachedData;
15311
15357
  }
15312
15358
  try {
15313
- const basePipeline = [
15314
- { $match: query },
15315
- { $sort: sort },
15316
- { $skip: page * limit },
15317
- { $limit: limit }
15318
- ];
15359
+ const basePipeline = [{ $match: query }];
15360
+ if (status && status == "all") {
15361
+ basePipeline.push(
15362
+ {
15363
+ $addFields: {
15364
+ sortPriority: {
15365
+ $cond: [{ $eq: ["$status", "pending"] }, 1, 2]
15366
+ }
15367
+ }
15368
+ },
15369
+ {
15370
+ $sort: {
15371
+ sortPriority: 1,
15372
+ ...sort
15373
+ }
15374
+ }
15375
+ );
15376
+ } else {
15377
+ basePipeline.push({
15378
+ $sort: sort
15379
+ });
15380
+ }
15381
+ basePipeline.push({ $skip: page * limit }, { $limit: limit });
15319
15382
  const [items, countResult] = await Promise.all([
15320
15383
  collection.aggregate(basePipeline, { session }).toArray(),
15321
15384
  collection.aggregate([{ $match: query }, { $count: "total" }], { session }).toArray()
@@ -17218,15 +17281,11 @@ function useVehicleService() {
17218
17281
  }
17219
17282
  }
17220
17283
  async function bulkUpsertVehicles(values, site, org) {
17221
- const session = import_node_server_utils75.useAtlas.getClient()?.startSession();
17222
- if (!session) {
17223
- throw new Error("Unable to start session for vehicle service.");
17224
- }
17225
17284
  try {
17226
17285
  if (!Array.isArray(values) || values.length === 0) {
17227
17286
  throw new Error("Vehicle list is required.");
17228
17287
  }
17229
- const now = (/* @__PURE__ */ new Date()).toISOString();
17288
+ const now = /* @__PURE__ */ new Date();
17230
17289
  const sanitizedValues = (await Promise.all(
17231
17290
  values.map(async (item) => {
17232
17291
  const plateNumber = Array.isArray(item.plateNumber) ? item.plateNumber[0] : item.plateNumber;
@@ -17241,7 +17300,7 @@ function useVehicleService() {
17241
17300
  ...item,
17242
17301
  org,
17243
17302
  site,
17244
- start: item.start ?? now,
17303
+ start: now.toISOString(),
17245
17304
  unit: unitId,
17246
17305
  plateNumber: typeof plateNumber === "string" ? plateNumber.trim().toUpperCase() : plateNumber
17247
17306
  };
@@ -17271,33 +17330,36 @@ function useVehicleService() {
17271
17330
  if (!siteCameras.length) {
17272
17331
  throw new Error("No site cameras found.");
17273
17332
  }
17274
- for (const vehicleValue of sanitizedValues) {
17275
- const plateNumber = vehicleValue.plateNumber;
17276
- const _mode = vehicleValue.type === "whitelist" /* WHITELIST */ ? "TrafficRedList" /* TRAFFIC_REDLIST */ : "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
17277
- for (const camera of siteCameras) {
17278
- const { host, username, password } = camera;
17279
- const dahuaPayload = {
17280
- host,
17281
- username,
17282
- password,
17283
- plateNumber,
17284
- mode: _mode,
17285
- ...vehicleValue.start ? { start: String(vehicleValue.start) } : {},
17286
- ...vehicleValue.end ? { end: String(vehicleValue.end) } : {},
17287
- ...vehicleValue.name ? { owner: vehicleValue.name } : {},
17288
- ...vehicleValue.vehicleModel ? { vehicleType: vehicleValue.vehicleModel } : {},
17289
- ...vehicleValue.vehicleColor ? { vehicleColor: vehicleValue.vehicleColor } : {}
17290
- };
17291
- const dahuaResponse = await _bulkInsertPlateNumber(dahuaPayload);
17292
- const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
17293
- vehicleValue.recNo = responseData.split("=")[1]?.trim();
17294
- }
17295
- }
17296
- return await _bulkUpsertVehicles(sanitizedValues, session);
17333
+ await Promise.all(
17334
+ sanitizedValues.map(async (vehicleValue) => {
17335
+ const plateNumber = vehicleValue.plateNumber;
17336
+ const _mode = vehicleValue.type === "whitelist" /* WHITELIST */ ? "TrafficRedList" /* TRAFFIC_REDLIST */ : "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
17337
+ const recNos = await Promise.all(
17338
+ siteCameras.map(async (camera) => {
17339
+ const { host, username, password } = camera;
17340
+ const dahuaPayload = {
17341
+ host,
17342
+ username,
17343
+ password,
17344
+ plateNumber,
17345
+ mode: _mode,
17346
+ ...vehicleValue.start ? { start: String(vehicleValue.start) } : {},
17347
+ ...vehicleValue.end ? { end: String(vehicleValue.end) } : {},
17348
+ ...vehicleValue.name ? { owner: vehicleValue.name } : {},
17349
+ ...vehicleValue.vehicleModel ? { vehicleType: vehicleValue.vehicleModel } : {},
17350
+ ...vehicleValue.vehicleColor ? { vehicleColor: vehicleValue.vehicleColor } : {}
17351
+ };
17352
+ const dahuaResponse = await _bulkInsertPlateNumber(dahuaPayload);
17353
+ const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
17354
+ return responseData.split("=")[1]?.trim();
17355
+ })
17356
+ );
17357
+ vehicleValue.recNo = recNos.find((r) => r) ?? void 0;
17358
+ })
17359
+ );
17360
+ return await _bulkUpsertVehicles(sanitizedValues);
17297
17361
  } catch (error) {
17298
17362
  throw error;
17299
- } finally {
17300
- session.endSession();
17301
17363
  }
17302
17364
  }
17303
17365
  return {
@@ -18086,7 +18148,8 @@ function useSiteController() {
18086
18148
  getSites: _getSites,
18087
18149
  getSiteById: _getSiteById,
18088
18150
  updateSiteBlock: _updateSiteBlock,
18089
- deleteSite: _deleteSite
18151
+ deleteSite: _deleteSite,
18152
+ getAllSitesForResidentCreation: _getAllSitesForResidentCreation
18090
18153
  } = useSiteRepo();
18091
18154
  const { updateGuardPostById, siteInformation: _siteInformation } = useSiteService();
18092
18155
  async function createSite(req, res, next) {
@@ -18271,14 +18334,13 @@ function useSiteController() {
18271
18334
  id: import_joi42.default.string().hex().required(),
18272
18335
  bgImage: import_joi42.default.string().optional().allow("", null),
18273
18336
  description: import_joi42.default.string().optional().allow("", null),
18274
- docs: import_joi42.default.array().items(import_joi42.default.object({
18275
- id: import_joi42.default.string().hex().optional().allow("", null),
18276
- name: import_joi42.default.string().optional().allow("", null)
18277
- })).optional().allow("", null)
18278
- }).validate(
18279
- { id, ...payload },
18280
- { abortEarly: false }
18281
- );
18337
+ docs: import_joi42.default.array().items(
18338
+ import_joi42.default.object({
18339
+ id: import_joi42.default.string().hex().optional().allow("", null),
18340
+ name: import_joi42.default.string().optional().allow("", null)
18341
+ })
18342
+ ).optional().allow("", null)
18343
+ }).validate({ id, ...payload }, { abortEarly: false });
18282
18344
  if (error) {
18283
18345
  import_node_server_utils78.logger.log({ level: "error", message: error.message });
18284
18346
  next(new import_node_server_utils78.BadRequestError(error.message));
@@ -18294,6 +18356,36 @@ function useSiteController() {
18294
18356
  return;
18295
18357
  }
18296
18358
  }
18359
+ async function getAllSitesForResidentCreation(req, res, next) {
18360
+ const validation = import_joi42.default.object({
18361
+ search: import_joi42.default.string().optional().allow("", null),
18362
+ page: import_joi42.default.number().integer().min(1).allow("", null).default(1),
18363
+ limit: import_joi42.default.number().integer().min(1).max(100).allow("", null).default(10)
18364
+ });
18365
+ const query = { ...req.query };
18366
+ const { error } = validation.validate(query);
18367
+ if (error) {
18368
+ import_node_server_utils78.logger.log({ level: "error", message: error.message });
18369
+ next(new import_node_server_utils78.BadRequestError(error.message));
18370
+ return;
18371
+ }
18372
+ const search = req.query.search ?? "";
18373
+ const page = parseInt(req.query.page ?? "1");
18374
+ const limit = parseInt(req.query.limit ?? "10");
18375
+ try {
18376
+ const data = await _getAllSitesForResidentCreation({
18377
+ search,
18378
+ page,
18379
+ limit
18380
+ });
18381
+ res.json(data);
18382
+ return;
18383
+ } catch (error2) {
18384
+ import_node_server_utils78.logger.log({ level: "error", message: error2.message });
18385
+ next(error2);
18386
+ return;
18387
+ }
18388
+ }
18297
18389
  return {
18298
18390
  createSite,
18299
18391
  getSites,
@@ -18302,7 +18394,8 @@ function useSiteController() {
18302
18394
  deleteSite,
18303
18395
  updateById,
18304
18396
  updateGuardPostsById,
18305
- siteInformation
18397
+ siteInformation,
18398
+ getAllSitesForResidentCreation
18306
18399
  };
18307
18400
  }
18308
18401
 
@@ -19331,6 +19424,7 @@ function useBuildingUnitController() {
19331
19424
  var import_node_server_utils87 = require("@7365admin1/node-server-utils");
19332
19425
  var import_joi46 = __toESM(require("joi"));
19333
19426
  var import_exceljs = __toESM(require("exceljs"));
19427
+ var import_csv_parser = __toESM(require("csv-parser"));
19334
19428
  var import_fs2 = __toESM(require("fs"));
19335
19429
  function useVehicleController() {
19336
19430
  const {
@@ -19375,8 +19469,15 @@ function useVehicleController() {
19375
19469
  };
19376
19470
  }
19377
19471
  function parseExpiryDate(value) {
19378
- if (!value)
19379
- return void 0;
19472
+ if (!value) {
19473
+ const today = /* @__PURE__ */ new Date();
19474
+ today.setFullYear(today.getFullYear() + 10);
19475
+ return today.toISOString();
19476
+ }
19477
+ const date = new Date(value);
19478
+ if (!isNaN(date.getTime())) {
19479
+ return date.toISOString();
19480
+ }
19380
19481
  const [day, monthStr, yearShort] = value.split("-");
19381
19482
  const months = {
19382
19483
  Jan: 0,
@@ -19396,19 +19497,17 @@ function useVehicleController() {
19396
19497
  if (month === void 0)
19397
19498
  return void 0;
19398
19499
  const year = 2e3 + Number(yearShort);
19399
- const date = new Date(year, month, Number(day));
19400
- return isNaN(date.getTime()) ? void 0 : date.toISOString();
19500
+ const fallbackDate = new Date(year, month, Number(day));
19501
+ return isNaN(fallbackDate.getTime()) ? void 0 : fallbackDate.toISOString();
19401
19502
  }
19402
- async function uploadExcelVehicles(req, res, next) {
19503
+ async function uploadSpreadsheetVehicles(req, res, next) {
19403
19504
  try {
19404
19505
  if (!req.file) {
19405
- next(new import_node_server_utils87.BadRequestError("Excel file is required."));
19406
- return;
19407
- }
19408
- if (!req.file.originalname.toLowerCase().endsWith(".xlsx")) {
19409
- next(new import_node_server_utils87.BadRequestError("Only .xlsx files are allowed."));
19506
+ next(new import_node_server_utils87.BadRequestError("Spreadsheet file is required."));
19410
19507
  return;
19411
19508
  }
19509
+ const { originalname, path: path4 } = req.file;
19510
+ const lowerName = originalname.toLowerCase();
19412
19511
  const rowSchema = import_joi46.default.object({
19413
19512
  fullName: import_joi46.default.string().trim().required(),
19414
19513
  userType: import_joi46.default.string().trim().required(),
@@ -19420,7 +19519,11 @@ function useVehicleController() {
19420
19519
  plateNumber: import_joi46.default.string().trim().uppercase().required(),
19421
19520
  vehicleModel: import_joi46.default.string().trim().allow("", null).optional(),
19422
19521
  vehicleColor: import_joi46.default.string().trim().allow("", null).optional(),
19423
- subscriptionExpiry: import_joi46.default.string().trim().allow("", null).optional()
19522
+ subscriptionExpiry: import_joi46.default.alternatives().try(
19523
+ import_joi46.default.date().iso(),
19524
+ // ISO format
19525
+ import_joi46.default.string().pattern(/^\d{1,2}-[A-Za-z]{3}-\d{2}$/)
19526
+ ).allow("", null).optional()
19424
19527
  });
19425
19528
  const querySchema = import_joi46.default.object({
19426
19529
  site: import_joi46.default.string().hex().length(24).required(),
@@ -19428,10 +19531,7 @@ function useVehicleController() {
19428
19531
  });
19429
19532
  const { error: queryError, value: queryValue } = querySchema.validate(
19430
19533
  req.query,
19431
- {
19432
- abortEarly: false,
19433
- convert: true
19434
- }
19534
+ { abortEarly: false, convert: true }
19435
19535
  );
19436
19536
  if (queryError) {
19437
19537
  next(
@@ -19442,30 +19542,43 @@ function useVehicleController() {
19442
19542
  return;
19443
19543
  }
19444
19544
  const { site, org } = queryValue;
19445
- const workbook = new import_exceljs.default.Workbook();
19446
- await workbook.xlsx.readFile(req.file.path);
19447
- const worksheet = workbook.worksheets[0];
19448
- if (!worksheet) {
19449
- next(new import_node_server_utils87.BadRequestError("No worksheet found in uploaded Excel file."));
19450
- return;
19451
- }
19452
- const rows = [];
19453
- const headerRow = worksheet.getRow(1);
19454
- const headers = (headerRow.values || []).slice(1).map((header) => String(header ?? "").trim());
19455
- worksheet.eachRow((row, rowNumber) => {
19456
- if (rowNumber === 1)
19545
+ let rows = [];
19546
+ if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
19547
+ const workbook = new import_exceljs.default.Workbook();
19548
+ await workbook.xlsx.readFile(path4);
19549
+ const worksheet = workbook.worksheets[0];
19550
+ if (!worksheet) {
19551
+ next(
19552
+ new import_node_server_utils87.BadRequestError("No worksheet found in uploaded Excel file.")
19553
+ );
19457
19554
  return;
19458
- const rowData = {};
19459
- headers.forEach((header, index) => {
19460
- rowData[header] = row.getCell(index + 1).value ?? "";
19555
+ }
19556
+ const headerRow = worksheet.getRow(1);
19557
+ const headers = (headerRow.values || []).slice(1).map((header) => String(header ?? "").trim());
19558
+ worksheet.eachRow((row, rowNumber) => {
19559
+ if (rowNumber === 1)
19560
+ return;
19561
+ const rowData = {};
19562
+ headers.forEach((header, index) => {
19563
+ rowData[header] = row.getCell(index + 1).value ?? "";
19564
+ });
19565
+ if (Object.values(rowData).some(
19566
+ (v) => v !== "" && v !== null && v !== void 0
19567
+ )) {
19568
+ rows.push(rowData);
19569
+ }
19570
+ });
19571
+ } else if (lowerName.endsWith(".csv")) {
19572
+ rows = await new Promise((resolve, reject) => {
19573
+ const parsed = [];
19574
+ import_fs2.default.createReadStream(path4).pipe((0, import_csv_parser.default)()).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
19461
19575
  });
19462
- const hasValue = Object.values(rowData).some(
19463
- (value) => value !== null && value !== void 0 && value !== ""
19576
+ } else {
19577
+ next(
19578
+ new import_node_server_utils87.BadRequestError("Only .xlsx, .xls, or .csv files are allowed.")
19464
19579
  );
19465
- if (hasValue) {
19466
- rows.push(rowData);
19467
- }
19468
- });
19580
+ return;
19581
+ }
19469
19582
  const validRows = [];
19470
19583
  const invalidRows = [];
19471
19584
  rows.forEach((row, index) => {
@@ -19479,9 +19592,9 @@ function useVehicleController() {
19479
19592
  data: row,
19480
19593
  errors: error.details.map((d) => d.message)
19481
19594
  });
19482
- return;
19595
+ } else {
19596
+ validRows.push(value);
19483
19597
  }
19484
- validRows.push(value);
19485
19598
  });
19486
19599
  const vehicles = validRows.map((row) => mapRowToVehicle(row, site, org));
19487
19600
  let data = {};
@@ -19489,15 +19602,15 @@ function useVehicleController() {
19489
19602
  data = await _bulkUpsertVehicles(vehicles, site, org);
19490
19603
  }
19491
19604
  res.status(200).json({
19492
- message: "Excel import completed.",
19493
- sheetName: worksheet.name,
19605
+ message: "Spreadsheet import completed.",
19606
+ fileName: originalname,
19494
19607
  totalRows: rows.length,
19495
19608
  validRows: validRows.length,
19496
19609
  invalidRows: invalidRows.length,
19497
19610
  validationErrors: invalidRows,
19498
19611
  data
19499
19612
  });
19500
- import_fs2.default.unlink(req.file.path, () => {
19613
+ import_fs2.default.unlink(path4, () => {
19501
19614
  });
19502
19615
  } catch (error) {
19503
19616
  import_node_server_utils87.logger.log({ level: "error", message: error.message });
@@ -19839,8 +19952,7 @@ function useVehicleController() {
19839
19952
  getVehiclesByNRIC,
19840
19953
  reactivateVehicleById,
19841
19954
  getAllVehiclesByUnitId,
19842
- // uploadCsvVehicles,
19843
- uploadExcelVehicles
19955
+ uploadSpreadsheetVehicles
19844
19956
  };
19845
19957
  }
19846
19958
 
@@ -22249,11 +22361,6 @@ var KeyRepo = class {
22249
22361
  } else if (organization) {
22250
22362
  defaultQuery = { organization };
22251
22363
  }
22252
- console.log("key-query: ", {
22253
- ...defaultQuery,
22254
- ...searchQuery,
22255
- ...dateFilter
22256
- });
22257
22364
  try {
22258
22365
  const result = await this.collection().aggregate([
22259
22366
  {
@@ -22766,14 +22873,28 @@ function useVisitorTransactionService() {
22766
22873
  const host = camera.host;
22767
22874
  const username = camera.username;
22768
22875
  const password = camera.password;
22769
- const mode = "TrafficRedList" /* TRAFFIC_REDLIST */;
22876
+ const redlist = "TrafficRedList" /* TRAFFIC_REDLIST */;
22877
+ const blacklist = "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
22770
22878
  const _plateNumber = value.plateNumber;
22879
+ const dahuaBlocklistQuery = {
22880
+ host,
22881
+ username,
22882
+ password,
22883
+ plateNumber: _plateNumber,
22884
+ mode: blacklist
22885
+ };
22886
+ const isBlocklistedRaw = await _getPlateNumber(dahuaBlocklistQuery);
22887
+ const rawString = isBlocklistedRaw?.toString?.("utf-8") ?? String(isBlocklistedRaw);
22888
+ const foundMatch = rawString.match(/found=(\d+)/);
22889
+ const found = foundMatch ? Number(foundMatch[1]) : 0;
22890
+ if (found === 1)
22891
+ throw new import_node_server_utils102.BadRequestError("This plate number is blocklisted");
22771
22892
  const dahuaQuery = {
22772
22893
  host,
22773
22894
  username,
22774
22895
  password,
22775
22896
  plateNumber: _plateNumber,
22776
- mode
22897
+ mode: redlist
22777
22898
  };
22778
22899
  const raw = await _getPlateNumber(dahuaQuery);
22779
22900
  const parsed = parseDahuaFind(raw);
@@ -22783,7 +22904,7 @@ function useVisitorTransactionService() {
22783
22904
  username,
22784
22905
  password,
22785
22906
  plateNumber: _plateNumber,
22786
- mode,
22907
+ mode: redlist,
22787
22908
  start: startDahuaDate,
22788
22909
  end: endDahuaDate,
22789
22910
  owner: value.name ?? "",
@@ -22819,7 +22940,7 @@ function useVisitorTransactionService() {
22819
22940
  password,
22820
22941
  plateNumber: _plateNumber,
22821
22942
  recno: parsed.recNo,
22822
- mode,
22943
+ mode: redlist,
22823
22944
  start: startDahuaDate,
22824
22945
  end: endDahuaDate,
22825
22946
  owner: value.name ?? "",
@@ -22928,6 +23049,14 @@ function useVisitorTransactionService() {
22928
23049
  }
22929
23050
  value.passKeys = keptPassKeys;
22930
23051
  }
23052
+ if (value.checkIn) {
23053
+ const parsed = new Date(value.checkIn);
23054
+ value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
23055
+ }
23056
+ if (value.checkOut) {
23057
+ const parsed = new Date(value.checkOut);
23058
+ value.checkOut = isNaN(parsed.getTime()) ? null : parsed;
23059
+ }
22931
23060
  await _updateVisitorTansactionById(id, value, session);
22932
23061
  await session?.commitTransaction();
22933
23062
  return "Successfully updated visitor transaction.";
@@ -23927,10 +24056,11 @@ function usePersonService() {
23927
24056
  email: value.email,
23928
24057
  password: hashedPassword,
23929
24058
  name: value.name,
24059
+ status: value.platform == "mobile" ? "deleted" : "active",
23930
24060
  defaultOrg: value.org?.toString() || ""
23931
24061
  };
23932
24062
  const userId = await addUser(user, session);
23933
- value.user = userId;
24063
+ value.user = userId.toString();
23934
24064
  let org = null;
23935
24065
  if (userId) {
23936
24066
  if (value?.org) {
@@ -24231,7 +24361,6 @@ function usePersonController() {
24231
24361
  }
24232
24362
  async function getPeopleByUnit(req, res, next) {
24233
24363
  const PERSON_TYPES3 = Object.values(PersonTypes);
24234
- console.log(req.query);
24235
24364
  try {
24236
24365
  const schema2 = import_joi58.default.object({
24237
24366
  unit: import_joi58.default.string().required(),
@@ -29512,7 +29641,7 @@ function useBulletinBoardController() {
29512
29641
  page: import_joi76.default.number().integer().min(1).allow("", null).default(1),
29513
29642
  limit: import_joi76.default.number().integer().min(1).max(100).allow("", null).default(10),
29514
29643
  sort: import_joi76.default.string().valid(...Object.values(BulletinSort)).default("_id" /* ID */),
29515
- order: import_joi76.default.string().valid(...Object.values(SortOrder)).default("asc" /* ASC */),
29644
+ order: import_joi76.default.string().valid(...Object.values(SortOrder)).default("desc" /* DESC */),
29516
29645
  site: import_joi76.default.string().hex().length(24).required(),
29517
29646
  status: import_joi76.default.string().valid(...Object.values(BuildingStatus)).optional().default("active" /* ACTIVE */),
29518
29647
  recipients: import_joi76.default.alternatives().try(
@@ -32834,7 +32963,11 @@ var formatEntryPassDate = (date) => {
32834
32963
  const day = String(newDate.getDate()).padStart(2, "0");
32835
32964
  return `${year}${month}${day}`;
32836
32965
  };
32837
- async function removeAccessGroup({ cardNo, staffNo, url }) {
32966
+ async function removeAccessGroup({
32967
+ cardNo,
32968
+ staffNo,
32969
+ url
32970
+ }) {
32838
32971
  try {
32839
32972
  const commands = readTemplate("delete-qr-card", {
32840
32973
  staffNo,
@@ -32855,8 +32988,6 @@ async function removeAccessGroup({ cardNo, staffNo, url }) {
32855
32988
  });
32856
32989
  const response = await sendCommand(commands, url);
32857
32990
  const result = await (0, import_xml2js.parseStringPromise)(response, { explicitArray: false });
32858
- console.log(result.RESULT.$.STCODE);
32859
- console.log(commands);
32860
32991
  if (result && result.RESULT.$.STCODE !== "0") {
32861
32992
  throw new Error("Command failed, server error.");
32862
32993
  }
@@ -38569,7 +38700,6 @@ function useStatementOfAccountController() {
38569
38700
  try {
38570
38701
  const _id = req.params.id;
38571
38702
  const status = req.params.status;
38572
- console.log(_id, status);
38573
38703
  const result = await _updateStatusById(_id, { status });
38574
38704
  res.status(200).json({ message: result });
38575
38705
  return;
@@ -44209,6 +44339,25 @@ function useManpowerMonitoringRepo() {
44209
44339
  const namespace_collection = "manpower-settings";
44210
44340
  const collection = db.collection(namespace_collection);
44211
44341
  const serviceProviderCollection = db.collection("site.service-providers");
44342
+ async function createIndexes() {
44343
+ try {
44344
+ await collection.createIndexes([
44345
+ {
44346
+ key: { siteId: 1 }
44347
+ },
44348
+ { key: { createdAt: 1 } }
44349
+ ]);
44350
+ return `Successfully created indexes for ${namespace_collection}.`;
44351
+ } catch (error) {
44352
+ import_node_server_utils197.logger.log({
44353
+ level: "error",
44354
+ message: error.message
44355
+ });
44356
+ throw new import_node_server_utils197.InternalServerError(
44357
+ "Failed to create general indexes on manpower monitoring."
44358
+ );
44359
+ }
44360
+ }
44212
44361
  async function createManpowerMonitoringSettings(value, session) {
44213
44362
  try {
44214
44363
  value = new MManpowerMonitoring(value);
@@ -44385,7 +44534,8 @@ function useManpowerMonitoringRepo() {
44385
44534
  getManpowerSettingsBySiteId,
44386
44535
  updateManpowerMonitoringSettings,
44387
44536
  multipleManpowerMonitoringSettings,
44388
- getAllSites
44537
+ getAllSites,
44538
+ createIndexes
44389
44539
  };
44390
44540
  }
44391
44541
 
@@ -44448,6 +44598,25 @@ function useManpowerRemarksRepo() {
44448
44598
  }
44449
44599
  const namespace_collection = "manpower-remarks";
44450
44600
  const collection = db.collection(namespace_collection);
44601
+ async function createIndexes() {
44602
+ try {
44603
+ await collection.createIndexes([
44604
+ {
44605
+ key: { siteId: 1 }
44606
+ },
44607
+ { key: { createdAt: 1 } }
44608
+ ]);
44609
+ return `Successfully created indexes for ${namespace_collection}.`;
44610
+ } catch (error) {
44611
+ import_node_server_utils198.logger.log({
44612
+ level: "error",
44613
+ message: error.message
44614
+ });
44615
+ throw new import_node_server_utils198.InternalServerError(
44616
+ "Failed to create general indexes on manpower remarks."
44617
+ );
44618
+ }
44619
+ }
44451
44620
  async function createManpowerRemarks(value, session) {
44452
44621
  try {
44453
44622
  value = new MManpowerRemarks(value);
@@ -44570,7 +44739,8 @@ function useManpowerRemarksRepo() {
44570
44739
  getManpowerRemarksAllSite,
44571
44740
  getManpowerRemarksBySiteId,
44572
44741
  updateManpowerRemarks,
44573
- updateRemarksStatus
44742
+ updateRemarksStatus,
44743
+ createIndexes
44574
44744
  };
44575
44745
  }
44576
44746
 
@@ -44582,7 +44752,6 @@ function useManpowerMonitoringSrvc() {
44582
44752
  } = useManpowerMonitoringRepo();
44583
44753
  const { createManpowerRemarks: _createManpowerRemarks } = useManpowerRemarksRepo();
44584
44754
  async function createManpowerMonitoringSettings(payload) {
44585
- console.log("Im here now at service");
44586
44755
  const session = import_node_server_utils199.useAtlas.getClient()?.startSession();
44587
44756
  if (!session) {
44588
44757
  throw new import_node_server_utils199.BadRequestError("Database session not available.");
@@ -44598,7 +44767,6 @@ function useManpowerMonitoringSrvc() {
44598
44767
  const afternoonAlertTime = afternoonCheckInTime ? import_moment_timezone3.default.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
44599
44768
  const nightAlertTime = import_moment_timezone3.default.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
44600
44769
  const nowSGT = (0, import_moment_timezone3.default)().tz("Asia/Singapore");
44601
- console.log("im done preparing the payload");
44602
44770
  try {
44603
44771
  const remarksPayload = {
44604
44772
  siteId: payload.siteId,
@@ -44757,7 +44925,6 @@ function useManpowerMonitoringCtrl() {
44757
44925
  });
44758
44926
  const _id = req.params.id;
44759
44927
  const payload = { ...req.body };
44760
- console.log("_id", _id);
44761
44928
  const { error } = validation.validate({ _id, ...payload });
44762
44929
  if (error) {
44763
44930
  next(new import_node_server_utils200.BadRequestError(error.message));
@@ -44860,6 +45027,25 @@ function useManpowerDesignationRepo() {
44860
45027
  }
44861
45028
  const namespace_collection = "manpower-designations";
44862
45029
  const collection = db.collection(namespace_collection);
45030
+ async function createIndexes() {
45031
+ try {
45032
+ await collection.createIndexes([
45033
+ {
45034
+ key: { siteId: 1 }
45035
+ },
45036
+ { key: { createdAt: 1 } }
45037
+ ]);
45038
+ return `Successfully created indexes for ${namespace_collection}.`;
45039
+ } catch (error) {
45040
+ import_node_server_utils201.logger.log({
45041
+ level: "error",
45042
+ message: error.message
45043
+ });
45044
+ throw new import_node_server_utils201.InternalServerError(
45045
+ "Failed to create general indexes on manpower designations."
45046
+ );
45047
+ }
45048
+ }
44863
45049
  async function createManpowerDesignations(value) {
44864
45050
  try {
44865
45051
  value = new MManpowerDesignations(value);
@@ -44915,7 +45101,8 @@ function useManpowerDesignationRepo() {
44915
45101
  return {
44916
45102
  createManpowerDesignations,
44917
45103
  getManpowerDesignationsBySiteId,
44918
- updateManpowerDesignations
45104
+ updateManpowerDesignations,
45105
+ createIndexes
44919
45106
  };
44920
45107
  }
44921
45108