@7365admin1/core 3.26.0 → 3.28.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
@@ -9141,6 +9141,31 @@ function useUserRepo() {
9141
9141
  throw new import_node_server_utils10.InternalServerError("Failed to update user organization.");
9142
9142
  }
9143
9143
  }
9144
+ async function updateUserUnitById(id, value, session) {
9145
+ const _id = (0, import_node_server_utils10.toObjectId)(id);
9146
+ const update = {};
9147
+ if ("block" in value)
9148
+ update.block = value.block ?? null;
9149
+ if ("level" in value)
9150
+ update.level = value.level ?? null;
9151
+ if ("unitId" in value)
9152
+ update.unitId = value.unitId ?? null;
9153
+ if ("unitName" in value)
9154
+ update.unitName = value.unitName ?? "";
9155
+ if (Object.keys(update).length === 0) {
9156
+ return "No user unit fields to update.";
9157
+ }
9158
+ try {
9159
+ await collection.updateOne(
9160
+ { _id },
9161
+ { $set: { ...update, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
9162
+ { session }
9163
+ );
9164
+ return "Successfully updated user unit information.";
9165
+ } catch (error) {
9166
+ throw new import_node_server_utils10.InternalServerError("Failed to update user unit information.");
9167
+ }
9168
+ }
9144
9169
  return {
9145
9170
  createIndex,
9146
9171
  createTextIndex,
@@ -9159,7 +9184,8 @@ function useUserRepo() {
9159
9184
  getUserByEmailStatus,
9160
9185
  updateUserSIDById,
9161
9186
  resetPassword,
9162
- updateUserOrgById
9187
+ updateUserOrgById,
9188
+ updateUserUnitById
9163
9189
  };
9164
9190
  }
9165
9191
 
@@ -25401,6 +25427,10 @@ function usePersonRepo() {
25401
25427
  }
25402
25428
  async function getByNRIC(value) {
25403
25429
  try {
25430
+ if (!value || value.trim() === "") {
25431
+ import_node_server_utils74.logger.warn("getByNRIC called with an empty or invalid NRIC value.");
25432
+ return null;
25433
+ }
25404
25434
  const cacheKey = (0, import_node_server_utils74.makeCacheKey)(site_people_namespace_collection, {
25405
25435
  nric: value
25406
25436
  });
@@ -25449,8 +25479,11 @@ function usePersonRepo() {
25449
25479
  unit
25450
25480
  }, session) {
25451
25481
  try {
25482
+ if (!unit || !import_mongodb45.ObjectId.isValid(unit)) {
25483
+ throw new import_node_server_utils74.BadRequestError("Invalid unit ID.");
25484
+ }
25452
25485
  const query = {
25453
- unit,
25486
+ unit: new import_mongodb45.ObjectId(unit),
25454
25487
  status,
25455
25488
  ...Array.isArray(type) && type.length > 0 && {
25456
25489
  type: { $in: type }
@@ -26419,18 +26452,7 @@ function useBuildingUnitRepo() {
26419
26452
  } catch (error) {
26420
26453
  throw new import_node_server_utils76.BadRequestError("Invalid ID.");
26421
26454
  }
26422
- const cacheKey = (0, import_node_server_utils76.makeCacheKey)(building_units_namespace_collection, {
26423
- _id: String(_id)
26424
- });
26425
26455
  try {
26426
- const cached = await getCache(cacheKey);
26427
- if (cached) {
26428
- import_node_server_utils76.logger.log({
26429
- level: "info",
26430
- message: `Cache hit for getById building unit: ${cacheKey}`
26431
- });
26432
- return cached;
26433
- }
26434
26456
  const result = await collection.findOne({
26435
26457
  _id,
26436
26458
  deletedAt: { $in: ["", null] }
@@ -26438,17 +26460,6 @@ function useBuildingUnitRepo() {
26438
26460
  if (!result) {
26439
26461
  throw new import_node_server_utils76.BadRequestError("Building unit not found.");
26440
26462
  }
26441
- setCache(cacheKey, result, 300).then(() => {
26442
- import_node_server_utils76.logger.log({
26443
- level: "info",
26444
- message: `Cache set for building unit by id: ${cacheKey}`
26445
- });
26446
- }).catch((err) => {
26447
- import_node_server_utils76.logger.log({
26448
- level: "error",
26449
- message: `Failed to set cache for building unit by id: ${err.message}`
26450
- });
26451
- });
26452
26463
  return result;
26453
26464
  } catch (error) {
26454
26465
  if (error instanceof import_node_server_utils76.AppError) {
@@ -34904,7 +34915,7 @@ function useVisitorTransactionService() {
34904
34915
  const unit = await _getUnitById(value.unit);
34905
34916
  value.unitName = unit?.name;
34906
34917
  }
34907
- if (allowedPersonTypes.includes(value?.type)) {
34918
+ if (allowedPersonTypes.includes(value?.type) && value?.nric) {
34908
34919
  const nric = value?.nric || "";
34909
34920
  const person = await getByNRIC(nric);
34910
34921
  const existingCompanyName = person?.companyName?.includes(
@@ -35136,6 +35147,103 @@ function useVisitorTransactionService() {
35136
35147
  let host;
35137
35148
  let username;
35138
35149
  let password;
35150
+ if (value.checkIn) {
35151
+ const parsed = new Date(value.checkIn);
35152
+ value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
35153
+ }
35154
+ if (value.isMembersAdded != true && Array.isArray(value.members) && value.members.length > 0) {
35155
+ const chunkSize = 10;
35156
+ const {
35157
+ block,
35158
+ level,
35159
+ unit,
35160
+ site,
35161
+ org,
35162
+ type,
35163
+ company,
35164
+ remarks,
35165
+ contractorType,
35166
+ unitName
35167
+ } = value;
35168
+ for (let i = 0; i < value.members.length; i += chunkSize) {
35169
+ const chunk = value.members.slice(i, i + chunkSize);
35170
+ await Promise.all(
35171
+ chunk.map(async (member) => {
35172
+ const clonedMember = structuredClone(member);
35173
+ const { visitorPass, passKeys } = clonedMember;
35174
+ const preparedVisitorPass = Array.isArray(visitorPass) ? visitorPass.map((item) => ({
35175
+ ...item,
35176
+ receivedDate: /* @__PURE__ */ new Date(),
35177
+ status: "Not Returned" /* NOT_RETURNED */,
35178
+ lastUpdate: null,
35179
+ remarks: ""
35180
+ })) : [];
35181
+ const preparedPassKeys = Array.isArray(passKeys) ? passKeys.map((item) => ({
35182
+ ...item,
35183
+ receivedDate: /* @__PURE__ */ new Date(),
35184
+ status: "Not Returned" /* NOT_RETURNED */,
35185
+ lastUpdate: null,
35186
+ remarks: ""
35187
+ })) : [];
35188
+ const visitorId = await _add(
35189
+ {
35190
+ ...clonedMember,
35191
+ block,
35192
+ level,
35193
+ unit,
35194
+ unitName,
35195
+ site,
35196
+ org,
35197
+ type,
35198
+ company,
35199
+ remarks,
35200
+ contractorType,
35201
+ checkIn: value.checkIn,
35202
+ visitorPass: preparedVisitorPass,
35203
+ passKeys: preparedPassKeys,
35204
+ status: "registered" /* REGISTERED */
35205
+ },
35206
+ session
35207
+ );
35208
+ console.log("visitorId service", visitorId);
35209
+ for (const item of preparedVisitorPass) {
35210
+ await KeyRepo.checkPassOrKeyAvailability(item.keyId, "Pass", session);
35211
+ await KeyRepo.updateKeyById(
35212
+ item.keyId,
35213
+ {
35214
+ status: "In Use" /* IN_USE */,
35215
+ updatedBy: value.createdBy
35216
+ },
35217
+ value.site,
35218
+ session,
35219
+ void 0,
35220
+ visitorId,
35221
+ void 0,
35222
+ true
35223
+ );
35224
+ }
35225
+ for (const item of preparedPassKeys) {
35226
+ await KeyRepo.checkPassOrKeyAvailability(item.keyId, "Key", session);
35227
+ await KeyRepo.updateKeyById(
35228
+ item.keyId,
35229
+ {
35230
+ status: "In Use" /* IN_USE */,
35231
+ updatedBy: value.createdBy,
35232
+ visitorId
35233
+ },
35234
+ value.site,
35235
+ session,
35236
+ void 0,
35237
+ visitorId,
35238
+ void 0,
35239
+ true
35240
+ );
35241
+ }
35242
+ })
35243
+ );
35244
+ }
35245
+ value.isMembersAdded = true;
35246
+ }
35139
35247
  if (value.site && value.plateNumber) {
35140
35248
  try {
35141
35249
  camera = await _getVisitorsInBySite(value.site);
@@ -35169,10 +35277,6 @@ function useVisitorTransactionService() {
35169
35277
  if (found === 1)
35170
35278
  throw new import_node_server_utils107.BadRequestError("This plate number is blocklisted");
35171
35279
  }
35172
- if (value.checkIn) {
35173
- const parsed = new Date(value.checkIn);
35174
- value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
35175
- }
35176
35280
  if (value.checkOut) {
35177
35281
  const parsed = new Date(value.checkOut);
35178
35282
  value.checkOut = isNaN(parsed.getTime()) ? null : parsed;
@@ -36216,7 +36320,8 @@ function usePersonService() {
36216
36320
  getUserByEmail,
36217
36321
  updateUserFieldById: _updateUserFieldById,
36218
36322
  getUserById,
36219
- updateUserOrgById: _updateUserOrgById
36323
+ updateUserOrgById: _updateUserOrgById,
36324
+ updateUserUnitById: _updateUserUnitById
36220
36325
  } = useUserRepo();
36221
36326
  const { add: addMember } = useMemberRepo();
36222
36327
  const { getById: _getUnitById, updateById: updateUnitById } = useBuildingUnitRepo();
@@ -36363,6 +36468,10 @@ function usePersonService() {
36363
36468
  value.unit = new import_mongodb66.ObjectId(value.unit);
36364
36469
  }
36365
36470
  const isOrgChanged = value.org && person.org?.toString() !== value.org.toString();
36471
+ const toKey = (v) => v === null || v === void 0 || v === "" ? "" : v.toString();
36472
+ const isBlockChanged = "block" in value && toKey(value.block) !== toKey(person.block);
36473
+ const isLevelChanged = "level" in value && toKey(value.level) !== toKey(person.level);
36474
+ const isUnitChanged = "unit" in value && toKey(value.unit) !== toKey(person.unit);
36366
36475
  await _updateById(_id, value, session);
36367
36476
  if (isOrgChanged && person.user) {
36368
36477
  await _updateUserOrgById(
@@ -36371,6 +36480,26 @@ function usePersonService() {
36371
36480
  session
36372
36481
  );
36373
36482
  }
36483
+ if ((isBlockChanged || isLevelChanged || isUnitChanged) && person.user) {
36484
+ const userUnitPayload = {};
36485
+ if (isBlockChanged) {
36486
+ userUnitPayload.block = value.block ?? null;
36487
+ }
36488
+ if (isLevelChanged) {
36489
+ userUnitPayload.level = value.level ?? null;
36490
+ }
36491
+ if (isUnitChanged) {
36492
+ userUnitPayload.unitId = value.unit ?? null;
36493
+ if ("unitName" in value) {
36494
+ userUnitPayload.unitName = value.unitName ?? "";
36495
+ }
36496
+ }
36497
+ await _updateUserUnitById(
36498
+ person.user.toString(),
36499
+ userUnitPayload,
36500
+ session
36501
+ );
36502
+ }
36374
36503
  if (value.unit && (isNameUpdated || isOwnerChanged || value.isOwner)) {
36375
36504
  const unit = await _getUnitById(value.unit.toString());
36376
36505
  if (unit) {
@@ -36400,6 +36529,16 @@ function usePersonService() {
36400
36529
  }
36401
36530
  }
36402
36531
  }
36532
+ if (isUnitChanged && person.isOwner && person.unit) {
36533
+ const previousUnit = await _getUnitById(person.unit.toString());
36534
+ if (previousUnit && previousUnit._id && previousUnit.owner?.toString() === person?._id?.toString()) {
36535
+ await updateUnitById(
36536
+ previousUnit._id.toString(),
36537
+ { owner: "", ownerName: "" },
36538
+ session
36539
+ );
36540
+ }
36541
+ }
36403
36542
  await session.commitTransaction();
36404
36543
  return "Person updated successfully.";
36405
36544
  } catch (error) {
@@ -45304,7 +45443,6 @@ function useSiteUnitBillingService() {
45304
45443
  const { getAll, updateById: _updateById } = useSiteBillingItemRepo();
45305
45444
  const { getBuildingUnitsWithOwner: _getBuildingUnitsWithOwner } = useBuildingUnitRepo();
45306
45445
  async function processBilling() {
45307
- console.log("Starting billing process...");
45308
45446
  const billing_items = await getAll({
45309
45447
  search: "",
45310
45448
  page: 1,
@@ -45347,7 +45485,7 @@ function useSiteUnitBillingService() {
45347
45485
  const buildUnitBilling = (unit) => ({
45348
45486
  site: billing_item.site.toString(),
45349
45487
  org: billing_item.org.toString(),
45350
- billItem: billing_item._id,
45488
+ billItem: billing_item._id?.toString(),
45351
45489
  billName: billing_item.name,
45352
45490
  unitId: unit._id.toString(),
45353
45491
  unit: unit.blockName + " / " + unit.levelName + " / " + unit.name,
@@ -45381,6 +45519,9 @@ function useSiteUnitBillingService() {
45381
45519
  level: "error",
45382
45520
  message: `Failed to proccess cron billing: ${error.message}`
45383
45521
  });
45522
+ if (session.inTransaction()) {
45523
+ await session.abortTransaction();
45524
+ }
45384
45525
  continue;
45385
45526
  } finally {
45386
45527
  session.endSession();
@@ -45435,6 +45576,7 @@ function useSiteUnitBillingService() {
45435
45576
  const billingMonth = Number(billing_item.month);
45436
45577
  const billingDay = Number(billing_item.date);
45437
45578
  if (billing_item.frequency === "monthly" /* MONTHLY */) {
45579
+ console.log("billing_item", billing_item.name);
45438
45580
  return todayDate === billingDay;
45439
45581
  }
45440
45582
  if (billing_item.frequency === "quarterly" /* QAURTERLY */) {
@@ -46566,7 +46708,7 @@ function UseAccessManagementRepo() {
46566
46708
  $lookup: {
46567
46709
  from: "building-levels",
46568
46710
  localField: "_id",
46569
- foreignField: "block",
46711
+ foreignField: "blockId",
46570
46712
  pipeline: [
46571
46713
  { $match: { status: { $ne: "deleted" } } },
46572
46714
  {
@@ -46587,7 +46729,7 @@ function UseAccessManagementRepo() {
46587
46729
  {
46588
46730
  $project: {
46589
46731
  _id: 1,
46590
- level: 1,
46732
+ name: 1,
46591
46733
  units: 1
46592
46734
  }
46593
46735
  }
@@ -46748,7 +46890,7 @@ function UseAccessManagementRepo() {
46748
46890
  $project: {
46749
46891
  _id: "$level.units._id",
46750
46892
  name: "$level.units.name",
46751
- level: { _id: "$level._id", level: "$level.level" },
46893
+ level: { _id: "$level._id", level: "$level.name" },
46752
46894
  block: { _id: "$_id", name: "$name", block: "$block" },
46753
46895
  site: "$site",
46754
46896
  unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
@@ -47872,7 +48014,8 @@ function UseAccessManagementRepo() {
47872
48014
  remarks: 1,
47873
48015
  requestDate: 1,
47874
48016
  createdAt: 1,
47875
- updatedAt: 1
48017
+ updatedAt: 1,
48018
+ userCred: 1
47876
48019
  }
47877
48020
  }
47878
48021
  );
@@ -48168,7 +48311,7 @@ function UseAccessManagementRepo() {
48168
48311
  const unitId = new import_mongodb97.ObjectId(params.unitId);
48169
48312
  const quantity = params.quantity;
48170
48313
  const type = params.type;
48171
- const visitorId = new import_mongodb97.ObjectId(params.visitorId);
48314
+ const visitorId = new import_mongodb97.ObjectId(params.user?.visitorId);
48172
48315
  const nfcCards = params.nfcCards;
48173
48316
  const acm_url = params.acm_url;
48174
48317
  let cards = [];
@@ -48215,7 +48358,10 @@ function UseAccessManagementRepo() {
48215
48358
  const updateFields = {
48216
48359
  staffNo: `STAFF-${cardId.toString().slice(-10)}`,
48217
48360
  updatedAt: /* @__PURE__ */ new Date(),
48218
- userId: updatedVisitor
48361
+ userId: updatedVisitor,
48362
+ userCred: {
48363
+ ...params.user
48364
+ }
48219
48365
  };
48220
48366
  if (type === "QRCODE" /* QR */) {
48221
48367
  updateFields.one_time = true;
@@ -48357,7 +48503,7 @@ function UseAccessManagementRepo() {
48357
48503
  $lookup: {
48358
48504
  from: "building-levels",
48359
48505
  localField: "_id",
48360
- foreignField: "block",
48506
+ foreignField: "blockId",
48361
48507
  as: "levels",
48362
48508
  pipeline: [
48363
48509
  {
@@ -50221,7 +50367,7 @@ function useAccessManagementController() {
50221
50367
  quantity = 1,
50222
50368
  type,
50223
50369
  nfcCards,
50224
- visitorId,
50370
+ user,
50225
50371
  acm_url
50226
50372
  } = req.body;
50227
50373
  const schema2 = import_joi87.default.object({
@@ -50236,7 +50382,7 @@ function useAccessManagementController() {
50236
50382
  })
50237
50383
  ).required(),
50238
50384
  acm_url: import_joi87.default.string().required(),
50239
- visitorId: import_joi87.default.string().hex().length(24).required()
50385
+ user: import_joi87.default.object().optional().allow("", null)
50240
50386
  });
50241
50387
  const { error } = schema2.validate({
50242
50388
  site,
@@ -50244,7 +50390,7 @@ function useAccessManagementController() {
50244
50390
  quantity,
50245
50391
  type,
50246
50392
  nfcCards,
50247
- visitorId,
50393
+ user,
50248
50394
  acm_url
50249
50395
  });
50250
50396
  if (error) {
@@ -50256,7 +50402,7 @@ function useAccessManagementController() {
50256
50402
  quantity,
50257
50403
  type,
50258
50404
  nfcCards,
50259
- visitorId,
50405
+ user,
50260
50406
  acm_url
50261
50407
  });
50262
50408
  return res.status(200).json({ message: "Success", data: result });
@@ -50843,11 +50989,24 @@ function useNfcPatrolTagRepo() {
50843
50989
  });
50844
50990
  });
50845
50991
  }
50992
+ async function getById(_id, session) {
50993
+ try {
50994
+ _id = typeof _id === "string" ? new import_mongodb99.ObjectId(_id) : _id;
50995
+ } catch {
50996
+ throw new import_node_server_utils161.BadRequestError("Invalid NFC Patrol Tag ID.");
50997
+ }
50998
+ const tag = await collection.findOne({ _id }, { session });
50999
+ if (!tag) {
51000
+ throw new import_node_server_utils161.NotFoundError("NFC Patrol Tag not found.");
51001
+ }
51002
+ return tag;
51003
+ }
50846
51004
  return {
50847
51005
  createIndexes,
50848
51006
  add,
50849
51007
  getAll,
50850
- updateNfcPatrolTagBySite
51008
+ updateNfcPatrolTagBySite,
51009
+ getById
50851
51010
  };
50852
51011
  }
50853
51012
 
@@ -50956,7 +51115,7 @@ var import_node_server_utils163 = require("@7365admin1/node-server-utils");
50956
51115
  var import_joi89 = __toESM(require("joi"));
50957
51116
  function useNfcPatrolTagController() {
50958
51117
  const { add: _add, updateNfcPatrolTagBySite: _updateNfcPatrolTagBySite } = useNfcPatrolTagService();
50959
- const { getAll: _getAll } = useNfcPatrolTagRepo();
51118
+ const { getAll: _getAll, getById: _getById } = useNfcPatrolTagRepo();
50960
51119
  async function add(req, res, next) {
50961
51120
  const cookies = req.headers.cookie ? req.headers.cookie.split(";").map((cookie) => cookie.trim().split("=")).reduce(
50962
51121
  (acc, [key, value2]) => ({ ...acc, [key]: value2 }),
@@ -51046,10 +51205,34 @@ function useNfcPatrolTagController() {
51046
51205
  return;
51047
51206
  }
51048
51207
  }
51208
+ async function getById(req, res, next) {
51209
+ const validation = import_joi89.default.object({
51210
+ id: import_joi89.default.string().length(24).hex().required()
51211
+ });
51212
+ const { error } = validation.validate(req.params, {
51213
+ abortEarly: false
51214
+ });
51215
+ if (error) {
51216
+ const messages = error.details.map((d) => d.message).join(", ");
51217
+ import_node_server_utils163.logger.log({ level: "error", message: messages });
51218
+ next(new import_node_server_utils163.BadRequestError(messages));
51219
+ return;
51220
+ }
51221
+ try {
51222
+ const tag = await _getById(req.params.id);
51223
+ res.status(200).json(tag);
51224
+ return;
51225
+ } catch (error2) {
51226
+ import_node_server_utils163.logger.log({ level: "error", message: error2.message });
51227
+ next(error2);
51228
+ return;
51229
+ }
51230
+ }
51049
51231
  return {
51050
51232
  add,
51051
51233
  getAll,
51052
- updateNfcPatrolTagBySite
51234
+ updateNfcPatrolTagBySite,
51235
+ getById
51053
51236
  };
51054
51237
  }
51055
51238
 
@@ -57479,7 +57662,7 @@ var schemaNfcPatrolLog = import_joi110.default.object({
57479
57662
  checkPoints: import_joi110.default.array().items(
57480
57663
  import_joi110.default.object({
57481
57664
  nfcTag_id: import_joi110.default.string().length(24).hex().required(),
57482
- nfcTag_name: import_joi110.default.string().length(24).hex().required(),
57665
+ nfcTag_name: import_joi110.default.string().required(),
57483
57666
  travelTime: import_joi110.default.number().integer().min(0).required(),
57484
57667
  startDateTime: import_joi110.default.date().required().messages({
57485
57668
  "date.base": "startDateTime must be a valid date or ISO string"
@@ -57487,7 +57670,7 @@ var schemaNfcPatrolLog = import_joi110.default.object({
57487
57670
  endDateTime: import_joi110.default.date().required().messages({
57488
57671
  "date.base": "endDateTime must be a valid date or ISO string"
57489
57672
  }),
57490
- status: import_joi110.default.string().valid("Completed", "Skipped").required(),
57673
+ status: import_joi110.default.string().valid("Pending", "Completed", "Skipped").required(),
57491
57674
  skippedRemarks: import_joi110.default.string().required()
57492
57675
  })
57493
57676
  ).min(0).required(),
@@ -57664,17 +57847,59 @@ function useNfcPatrolLogRepo() {
57664
57847
  });
57665
57848
  });
57666
57849
  }
57850
+ async function getById(id, session) {
57851
+ try {
57852
+ id = new import_mongodb121.ObjectId(id);
57853
+ } catch {
57854
+ throw new import_node_server_utils198.BadRequestError("Invalid Log ID.");
57855
+ }
57856
+ return collection.findOne(
57857
+ { _id: id },
57858
+ { session }
57859
+ );
57860
+ }
57861
+ async function updateCheckpoint(id, checkpointIndex, payload, session) {
57862
+ try {
57863
+ id = new import_mongodb121.ObjectId(id);
57864
+ } catch {
57865
+ throw new import_node_server_utils198.BadRequestError("Invalid Log ID.");
57866
+ }
57867
+ const setData = {
57868
+ [`checkPoints.${checkpointIndex}.status`]: payload.action === "complete" ? "Completed" : "Skipped",
57869
+ [`checkPoints.${checkpointIndex}.endDateTime`]: /* @__PURE__ */ new Date()
57870
+ };
57871
+ if (payload.action === "skip") {
57872
+ setData[`checkPoints.${checkpointIndex}.skippedRemarks`] = payload.skippedRemarks;
57873
+ }
57874
+ const res = await collection.updateOne(
57875
+ { _id: id },
57876
+ {
57877
+ $set: setData
57878
+ },
57879
+ { session }
57880
+ );
57881
+ delCachedData();
57882
+ return res;
57883
+ }
57667
57884
  return {
57668
57885
  createIndexes,
57669
57886
  add,
57670
- getAllBySite
57887
+ getAllBySite,
57888
+ getById,
57889
+ updateCheckpoint
57671
57890
  };
57672
57891
  }
57673
57892
 
57674
57893
  // src/services/nfc-patrol-log.service.ts
57675
57894
  var import_node_server_utils199 = require("@7365admin1/node-server-utils");
57676
57895
  function useNfcPatrolLogService() {
57677
- const { add: _add } = useNfcPatrolLogRepo();
57896
+ const {
57897
+ add: _add,
57898
+ getById,
57899
+ updateCheckpoint
57900
+ } = useNfcPatrolLogRepo();
57901
+ const routeRepo = useNfcPatrolRouteRepo();
57902
+ const tagRepo = useNfcPatrolTagRepo();
57678
57903
  async function add(value) {
57679
57904
  const session = import_node_server_utils199.useAtlas.getClient()?.startSession();
57680
57905
  session?.startTransaction();
@@ -57689,8 +57914,54 @@ function useNfcPatrolLogService() {
57689
57914
  session?.endSession();
57690
57915
  }
57691
57916
  }
57917
+ async function completeCheckpoint(logId, payload) {
57918
+ const session = import_node_server_utils199.useAtlas.getClient()?.startSession();
57919
+ session?.startTransaction();
57920
+ try {
57921
+ const log = await getById(logId, session);
57922
+ if (!log) {
57923
+ throw new import_node_server_utils199.BadRequestError("Patrol Log not found.");
57924
+ }
57925
+ const logCheckpoint = log.checkPoints[payload.checkpointIndex];
57926
+ if (!logCheckpoint) {
57927
+ throw new import_node_server_utils199.BadRequestError("Checkpoint log not found.");
57928
+ }
57929
+ if (logCheckpoint.status === "Completed") {
57930
+ throw new import_node_server_utils199.BadRequestError("Checkpoint already completed.");
57931
+ }
57932
+ if (payload.action === "skip" && !payload.skippedRemarks?.trim()) {
57933
+ throw new import_node_server_utils199.BadRequestError("Skipped remarks are required.");
57934
+ }
57935
+ if (payload.action === "complete") {
57936
+ const tag = await tagRepo.getById(logCheckpoint.nfcTag_id);
57937
+ if (!tag) {
57938
+ throw new import_node_server_utils199.BadRequestError("NFC Tag not found.");
57939
+ }
57940
+ if (!tag.tagID) {
57941
+ throw new import_node_server_utils199.BadRequestError("NFC Tag has not been configured.");
57942
+ }
57943
+ if (tag.tagID !== payload.uid) {
57944
+ throw new import_node_server_utils199.BadRequestError("Invalid NFC Tag.");
57945
+ }
57946
+ }
57947
+ await updateCheckpoint(
57948
+ logId,
57949
+ payload.checkpointIndex,
57950
+ payload,
57951
+ session
57952
+ );
57953
+ await session?.commitTransaction();
57954
+ return "Checkpoint updated.";
57955
+ } catch (error) {
57956
+ await session?.abortTransaction();
57957
+ throw error;
57958
+ } finally {
57959
+ await session?.endSession();
57960
+ }
57961
+ }
57692
57962
  return {
57693
- add
57963
+ add,
57964
+ completeCheckpoint
57694
57965
  };
57695
57966
  }
57696
57967
 
@@ -57698,8 +57969,8 @@ function useNfcPatrolLogService() {
57698
57969
  var import_node_server_utils200 = require("@7365admin1/node-server-utils");
57699
57970
  var import_joi111 = __toESM(require("joi"));
57700
57971
  function useNfcPatrolLogController() {
57701
- const { add: _add } = useNfcPatrolLogService();
57702
- const { getAllBySite: _getAllBySite } = useNfcPatrolLogRepo();
57972
+ const { add: _add, completeCheckpoint: _completeCheckpoint } = useNfcPatrolLogService();
57973
+ const { getAllBySite: _getAllBySite, getById: _getById } = useNfcPatrolLogRepo();
57703
57974
  async function add(req, res, next) {
57704
57975
  const payload = { ...req.body };
57705
57976
  try {
@@ -57761,9 +58032,36 @@ function useNfcPatrolLogController() {
57761
58032
  return;
57762
58033
  }
57763
58034
  }
58035
+ async function completeCheckpoint(req, res, next) {
58036
+ const { id } = req.params;
58037
+ const payload = {
58038
+ checkpointIndex: req.body.checkpointIndex,
58039
+ uid: req.body.uid,
58040
+ action: req.body.action,
58041
+ skippedRemarks: req.body.skippedRemarks
58042
+ };
58043
+ try {
58044
+ const data = await _completeCheckpoint(id, payload);
58045
+ res.status(200).json(data);
58046
+ return;
58047
+ } catch (error) {
58048
+ import_node_server_utils200.logger.error(error.message);
58049
+ next(error);
58050
+ }
58051
+ }
58052
+ async function getLog(req, res, next) {
58053
+ try {
58054
+ const log = await _getById(req.params.id);
58055
+ res.json(log);
58056
+ } catch (error) {
58057
+ next(error);
58058
+ }
58059
+ }
57764
58060
  return {
57765
58061
  add,
57766
- getAllBySite
58062
+ getAllBySite,
58063
+ completeCheckpoint,
58064
+ getLog
57767
58065
  };
57768
58066
  }
57769
58067