@7365admin1/core 2.21.0 → 2.23.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
@@ -38,6 +38,7 @@ __export(src_exports, {
38
38
  BulletinStatus: () => BulletinStatus,
39
39
  CameraType: () => CameraType,
40
40
  DEVICE_STATUS: () => DEVICE_STATUS,
41
+ DayOfWeek: () => DayOfWeek,
41
42
  EAccessCardTypes: () => EAccessCardTypes,
42
43
  EAccessCardUserTypes: () => EAccessCardUserTypes,
43
44
  FacilitySort: () => FacilitySort,
@@ -67,6 +68,8 @@ __export(src_exports, {
67
68
  MIncidentReport: () => MIncidentReport,
68
69
  MManpowerDesignations: () => MManpowerDesignations,
69
70
  MManpowerMonitoring: () => MManpowerMonitoring,
71
+ MManpowerRemarks: () => MManpowerRemarks,
72
+ MManpowerSites: () => MManpowerSites,
70
73
  MMember: () => MMember,
71
74
  MNfcPatrolLog: () => MNfcPatrolLog,
72
75
  MNfcPatrolRoute: () => MNfcPatrolRoute,
@@ -79,6 +82,7 @@ __export(src_exports, {
79
82
  MOnlineForm: () => MOnlineForm,
80
83
  MOrg: () => MOrg,
81
84
  MOvernightParkingApprovalHours: () => MOvernightParkingApprovalHours,
85
+ MOvernightParkingRequest: () => MOvernightParkingRequest,
82
86
  MPatrolLog: () => MPatrolLog,
83
87
  MPatrolQuestion: () => MPatrolQuestion,
84
88
  MPatrolRoute: () => MPatrolRoute,
@@ -103,6 +107,8 @@ __export(src_exports, {
103
107
  MVisitorTransaction: () => MVisitorTransaction,
104
108
  MWorkOrder: () => MWorkOrder,
105
109
  OrgNature: () => OrgNature,
110
+ OvernightParkingRequestSort: () => OvernightParkingRequestSort,
111
+ OvernightParkingRequestStatus: () => OvernightParkingRequestStatus,
106
112
  PERSON_TYPES: () => PERSON_TYPES,
107
113
  PMDashboardCollection: () => PMDashboardCollection,
108
114
  Period: () => Period,
@@ -111,6 +117,7 @@ __export(src_exports, {
111
117
  SiteStatus: () => SiteStatus,
112
118
  SortFields: () => SortFields,
113
119
  SortOrder: () => SortOrder,
120
+ SubscriptionType: () => SubscriptionType,
114
121
  UseAccessManagementRepo: () => UseAccessManagementRepo,
115
122
  VehicleCategory: () => VehicleCategory,
116
123
  VehicleOrder: () => VehicleOrder,
@@ -119,6 +126,7 @@ __export(src_exports, {
119
126
  VehicleType: () => VehicleType,
120
127
  VisitorSort: () => VisitorSort,
121
128
  VisitorStatus: () => VisitorStatus,
129
+ addressSchema: () => addressSchema,
122
130
  allowedFieldsSite: () => allowedFieldsSite,
123
131
  allowedNatures: () => allowedNatures,
124
132
  attendanceSchema: () => attendanceSchema,
@@ -127,6 +135,7 @@ __export(src_exports, {
127
135
  bulletin_boards_namespace_collection: () => bulletin_boards_namespace_collection,
128
136
  calculatePercentage: () => calculatePercentage,
129
137
  chatSchema: () => chatSchema,
138
+ createManpowerRemarksDaily: () => createManpowerRemarksDaily,
130
139
  customerSchema: () => customerSchema,
131
140
  designationsSchema: () => designationsSchema,
132
141
  events_namespace_collection: () => events_namespace_collection,
@@ -141,13 +150,19 @@ __export(src_exports, {
141
150
  landscapeDashboardCollection: () => landscapeDashboardCollection,
142
151
  mAndEDashboardCollection: () => mAndEDashboardCollection,
143
152
  manpowerDesignationsSchema: () => manpowerDesignationsSchema,
153
+ manpowerEvents: () => manpowerEvents,
144
154
  manpowerMonitoringSchema: () => manpowerMonitoringSchema,
155
+ manpowerRemarksSchema: () => manpowerRemarksSchema,
156
+ manpowerSitesSchema: () => manpowerSitesSchema,
145
157
  nfcPatrolSettingsSchema: () => nfcPatrolSettingsSchema,
146
158
  nfcPatrolSettingsSchemaUpdate: () => nfcPatrolSettingsSchemaUpdate,
159
+ occurrence_book_namespace_collection: () => occurrence_book_namespace_collection,
147
160
  orgSchema: () => orgSchema,
161
+ overnight_parking_requests_namespace_collection: () => overnight_parking_requests_namespace_collection,
148
162
  pestDashboardCollection: () => pestDashboardCollection,
149
163
  poolDashboardCollection: () => poolDashboardCollection,
150
164
  promoCodeSchema: () => promoCodeSchema,
165
+ remarksSchema: () => remarksSchema,
151
166
  robotSchema: () => robotSchema,
152
167
  schema: () => schema,
153
168
  schemaBilling: () => schemaBilling,
@@ -174,6 +189,7 @@ __export(src_exports, {
174
189
  schemaOccurrenceSubject: () => schemaOccurrenceSubject,
175
190
  schemaOnlineForm: () => schemaOnlineForm,
176
191
  schemaOvernightParkingApprovalHours: () => schemaOvernightParkingApprovalHours,
192
+ schemaOvernightParkingRequest: () => schemaOvernightParkingRequest,
177
193
  schemaPatrolLog: () => schemaPatrolLog,
178
194
  schemaPatrolQuestion: () => schemaPatrolQuestion,
179
195
  schemaPatrolRoute: () => schemaPatrolRoute,
@@ -198,6 +214,7 @@ __export(src_exports, {
198
214
  schemaUpdateOccurrenceSubject: () => schemaUpdateOccurrenceSubject,
199
215
  schemaUpdateOnlineForm: () => schemaUpdateOnlineForm,
200
216
  schemaUpdateOptions: () => schemaUpdateOptions,
217
+ schemaUpdateOvernightParkingRequest: () => schemaUpdateOvernightParkingRequest,
201
218
  schemaUpdatePatrolLog: () => schemaUpdatePatrolLog,
202
219
  schemaUpdatePatrolQuestion: () => schemaUpdatePatrolQuestion,
203
220
  schemaUpdatePatrolRoute: () => schemaUpdatePatrolRoute,
@@ -220,6 +237,8 @@ __export(src_exports, {
220
237
  siteSchema: () => siteSchema,
221
238
  site_people_namespace_collection: () => site_people_namespace_collection,
222
239
  tokenSchema: () => tokenSchema,
240
+ updateRemarksStatusEod: () => updateRemarksStatusEod,
241
+ updateRemarksisAcknowledged: () => updateRemarksisAcknowledged,
223
242
  updateSiteSchema: () => updateSiteSchema,
224
243
  useAccessManagementController: () => useAccessManagementController,
225
244
  useAddressRepo: () => useAddressRepo,
@@ -271,6 +290,8 @@ __export(src_exports, {
271
290
  useGuestManagementController: () => useGuestManagementController,
272
291
  useGuestManagementRepo: () => useGuestManagementRepo,
273
292
  useGuestManagementService: () => useGuestManagementService,
293
+ useHrmLabsAttendanceCtrl: () => useHrmLabsAttendanceCtrl,
294
+ useHrmLabsAttendanceSrvc: () => useHrmLabsAttendanceSrvc,
274
295
  useIncidentReportController: () => useIncidentReportController,
275
296
  useIncidentReportRepo: () => useIncidentReportRepo,
276
297
  useIncidentReportService: () => useIncidentReportService,
@@ -282,6 +303,11 @@ __export(src_exports, {
282
303
  useManpowerMonitoringCtrl: () => useManpowerMonitoringCtrl,
283
304
  useManpowerMonitoringRepo: () => useManpowerMonitoringRepo,
284
305
  useManpowerMonitoringSrvc: () => useManpowerMonitoringSrvc,
306
+ useManpowerRemarkCtrl: () => useManpowerRemarkCtrl,
307
+ useManpowerRemarksRepo: () => useManpowerRemarksRepo,
308
+ useManpowerSitesCtrl: () => useManpowerSitesCtrl,
309
+ useManpowerSitesRepo: () => useManpowerSitesRepo,
310
+ useManpowerSitesSrvc: () => useManpowerSitesSrvc,
285
311
  useMemberController: () => useMemberController,
286
312
  useMemberRepo: () => useMemberRepo,
287
313
  useNewDashboardController: () => useNewDashboardController,
@@ -313,6 +339,9 @@ __export(src_exports, {
313
339
  useOrgRepo: () => useOrgRepo,
314
340
  useOvernightParkingController: () => useOvernightParkingController,
315
341
  useOvernightParkingRepo: () => useOvernightParkingRepo,
342
+ useOvernightParkingRequestController: () => useOvernightParkingRequestController,
343
+ useOvernightParkingRequestRepo: () => useOvernightParkingRequestRepo,
344
+ useOvernightParkingRequestService: () => useOvernightParkingRequestService,
316
345
  usePatrolLogController: () => usePatrolLogController,
317
346
  usePatrolLogRepo: () => usePatrolLogRepo,
318
347
  usePatrolQuestionController: () => usePatrolQuestionController,
@@ -4936,6 +4965,16 @@ function useSiteRepo() {
4936
4965
  throw error;
4937
4966
  }
4938
4967
  }
4968
+ async function getAllSitesUnpaginated() {
4969
+ try {
4970
+ const sites = await collection.find({ deletedAt: "" }).project({
4971
+ _id: 1
4972
+ }).toArray();
4973
+ return sites;
4974
+ } catch (error) {
4975
+ throw error;
4976
+ }
4977
+ }
4939
4978
  return {
4940
4979
  createIndexes,
4941
4980
  createSite,
@@ -4948,7 +4987,8 @@ function useSiteRepo() {
4948
4987
  getByName,
4949
4988
  getByExactName,
4950
4989
  updateSiteIncidentCounter,
4951
- updateSiteById
4990
+ updateSiteById,
4991
+ getAllSitesUnpaginated
4952
4992
  };
4953
4993
  }
4954
4994
 
@@ -8063,6 +8103,11 @@ function useOrgController() {
8063
8103
  var import_node_server_utils36 = require("@7365admin1/node-server-utils");
8064
8104
  var import_joi20 = __toESM(require("joi"));
8065
8105
  var import_mongodb22 = require("mongodb");
8106
+ var SubscriptionType = /* @__PURE__ */ ((SubscriptionType2) => {
8107
+ SubscriptionType2["ORGANIZATION"] = "organization";
8108
+ SubscriptionType2["AFFILIATE"] = "affiliate";
8109
+ return SubscriptionType2;
8110
+ })(SubscriptionType || {});
8066
8111
  var schema = import_joi20.default.object({
8067
8112
  user: import_joi20.default.string().hex().required(),
8068
8113
  amount: import_joi20.default.number().min(0).required(),
@@ -8096,7 +8141,7 @@ function MSubscription(value) {
8096
8141
  currency: import_joi20.default.string().required(),
8097
8142
  description: import_joi20.default.string().optional().allow("", null),
8098
8143
  promoCode: import_joi20.default.string().optional().allow("", null),
8099
- type: import_joi20.default.string().valid("organization", "affiliate").required(),
8144
+ type: import_joi20.default.string().valid(...Object.values(SubscriptionType)).optional().allow(null, ""),
8100
8145
  paidSeats: import_joi20.default.number().optional().min(0).allow("", null),
8101
8146
  currentSeats: import_joi20.default.number().optional().min(0).allow("", null),
8102
8147
  maxSeats: import_joi20.default.number().optional().min(0).allow("", null),
@@ -8150,7 +8195,6 @@ function MSubscription(value) {
8150
8195
  status: "active",
8151
8196
  billingCycle: value.billingCycle,
8152
8197
  nextBillingDate,
8153
- // Fixed nextBillingDate logic
8154
8198
  lastPaymentStatus: value.lastPaymentStatus ?? "success",
8155
8199
  failedAttempts: value.failedAttempts ?? 0,
8156
8200
  createdAt: createdAt.toISOString(),
@@ -12956,7 +13000,8 @@ var schemaPerson = import_joi35.default.object({
12956
13000
  companyName: import_joi35.default.array().items(import_joi35.default.string()).optional(),
12957
13001
  plates: import_joi35.default.array().items(schemaPlate).optional().allow(null),
12958
13002
  isOwner: import_joi35.default.boolean().required(),
12959
- files: import_joi35.default.array().items(schemaFiles).optional().allow(null)
13003
+ files: import_joi35.default.array().items(schemaFiles).optional().allow(null),
13004
+ password: import_joi35.default.string().optional().allow(null, "")
12960
13005
  });
12961
13006
  var schemaUpdatePerson = import_joi35.default.object({
12962
13007
  _id: import_joi35.default.string().hex().required(),
@@ -12975,7 +13020,8 @@ var schemaUpdatePerson = import_joi35.default.object({
12975
13020
  companyName: import_joi35.default.array().items(import_joi35.default.string()).optional().allow(null, ""),
12976
13021
  plates: import_joi35.default.array().items(schemaFiles).optional().allow(null, ""),
12977
13022
  isOwner: import_joi35.default.boolean().optional().allow(null, ""),
12978
- files: import_joi35.default.array().items(schemaFiles).optional().allow(null)
13023
+ files: import_joi35.default.array().items(schemaFiles).optional().allow(null),
13024
+ password: import_joi35.default.string().optional().allow(null, "")
12979
13025
  });
12980
13026
  function MPerson(value) {
12981
13027
  const { error } = schemaPerson.validate(value);
@@ -13026,6 +13072,7 @@ function MPerson(value) {
13026
13072
  end: value.end,
13027
13073
  type: value.type,
13028
13074
  email: value.email,
13075
+ password: value.password ?? "",
13029
13076
  status: value.status ?? "active",
13030
13077
  nric: value.nric,
13031
13078
  remarks: value.remarks,
@@ -13575,6 +13622,8 @@ var VehicleSort = /* @__PURE__ */ ((VehicleSort2) => {
13575
13622
  VehicleSort2["CREATED_AT"] = "createdAt";
13576
13623
  VehicleSort2["ID"] = "_id";
13577
13624
  VehicleSort2["NAME"] = "name";
13625
+ VehicleSort2["START"] = "start";
13626
+ VehicleSort2["END"] = "end";
13578
13627
  return VehicleSort2;
13579
13628
  })(VehicleSort || {});
13580
13629
  var OrgNature = /* @__PURE__ */ ((OrgNature2) => {
@@ -13727,6 +13776,7 @@ var import_mongodb41 = require("mongodb");
13727
13776
  var import_joi38 = __toESM(require("joi"));
13728
13777
  var vehicles_namespace_collection = "vehicles";
13729
13778
  function useVehicleRepo() {
13779
+ vehicles_namespace_collection;
13730
13780
  const db = import_node_server_utils69.useAtlas.getDb();
13731
13781
  if (!db) {
13732
13782
  throw new import_node_server_utils69.InternalServerError("Unable to connect to server.");
@@ -16619,7 +16669,7 @@ var schemaBuildingUnit = import_joi43.default.object({
16619
16669
  buildingName: import_joi43.default.string().optional().allow("", null),
16620
16670
  block: import_joi43.default.number().integer().min(1).required(),
16621
16671
  level: import_joi43.default.string().required(),
16622
- category: import_joi43.default.string().required(),
16672
+ category: import_joi43.default.string().optional().allow(null, ""),
16623
16673
  status: import_joi43.default.string().optional().allow("", null),
16624
16674
  buildingUnitFiles: import_joi43.default.array().items(import_joi43.default.string()).optional().allow("", null),
16625
16675
  companyName: import_joi43.default.string().optional().allow("", null),
@@ -18204,11 +18254,13 @@ function useVehicleController() {
18204
18254
  getAllVehiclesByUnitId: _getAllVehiclesByUnitId
18205
18255
  } = useVehicleRepo();
18206
18256
  async function add(req, res, next) {
18207
- const payload = req.body;
18208
- const { error, value } = vehicleSchema.validate(payload);
18257
+ const { error, value } = vehicleSchema.validate(req.body, {
18258
+ abortEarly: false
18259
+ });
18209
18260
  if (error) {
18210
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18211
- next(new import_node_server_utils85.BadRequestError(error.message));
18261
+ const messages = error.details.map((d) => d.message).join(", ");
18262
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18263
+ next(new import_node_server_utils85.BadRequestError(messages));
18212
18264
  return;
18213
18265
  }
18214
18266
  try {
@@ -18224,40 +18276,29 @@ function useVehicleController() {
18224
18276
  }
18225
18277
  }
18226
18278
  async function getVehicles(req, res, next) {
18227
- const allowedFields = ["start", "end"];
18228
- const allowedOrder = ["asc", "desc"];
18229
- const validation = import_joi46.default.object({
18279
+ const schema2 = import_joi46.default.object({
18230
18280
  search: import_joi46.default.string().optional().allow("", null),
18231
- page: import_joi46.default.number().integer().min(1).allow("", null).default(1),
18232
- limit: import_joi46.default.number().integer().min(1).max(100).allow("", null).default(10),
18233
- sort: import_joi46.default.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
18234
- order: import_joi46.default.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
18281
+ page: import_joi46.default.number().integer().min(1).optional().default(1),
18282
+ limit: import_joi46.default.number().integer().min(1).max(100).optional().default(10),
18283
+ sort: import_joi46.default.string().optional().valid(...Object.values(VehicleSort)),
18284
+ order: import_joi46.default.string().optional().valid(...Object.values(SortOrder)),
18235
18285
  type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)).allow(null, ""),
18236
18286
  category: import_joi46.default.string().optional().valid(...Object.values(VehicleCategory)).allow(null, ""),
18237
18287
  status: import_joi46.default.string().optional().valid(...Object.values(VehicleStatus)).allow(null, "")
18238
18288
  });
18239
- const query = { ...req.query };
18240
- const { error } = validation.validate(query);
18289
+ const { error, value } = schema2.validate(req.query, {
18290
+ abortEarly: false
18291
+ });
18241
18292
  if (error) {
18242
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18243
- next(new import_node_server_utils85.BadRequestError(error.message));
18293
+ const messages = error.details.map((d) => d.message).join(", ");
18294
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18295
+ next(new import_node_server_utils85.BadRequestError(messages));
18244
18296
  return;
18245
18297
  }
18246
- const search = req.query.search ?? "";
18247
- const page = parseInt(req.query.page ?? "1");
18248
- const limit = parseInt(req.query.limit ?? "10");
18249
- const type = req.query.type ?? "";
18250
- const category = req.query.category ?? "";
18251
- const status = req.query.status ?? "";
18252
- const sortObj = {};
18253
- const sortFields = String(req.query.sort).split(",");
18254
- const sortOrders = String(req.query.order).split(",");
18255
- sortFields.forEach((field, index) => {
18256
- if (allowedFields.includes(field)) {
18257
- const order = sortOrders[index] === "asc" ? 1 : -1;
18258
- sortObj[field] = order;
18259
- }
18260
- });
18298
+ const { search, page, limit, type, category, status, sort, order } = value;
18299
+ const sortObj = {
18300
+ [sort ? sort : "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
18301
+ };
18261
18302
  try {
18262
18303
  const data = await _getVehicles({
18263
18304
  search,
@@ -18277,14 +18318,20 @@ function useVehicleController() {
18277
18318
  }
18278
18319
  }
18279
18320
  async function getSeasonPassTypes(req, res, next) {
18280
- const validation = import_joi46.default.string().hex().required();
18281
- const site = req.params.site;
18282
- const { error } = validation.validate(site);
18321
+ const schema2 = import_joi46.default.object({
18322
+ site: import_joi46.default.string().hex().length(24).required()
18323
+ });
18324
+ const { error, value } = schema2.validate(
18325
+ { site: req.params.site },
18326
+ { abortEarly: false }
18327
+ );
18283
18328
  if (error) {
18284
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18285
- next(new import_node_server_utils85.BadRequestError(error.message));
18329
+ const messages = error.details.map((d) => d.message).join(", ");
18330
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18331
+ next(new import_node_server_utils85.BadRequestError(messages));
18286
18332
  return;
18287
18333
  }
18334
+ const { site } = value;
18288
18335
  try {
18289
18336
  const data = await _getSeasonPassTypes(site);
18290
18337
  res.json(data);
@@ -18296,14 +18343,20 @@ function useVehicleController() {
18296
18343
  }
18297
18344
  }
18298
18345
  async function getVehicleById(req, res, next) {
18299
- const validation = import_joi46.default.string().hex().required();
18300
- const _id = req.params.id;
18301
- const { error } = validation.validate(_id);
18346
+ const schema2 = import_joi46.default.object({
18347
+ _id: import_joi46.default.string().hex().length(24).required()
18348
+ });
18349
+ const { error, value } = schema2.validate(
18350
+ { _id: req.params.id },
18351
+ { abortEarly: false }
18352
+ );
18302
18353
  if (error) {
18303
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18304
- next(new import_node_server_utils85.BadRequestError(error.message));
18354
+ const messages = error.details.map((d) => d.message).join(", ");
18355
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18356
+ next(new import_node_server_utils85.BadRequestError(messages));
18305
18357
  return;
18306
18358
  }
18359
+ const { _id } = value;
18307
18360
  try {
18308
18361
  const site = await _getVehicleById(_id);
18309
18362
  res.json(site);
@@ -18316,7 +18369,7 @@ function useVehicleController() {
18316
18369
  }
18317
18370
  async function updateVehicleById(req, res, next) {
18318
18371
  try {
18319
- const validation = import_joi46.default.object({
18372
+ const schema2 = import_joi46.default.object({
18320
18373
  _id: import_joi46.default.string().hex().length(24).required(),
18321
18374
  site: import_joi46.default.string().hex().length(24).required(),
18322
18375
  name: import_joi46.default.string().optional().allow("", null),
@@ -18331,13 +18384,17 @@ function useVehicleController() {
18331
18384
  recNo: import_joi46.default.string().optional().allow(null, ""),
18332
18385
  type: import_joi46.default.string().optional().valid(...Object.values(VehicleType)).allow(null, "")
18333
18386
  });
18334
- const { error, value } = validation.validate({
18335
- _id: req.params.id,
18336
- ...req.body
18337
- });
18387
+ const { error, value } = schema2.validate(
18388
+ {
18389
+ _id: req.params.id,
18390
+ ...req.body
18391
+ },
18392
+ { abortEarly: false }
18393
+ );
18338
18394
  if (error) {
18339
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18340
- next(new import_node_server_utils85.BadRequestError(error.message));
18395
+ const messages = error.details.map((d) => d.message).join(", ");
18396
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18397
+ next(new import_node_server_utils85.BadRequestError(messages));
18341
18398
  return;
18342
18399
  }
18343
18400
  const { _id, ...rest } = value;
@@ -18351,21 +18408,24 @@ function useVehicleController() {
18351
18408
  }
18352
18409
  }
18353
18410
  async function deleteVehicle(req, res, next) {
18354
- const _id = req.params.id;
18355
18411
  const deleteVehicleSchema = import_joi46.default.object({
18356
18412
  _id: import_joi46.default.string().hex().length(24).required(),
18357
18413
  recno: import_joi46.default.string().required(),
18358
18414
  site: import_joi46.default.string().hex().length(24).required(),
18359
- type: import_joi46.default.string().valid("whitelist", "blocklist").required(),
18415
+ type: import_joi46.default.string().valid(...Object.values(VehicleType)).required(),
18360
18416
  bypass: import_joi46.default.boolean().optional().default(true)
18361
18417
  });
18362
- const { error, value } = deleteVehicleSchema.validate({ _id, ...req.body });
18418
+ const { error, value } = deleteVehicleSchema.validate({
18419
+ _id: req.params.id,
18420
+ ...req.body
18421
+ });
18363
18422
  if (error) {
18364
- import_node_server_utils85.logger.log({ level: "error", message: error.message });
18365
- next(new import_node_server_utils85.BadRequestError(error.message));
18423
+ const messages = error.details.map((d) => d.message).join(", ");
18424
+ import_node_server_utils85.logger.log({ level: "error", message: messages });
18425
+ next(new import_node_server_utils85.BadRequestError(messages));
18366
18426
  return;
18367
18427
  }
18368
- const { recno, site, type, bypass } = value;
18428
+ const { recno, site, type, bypass, _id } = value;
18369
18429
  try {
18370
18430
  const data = await _deleteVehicle(_id, recno, site, type, bypass);
18371
18431
  res.json({
@@ -18700,10 +18760,12 @@ var schemaCustomerSite = import_joi48.default.object({
18700
18760
  _id: import_joi48.default.string().hex().optional().allow("", null),
18701
18761
  name: import_joi48.default.string().required(),
18702
18762
  site: import_joi48.default.string().hex().optional().allow("", null),
18703
- siteOrg: import_joi48.default.string().hex().required(),
18704
- siteOrgName: import_joi48.default.string().required(),
18763
+ siteOrg: import_joi48.default.string().hex().optional().allow("", null),
18764
+ siteOrgName: import_joi48.default.string().optional().allow("", null),
18705
18765
  org: import_joi48.default.string().hex().required(),
18706
18766
  status: import_joi48.default.string().optional().allow("", null),
18767
+ address: addressSchema.optional().allow("", null),
18768
+ category: import_joi48.default.string().valid(...Object.values(SiteCategories)).optional().allow(null, ""),
18707
18769
  createdAt: import_joi48.default.string().optional().allow("", null),
18708
18770
  updatedAt: import_joi48.default.string().optional().allow("", null),
18709
18771
  deletedAt: import_joi48.default.string().optional().allow("", null)
@@ -18748,6 +18810,8 @@ function MCustomerSite(value) {
18748
18810
  siteOrg: value.siteOrg,
18749
18811
  siteOrgName: value.siteOrgName,
18750
18812
  org: value.org,
18813
+ address: value.address,
18814
+ category: value.category,
18751
18815
  status: value.status ?? "active",
18752
18816
  createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
18753
18817
  updatedAt: value.updatedAt ?? "",
@@ -19018,7 +19082,12 @@ function useCustomerSiteService() {
19018
19082
  }
19019
19083
  }
19020
19084
  const siteId = await createSite(
19021
- { name: value.name, orgId: value.siteOrg },
19085
+ {
19086
+ name: value.name,
19087
+ orgId: value.siteOrg,
19088
+ address: value.address,
19089
+ category: value.category
19090
+ },
19022
19091
  session
19023
19092
  );
19024
19093
  if (!siteId) {
@@ -19130,25 +19199,15 @@ function useCustomerSiteController() {
19130
19199
  } = useCustomerSiteRepo();
19131
19200
  const { add: _add, addViaInvite: _addViaInvite } = useCustomerSiteService();
19132
19201
  async function add(req, res, next) {
19133
- const validation = import_joi50.default.object({
19134
- name: import_joi50.default.string().required(),
19135
- site: import_joi50.default.string().hex().optional().allow("", null),
19136
- siteOrg: import_joi50.default.string().hex().required(),
19137
- siteOrgName: import_joi50.default.string().required(),
19138
- org: import_joi50.default.string().hex().required()
19139
- });
19140
- const payload = { ...req.body };
19141
- const { error } = validation.validate(payload);
19202
+ const { error, value } = schemaCustomerSite.validate(req.body);
19142
19203
  if (error) {
19143
- import_node_server_utils90.logger.log({
19144
- level: "error",
19145
- message: `${error.message} - controller validation`
19146
- });
19147
- next(new import_node_server_utils90.BadRequestError(error.message));
19204
+ const messages = error.details.map((d) => d.message).join(", ");
19205
+ import_node_server_utils90.logger.log({ level: "error", message: messages });
19206
+ next(new import_node_server_utils90.BadRequestError(messages));
19148
19207
  return;
19149
19208
  }
19150
19209
  try {
19151
- const data = await _add(payload);
19210
+ const data = await _add(value);
19152
19211
  res.status(201).json(data);
19153
19212
  return;
19154
19213
  } catch (error2) {
@@ -21140,9 +21199,19 @@ function usePersonService() {
21140
21199
  updateById: _updateById
21141
21200
  } = usePersonRepo();
21142
21201
  const { addPlateNumber: _addPlateNumber } = useDahuaService();
21202
+ const {
21203
+ createUser: addUser,
21204
+ getUserById,
21205
+ getUserByEmail,
21206
+ updatePassword,
21207
+ updateUserFieldById: _updateUserFieldById
21208
+ } = useUserRepo();
21209
+ const { add: addMember } = useMemberRepo();
21143
21210
  const { getById: _getUnitById, updateById: updateUnitById } = useBuildingUnitRepo();
21144
21211
  const { getAllCameraWithPassword: _getAllSiteCameras } = useSiteCameraRepo();
21145
21212
  const { updateStatusById } = useFileRepo();
21213
+ const { getById: getOrgById } = useOrgRepo();
21214
+ const { getSiteById } = useSiteRepo();
21146
21215
  async function add(value) {
21147
21216
  const session = import_node_server_utils104.useAtlas.getClient()?.startSession();
21148
21217
  if (!session) {
@@ -21163,6 +21232,49 @@ function usePersonService() {
21163
21232
  }
21164
21233
  }
21165
21234
  }
21235
+ const isValidType = ["resident" /* RESIDENT */, "tenant" /* TENANT */].includes(
21236
+ value?.type
21237
+ );
21238
+ if (value.email && value.password && value.name && isValidType) {
21239
+ const _user = await getUserByEmail(value.email);
21240
+ if (_user) {
21241
+ throw new import_node_server_utils104.BadRequestError(`User already exists: ${value.email}.`);
21242
+ }
21243
+ const hashedPassword = await (0, import_node_server_utils104.hashPassword)(value.password);
21244
+ const user = {
21245
+ email: value.email,
21246
+ password: hashedPassword,
21247
+ name: value.name,
21248
+ defaultOrg: value.org?.toString() || ""
21249
+ };
21250
+ const userId = await addUser(user, session);
21251
+ let org = null;
21252
+ if (userId) {
21253
+ if (value?.org) {
21254
+ org = await getOrgById(value.org);
21255
+ if (!org) {
21256
+ value.org = "";
21257
+ }
21258
+ }
21259
+ let site;
21260
+ if (value.site) {
21261
+ site = await getSiteById(value.site);
21262
+ }
21263
+ await addMember(
21264
+ {
21265
+ org: value.org?.toString() || "",
21266
+ orgName: org?.name || "",
21267
+ user: userId.toString(),
21268
+ name: value.name,
21269
+ role: "",
21270
+ type: "resident",
21271
+ siteId: value.site?.toString() || "",
21272
+ siteName: site?.name || ""
21273
+ },
21274
+ session
21275
+ );
21276
+ }
21277
+ }
21166
21278
  await _add(value, session);
21167
21279
  await session.commitTransaction();
21168
21280
  return "People added successfully.";
@@ -24181,7 +24293,7 @@ function useSiteFacilityService() {
24181
24293
  });
24182
24294
  }, generateTimeSlots2 = function(start, end, interval) {
24183
24295
  const slots = [];
24184
- const timeToMinutes = (t) => {
24296
+ const timeToMinutes2 = (t) => {
24185
24297
  const [h, m] = t.split(":").map(Number);
24186
24298
  return h * 60 + m;
24187
24299
  };
@@ -24190,8 +24302,8 @@ function useSiteFacilityService() {
24190
24302
  const mm = m % 60;
24191
24303
  return `${String(h).padStart(2, "0")}:${String(mm).padStart(2, "0")}`;
24192
24304
  };
24193
- const startMin = timeToMinutes(start);
24194
- const endMin = timeToMinutes(end);
24305
+ const startMin = timeToMinutes2(start);
24306
+ const endMin = timeToMinutes2(end);
24195
24307
  const intervalMin = interval * 60;
24196
24308
  for (let t = startMin; t + intervalMin <= endMin; t += intervalMin) {
24197
24309
  const s = minutesToTime(t);
@@ -25533,14 +25645,17 @@ function useSiteFacilityBookingController() {
25533
25645
  }
25534
25646
  }
25535
25647
  async function deleteSiteFacilityBookingById(req, res, next) {
25536
- const validation = import_joi72.default.string().hex().required();
25537
- const _id = req.params.id;
25538
- const { error } = validation.validate(_id);
25648
+ const schema2 = import_joi72.default.object({
25649
+ _id: import_joi72.default.string().hex().length(24).required()
25650
+ });
25651
+ const { error, value } = schema2.validate({ _id: req.params.id });
25539
25652
  if (error) {
25540
- import_node_server_utils128.logger.log({ level: "error", message: error.message });
25541
- next(new import_node_server_utils128.BadRequestError(error.message));
25653
+ const messages = error.details.map((d) => d.message).join(", ");
25654
+ import_node_server_utils128.logger.log({ level: "error", message: messages });
25655
+ next(new import_node_server_utils128.BadRequestError(messages));
25542
25656
  return;
25543
25657
  }
25658
+ const { _id } = value;
25544
25659
  try {
25545
25660
  await _deleteSiteFacilityBookingById(_id);
25546
25661
  res.status(200).json({ message: "Successfully deleted site facility booking." });
@@ -26577,7 +26692,10 @@ function useBulletinBoardService() {
26577
26692
  const existingBulletinBoard = await _getBulletinBoardById(id);
26578
26693
  if (Array.isArray(existingBulletinBoard.file)) {
26579
26694
  for (const file of existingBulletinBoard.file) {
26580
- await _deleteFileById(file, session);
26695
+ try {
26696
+ await _deleteFileById(file, session);
26697
+ } catch (error) {
26698
+ }
26581
26699
  }
26582
26700
  }
26583
26701
  await _deleteBulletinBoardById(id, session);
@@ -26737,14 +26855,16 @@ function useBulletinBoardController() {
26737
26855
  }
26738
26856
  }
26739
26857
  async function deleteBulletinBoardById(req, res, next) {
26740
- const validation = import_joi76.default.string().hex().required();
26741
- const _id = req.params.id;
26742
- const { error } = validation.validate(_id);
26858
+ const schema2 = import_joi76.default.object({
26859
+ _id: import_joi76.default.string().hex().length(24).required()
26860
+ });
26861
+ const { error, value } = schema2.validate({ _id: req.params.id });
26743
26862
  if (error) {
26744
26863
  import_node_server_utils134.logger.log({ level: "error", message: error.message });
26745
26864
  next(new import_node_server_utils134.BadRequestError(error.message));
26746
26865
  return;
26747
26866
  }
26867
+ const { _id } = value;
26748
26868
  try {
26749
26869
  await _deleteBulletinBoardById(_id);
26750
26870
  res.status(200).json({ message: "Successfully deleted bulletin board." });
@@ -29544,6 +29664,7 @@ var import_mongodb84 = require("mongodb");
29544
29664
  var import_fs2 = __toESM(require("fs"));
29545
29665
  var import_path = __toESM(require("path"));
29546
29666
  var import_axios = __toESM(require("axios"));
29667
+ var import_xml2js = require("xml2js");
29547
29668
  var import_crypto = __toESM(require("crypto"));
29548
29669
  var ALGORITHM = "aes-256-gcm";
29549
29670
  var SECRET_KEY = import_crypto.default.createSecretKey(
@@ -29644,9 +29765,39 @@ var formatEntryPassDate = (date) => {
29644
29765
  const day = String(newDate.getDate()).padStart(2, "0");
29645
29766
  return `${year}${month}${day}`;
29646
29767
  };
29768
+ async function removeAccessGroup({ cardNo, staffNo, url }) {
29769
+ try {
29770
+ const commands = readTemplate("delete-qr-card", {
29771
+ staffNo,
29772
+ // dateOfJoin: formatEntryPassDate(cardDetails.startDate),
29773
+ // accessLevel: cardDetails.accessLevel,
29774
+ cardNo
29775
+ // pin: cardDetails.pin,
29776
+ // startDate: formatEntryPassDate(cardDetails.startDate),
29777
+ // endDate: formatEntryPassDate(cardDetails.endDate),
29778
+ // cardType: 0,
29779
+ // isActivated: cardDetails.isActivated ? 1 : 0,
29780
+ // isAntiPassBack: cardDetails.isAntiPassBack ? 1 : 0,
29781
+ // isLiftCard: cardDetails.isLiftCard ? 1 : 0,
29782
+ // isLiftActivate: cardDetails.isLiftCard ? 1 : 0,
29783
+ // liftAccessLevel: cardDetails.liftAccessLevel || 1,
29784
+ // liftAccessStartDate: formatEntryPassDate(cardDetails.liftAccessStartDate) || "19770510",
29785
+ // liftAccessEndDate: formatEntryPassDate(cardDetails.liftAccessEndDate) || "19770510",
29786
+ });
29787
+ const response = await sendCommand(commands, url);
29788
+ const result = await (0, import_xml2js.parseStringPromise)(response, { explicitArray: false });
29789
+ console.log(result.RESULT.$.STCODE);
29790
+ console.log(commands);
29791
+ if (result && result.RESULT.$.STCODE !== "0") {
29792
+ throw new Error("Command failed, server error.");
29793
+ }
29794
+ } catch (error) {
29795
+ console.log(error);
29796
+ }
29797
+ }
29647
29798
 
29648
29799
  // src/repositories/access-management.repo.ts
29649
- var import_xml2js = require("xml2js");
29800
+ var import_xml2js2 = require("xml2js");
29650
29801
 
29651
29802
  // src/utils/rsa-encryption.ts
29652
29803
  var crypto2 = __toESM(require("crypto"));
@@ -30655,7 +30806,7 @@ function UseAccessManagementRepo() {
30655
30806
  return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
30656
30807
  }).flat();
30657
30808
  const response = await sendCommand(commands.join("").toString(), params.acm_url);
30658
- const result = await (0, import_xml2js.parseStringPromise)(response, { explicitArray: false });
30809
+ const result = await (0, import_xml2js2.parseStringPromise)(response, { explicitArray: false });
30659
30810
  if (result && result.RESULT.$.STCODE !== "0") {
30660
30811
  throw new Error("Command failed, server error.");
30661
30812
  }
@@ -31516,7 +31667,7 @@ function UseAccessManagementRepo() {
31516
31667
  return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
31517
31668
  }).flat();
31518
31669
  const response = await sendCommand(commands.join("").toString(), acm_url);
31519
- serverResult = await (0, import_xml2js.parseStringPromise)(response, { explicitArray: false });
31670
+ serverResult = await (0, import_xml2js2.parseStringPromise)(response, { explicitArray: false });
31520
31671
  if (result && serverResult.RESULT.$.STCODE !== "0") {
31521
31672
  throw new Error("Command failed, server error.");
31522
31673
  }
@@ -31612,7 +31763,7 @@ function UseAccessManagementRepo() {
31612
31763
  var import_joi85 = __toESM(require("joi"));
31613
31764
 
31614
31765
  // src/services/access-management.service.ts
31615
- var import_xml2js2 = require("xml2js");
31766
+ var import_xml2js3 = require("xml2js");
31616
31767
  var import_stream = require("stream");
31617
31768
  var xlsx = __toESM(require("xlsx"));
31618
31769
  function useAccessManagementSvc() {
@@ -31675,7 +31826,7 @@ function useAccessManagementSvc() {
31675
31826
  try {
31676
31827
  const command = readTemplate("door-levels");
31677
31828
  const response = await sendCommand(command, params.acm_url);
31678
- const res = await (0, import_xml2js2.parseStringPromise)(response, { explicitArray: false });
31829
+ const res = await (0, import_xml2js3.parseStringPromise)(response, { explicitArray: false });
31679
31830
  const format = await formatDoorAccessLevels(res);
31680
31831
  return format;
31681
31832
  } catch (err) {
@@ -31686,7 +31837,7 @@ function useAccessManagementSvc() {
31686
31837
  try {
31687
31838
  const command = readTemplate("lift-levels");
31688
31839
  const response = await sendCommand(command, params.acm_url);
31689
- const res = await (0, import_xml2js2.parseStringPromise)(response, { explicitArray: false });
31840
+ const res = await (0, import_xml2js3.parseStringPromise)(response, { explicitArray: false });
31690
31841
  const format = await formatLiftAccessLevels(res);
31691
31842
  return format;
31692
31843
  } catch (error) {
@@ -31697,7 +31848,7 @@ function useAccessManagementSvc() {
31697
31848
  try {
31698
31849
  const command = readTemplate("access-group");
31699
31850
  const response = await sendCommand(command, params.acm_url);
31700
- const res = await (0, import_xml2js2.parseStringPromise)(response, { explicitArray: false });
31851
+ const res = await (0, import_xml2js3.parseStringPromise)(response, { explicitArray: false });
31701
31852
  const format = await formatAccessGroup(res);
31702
31853
  return format;
31703
31854
  } catch (err) {
@@ -32743,6 +32894,9 @@ function useAccessManagementController() {
32743
32894
  });
32744
32895
  }
32745
32896
  };
32897
+ const removeAccessCard = async ({ cardNo, staffNo, url }) => {
32898
+ return removeAccessGroup({ cardNo, staffNo, url });
32899
+ };
32746
32900
  return {
32747
32901
  addPhysicalCard,
32748
32902
  addNonPhysicalCard,
@@ -32773,7 +32927,8 @@ function useAccessManagementController() {
32773
32927
  vmsgenerateQrCodes,
32774
32928
  addVisitorAccessCard,
32775
32929
  signQrCode,
32776
- checkoutVisitor
32930
+ checkoutVisitor,
32931
+ removeAccessCard
32777
32932
  };
32778
32933
  }
32779
32934
 
@@ -33288,6 +33443,7 @@ function MOccurrenceBook(value) {
33288
33443
  // src/repositories/occurrence-book.repo.ts
33289
33444
  var import_node_server_utils155 = require("@7365admin1/node-server-utils");
33290
33445
  var import_mongodb88 = require("mongodb");
33446
+ var occurrence_book_namespace_collection = "occurrence-books";
33291
33447
  function useOccurrenceBookRepo() {
33292
33448
  const db = import_node_server_utils155.useAtlas.getDb();
33293
33449
  if (!db) {
@@ -33315,18 +33471,21 @@ function useOccurrenceBookRepo() {
33315
33471
  );
33316
33472
  }
33317
33473
  }
33318
- const namespace_collection = "occurrence-books";
33319
- const collection = db.collection(namespace_collection);
33320
- const { delNamespace, getCache, setCache } = (0, import_node_server_utils155.useCache)(namespace_collection);
33474
+ const collection = db.collection(occurrence_book_namespace_collection);
33475
+ const { delNamespace, getCache, setCache } = (0, import_node_server_utils155.useCache)(
33476
+ occurrence_book_namespace_collection
33477
+ );
33321
33478
  async function add(value, session) {
33322
33479
  try {
33323
33480
  value = MOccurrenceBook(value);
33324
33481
  const res = await collection.insertOne(value, { session });
33325
33482
  delNamespace().then(() => {
33326
- import_node_server_utils155.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
33483
+ import_node_server_utils155.logger.info(
33484
+ `Cache cleared for namespace: ${occurrence_book_namespace_collection}`
33485
+ );
33327
33486
  }).catch((err) => {
33328
33487
  import_node_server_utils155.logger.error(
33329
- `Failed to clear cache for namespace: ${namespace_collection}`,
33488
+ `Failed to clear cache for namespace: ${occurrence_book_namespace_collection}`,
33330
33489
  err
33331
33490
  );
33332
33491
  });
@@ -33409,7 +33568,10 @@ function useOccurrenceBookRepo() {
33409
33568
  query.$text = { $search: search };
33410
33569
  cacheOptions.search = search;
33411
33570
  }
33412
- const cacheKey = (0, import_node_server_utils155.makeCacheKey)(namespace_collection, cacheOptions);
33571
+ const cacheKey = (0, import_node_server_utils155.makeCacheKey)(
33572
+ occurrence_book_namespace_collection,
33573
+ cacheOptions
33574
+ );
33413
33575
  const cachedData = await getCache(cacheKey);
33414
33576
  if (cachedData) {
33415
33577
  import_node_server_utils155.logger.info(`Cache hit for key: ${cacheKey}`);
@@ -33443,7 +33605,9 @@ function useOccurrenceBookRepo() {
33443
33605
  } catch (error) {
33444
33606
  throw new import_node_server_utils155.BadRequestError("Invalid occurrence book ID format.");
33445
33607
  }
33446
- const cacheKey = (0, import_node_server_utils155.makeCacheKey)(namespace_collection, { _id });
33608
+ const cacheKey = (0, import_node_server_utils155.makeCacheKey)(occurrence_book_namespace_collection, {
33609
+ _id
33610
+ });
33447
33611
  const cachedData = await getCache(cacheKey);
33448
33612
  if (cachedData) {
33449
33613
  import_node_server_utils155.logger.info(`Cache hit for key: ${cacheKey}`);
@@ -33483,10 +33647,12 @@ function useOccurrenceBookRepo() {
33483
33647
  );
33484
33648
  }
33485
33649
  delNamespace().then(() => {
33486
- import_node_server_utils155.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
33650
+ import_node_server_utils155.logger.info(
33651
+ `Cache cleared for namespace: ${occurrence_book_namespace_collection}`
33652
+ );
33487
33653
  }).catch((err) => {
33488
33654
  import_node_server_utils155.logger.error(
33489
- `Failed to clear cache for namespace: ${namespace_collection}`,
33655
+ `Failed to clear cache for namespace: ${occurrence_book_namespace_collection}`,
33490
33656
  err
33491
33657
  );
33492
33658
  });
@@ -33512,10 +33678,12 @@ function useOccurrenceBookRepo() {
33512
33678
  throw new import_node_server_utils155.InternalServerError("Unable to delete occurrence book.");
33513
33679
  }
33514
33680
  delNamespace().then(() => {
33515
- import_node_server_utils155.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
33681
+ import_node_server_utils155.logger.info(
33682
+ `Cache cleared for namespace: ${occurrence_book_namespace_collection}`
33683
+ );
33516
33684
  }).catch((err) => {
33517
33685
  import_node_server_utils155.logger.error(
33518
- `Failed to clear cache for namespace: ${namespace_collection}`,
33686
+ `Failed to clear cache for namespace: ${occurrence_book_namespace_collection}`,
33519
33687
  err
33520
33688
  );
33521
33689
  });
@@ -33537,10 +33705,12 @@ function useOccurrenceBookRepo() {
33537
33705
  throw new import_node_server_utils155.InternalServerError("Unable to close daily occurrence book.");
33538
33706
  }
33539
33707
  delNamespace().then(() => {
33540
- import_node_server_utils155.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
33708
+ import_node_server_utils155.logger.info(
33709
+ `Cache cleared for namespace: ${occurrence_book_namespace_collection}`
33710
+ );
33541
33711
  }).catch((err) => {
33542
33712
  import_node_server_utils155.logger.error(
33543
- `Failed to clear cache for namespace: ${namespace_collection}`,
33713
+ `Failed to clear cache for namespace: ${occurrence_book_namespace_collection}`,
33544
33714
  err
33545
33715
  );
33546
33716
  });
@@ -33549,6 +33719,47 @@ function useOccurrenceBookRepo() {
33549
33719
  throw error;
33550
33720
  }
33551
33721
  }
33722
+ async function bulkCreate(payloads, session) {
33723
+ try {
33724
+ if (!payloads.length) {
33725
+ return { insertedCount: 0 };
33726
+ }
33727
+ const chunkSize = 500;
33728
+ let totalInserted = 0;
33729
+ for (let i = 0; i < payloads.length; i += chunkSize) {
33730
+ const chunk = payloads.slice(i, i + chunkSize);
33731
+ const operations = chunk.map((item) => ({
33732
+ insertOne: {
33733
+ document: {
33734
+ ...item,
33735
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
33736
+ updatedAt: "",
33737
+ deletedAt: ""
33738
+ }
33739
+ }
33740
+ }));
33741
+ const result = await collection.bulkWrite(operations, { session });
33742
+ totalInserted += result.insertedCount || 0;
33743
+ }
33744
+ import_node_server_utils155.logger.info(
33745
+ `Bulk insert successful: ${totalInserted} occurrence books created.`
33746
+ );
33747
+ delNamespace().then(() => {
33748
+ import_node_server_utils155.logger.info(
33749
+ `Cache cleared for namespace: ${occurrence_book_namespace_collection}`
33750
+ );
33751
+ }).catch((err) => {
33752
+ import_node_server_utils155.logger.error(
33753
+ `Failed to clear cache for namespace: ${occurrence_book_namespace_collection}`,
33754
+ err
33755
+ );
33756
+ });
33757
+ return { insertedCount: totalInserted };
33758
+ } catch (error) {
33759
+ import_node_server_utils155.logger.error("Bulk insert failed for occurrence books", error);
33760
+ throw error;
33761
+ }
33762
+ }
33552
33763
  return {
33553
33764
  add,
33554
33765
  getAll,
@@ -33557,7 +33768,8 @@ function useOccurrenceBookRepo() {
33557
33768
  deleteOccurrenceBookById,
33558
33769
  closeOccurrenceBooks,
33559
33770
  createIndexes,
33560
- createTextIndex
33771
+ createTextIndex,
33772
+ bulkCreate
33561
33773
  };
33562
33774
  }
33563
33775
 
@@ -33567,14 +33779,18 @@ function useOccurrenceBookService() {
33567
33779
  const {
33568
33780
  add: _add,
33569
33781
  updateOccurrenceBookById: _updateOccurrenceBookById,
33570
- closeOccurrenceBooks: _closeOccurrenceBooks
33782
+ closeOccurrenceBooks: _closeOccurrenceBooks,
33783
+ bulkCreate: _bulkCreate
33571
33784
  } = useOccurrenceBookRepo();
33572
33785
  const {
33573
33786
  add: _addOccurrenceCounter,
33574
33787
  incrementByType: _incrementByType,
33575
33788
  getByType: _getByType
33576
33789
  } = useCounterRepo();
33577
- const { getAllSites: _getAllSites } = useSiteRepo();
33790
+ const {
33791
+ getAllSites: _getAllSites,
33792
+ getAllSitesUnpaginated: _getAllSitesUnpaginated
33793
+ } = useSiteRepo();
33578
33794
  async function add(value) {
33579
33795
  const session = import_node_server_utils156.useAtlas.getClient()?.startSession();
33580
33796
  session?.startTransaction();
@@ -33612,39 +33828,31 @@ function useOccurrenceBookService() {
33612
33828
  }
33613
33829
  }
33614
33830
  async function processCreateDOB() {
33615
- const limit = 100;
33616
33831
  const counterName = "occurrence-book";
33617
- let page = 1;
33618
33832
  let entryCounter = 0;
33619
33833
  const session = import_node_server_utils156.useAtlas.getClient()?.startSession();
33620
- session?.startTransaction();
33621
- const existingCounter = await _getByType(counterName);
33622
- if (!existingCounter) {
33623
- await _addOccurrenceCounter(counterName);
33624
- } else {
33625
- await _incrementByType(counterName, session);
33626
- entryCounter = existingCounter.count + 1;
33627
- }
33628
- const baseDate = /* @__PURE__ */ new Date();
33629
- baseDate.setUTCMinutes(0, 0, 0);
33630
- const closedAt = new Date(baseDate);
33631
- closedAt.setUTCDate(closedAt.getUTCDate() + 3);
33632
33834
  try {
33633
- while (true) {
33634
- const sites = await _getAllSites({ page, limit });
33635
- if (sites.items.length === 0)
33636
- break;
33637
- for (const site of sites.items) {
33638
- const occurenceBookPayload = {
33639
- site: site._id,
33640
- date: baseDate.toISOString(),
33641
- closedAt: closedAt.toISOString(),
33642
- entryCounter
33643
- };
33644
- await _add(occurenceBookPayload, session);
33645
- }
33646
- page++;
33647
- }
33835
+ session?.startTransaction();
33836
+ const existingCounter = await _getByType(counterName);
33837
+ if (!existingCounter) {
33838
+ await _addOccurrenceCounter(counterName);
33839
+ entryCounter = 1;
33840
+ } else {
33841
+ entryCounter = existingCounter.count + 1;
33842
+ await _incrementByType(counterName);
33843
+ }
33844
+ const baseDate = /* @__PURE__ */ new Date();
33845
+ baseDate.setUTCMinutes(0, 0, 0);
33846
+ const closedAt = new Date(baseDate);
33847
+ closedAt.setUTCDate(closedAt.getUTCDate() + 3);
33848
+ const sites = await _getAllSitesUnpaginated();
33849
+ const payloads = sites.map((site) => ({
33850
+ site: site._id,
33851
+ date: baseDate.toISOString(),
33852
+ closedAt: closedAt.toISOString(),
33853
+ entryCounter
33854
+ }));
33855
+ await _bulkCreate(payloads, session);
33648
33856
  await session?.commitTransaction();
33649
33857
  } catch (err) {
33650
33858
  await session?.abortTransaction();
@@ -40167,6 +40375,8 @@ var import_node_server_utils194 = require("@7365admin1/node-server-utils");
40167
40375
 
40168
40376
  // src/utils/hrmlabs-attendance.util.ts
40169
40377
  var import_axios2 = __toESM(require("axios"));
40378
+ var import_moment_timezone = __toESM(require("moment-timezone"));
40379
+ var default_early_checkIn = 4;
40170
40380
  async function hrmLabsAuthentication({
40171
40381
  authUrl,
40172
40382
  username,
@@ -40193,6 +40403,205 @@ async function hrmLabsAuthentication({
40193
40403
  "HRMLabs Authentication failed. Please check your credentials."
40194
40404
  );
40195
40405
  }
40406
+ async function fetchAttendanceData({
40407
+ attendanceUrl,
40408
+ token,
40409
+ startDate,
40410
+ endDate,
40411
+ siteName,
40412
+ search
40413
+ }) {
40414
+ try {
40415
+ const res = await import_axios2.default.post(
40416
+ attendanceUrl,
40417
+ {
40418
+ start: startDate,
40419
+ end: endDate,
40420
+ locationName: siteName,
40421
+ search
40422
+ },
40423
+ {
40424
+ headers: { Authorization: `Bearer ${token}` },
40425
+ validateStatus: () => true
40426
+ }
40427
+ );
40428
+ if (res.status >= 200 && res.status < 300 && res.data?.success) {
40429
+ return { success: true, data: res.data.data || [] };
40430
+ }
40431
+ return {
40432
+ success: false,
40433
+ message: `Attendance API failed with status ${res.status}`,
40434
+ data: []
40435
+ };
40436
+ } catch (error) {
40437
+ console.error("fetchAttendanceData error:", error.message || error);
40438
+ return {
40439
+ success: false,
40440
+ message: error?.message || "Unknown error while fetching attendance data",
40441
+ data: []
40442
+ };
40443
+ }
40444
+ }
40445
+ function filterByShiftTime(attendance, shiftData, timezone, format) {
40446
+ return attendance.filter((item) => {
40447
+ if (!item.checkIn)
40448
+ return false;
40449
+ const checkInLocal = (0, import_moment_timezone.default)(item.checkIn, format);
40450
+ if (!checkInLocal.isValid())
40451
+ return false;
40452
+ const [startHour, startMinute] = shiftData.checkIn.split(":").map(Number);
40453
+ const [endHour, endMinute] = shiftData.checkOut.split(":").map(Number);
40454
+ const shiftStart = (0, import_moment_timezone.default)(checkInLocal).set({ hour: startHour, minute: startMinute, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
40455
+ const shiftEnd = (0, import_moment_timezone.default)(checkInLocal).set({
40456
+ hour: endHour,
40457
+ minute: endMinute,
40458
+ second: 0,
40459
+ millisecond: 0
40460
+ }).subtract(default_early_checkIn, "hour");
40461
+ if (shiftEnd.isBefore(shiftStart))
40462
+ shiftEnd.add(1, "day");
40463
+ return checkInLocal.isBetween(shiftStart, shiftEnd, null, "[]");
40464
+ });
40465
+ }
40466
+ function paginate49(data, page, limit) {
40467
+ const length = data.length;
40468
+ const startIndex = (page - 1) * limit;
40469
+ const endIndex = startIndex + limit;
40470
+ return {
40471
+ items: data.slice(startIndex, endIndex),
40472
+ pages: Math.ceil(length / limit),
40473
+ pageRange: `${startIndex + 1}-${Math.min(endIndex, length)} of ${length}`
40474
+ };
40475
+ }
40476
+ function designationCount(attendance, designationConfig, shiftName) {
40477
+ let data = [];
40478
+ const seen = /* @__PURE__ */ new Set();
40479
+ const count = {};
40480
+ const uniqueAttendanceData = attendance.filter((item) => {
40481
+ if (seen.has(item.identificationNumber))
40482
+ return false;
40483
+ seen.add(item.identificationNumber);
40484
+ return true;
40485
+ });
40486
+ for (const record of uniqueAttendanceData) {
40487
+ count[record.jobTitle] = (count[record.jobTitle] || 0) + 1;
40488
+ }
40489
+ let total = 0;
40490
+ const result = [];
40491
+ const addedTitles = /* @__PURE__ */ new Set();
40492
+ const shiftMap = {
40493
+ "Day Shift": "morningShift",
40494
+ "Afternoon Shift": "afternoonShift",
40495
+ "Night Shift": "nightShift"
40496
+ };
40497
+ for (const designation of designationConfig.designations) {
40498
+ const title = designation.title;
40499
+ const shifts = designation.shifts;
40500
+ if (shiftName === "all") {
40501
+ total = (shifts.morningShift || 0) + (shifts.afternoonShift || 0) + (shifts.nightShift || 0);
40502
+ } else {
40503
+ total = shifts[shiftMap[shiftName]] || 0;
40504
+ }
40505
+ const countValue = count[title] ?? 0;
40506
+ result.push({
40507
+ name: title,
40508
+ count: countValue,
40509
+ total
40510
+ });
40511
+ addedTitles.add(title);
40512
+ }
40513
+ for (const title in count) {
40514
+ if (!addedTitles.has(title)) {
40515
+ result.push({
40516
+ name: title,
40517
+ count: count[title],
40518
+ total: 0
40519
+ });
40520
+ }
40521
+ }
40522
+ return result;
40523
+ }
40524
+ function totalCountPerShift(attendance, shiftData, timezone, format) {
40525
+ let totalCountPerShift3 = [];
40526
+ const seen = /* @__PURE__ */ new Set();
40527
+ const uniqueAttendanceData = [];
40528
+ for (const item of attendance) {
40529
+ if (!seen.has(item.identificationNumber)) {
40530
+ const duplicates = attendance.filter(
40531
+ (a) => a.identificationNumber === item.identificationNumber
40532
+ );
40533
+ if (duplicates.length > 1) {
40534
+ const preferred = duplicates.find((a) => a.timeDiff > 0.1) || item;
40535
+ uniqueAttendanceData.push(preferred);
40536
+ } else {
40537
+ uniqueAttendanceData.push(item);
40538
+ }
40539
+ seen.add(item.identificationNumber);
40540
+ }
40541
+ }
40542
+ let data = [];
40543
+ for (const shift of shiftData) {
40544
+ data = uniqueAttendanceData.filter((item) => {
40545
+ if (!item.checkIn)
40546
+ return false;
40547
+ const checkInLocal = (0, import_moment_timezone.default)(item.checkIn, format);
40548
+ if (!checkInLocal.isValid())
40549
+ return false;
40550
+ const [startHour, startMinute] = shift.checkIn.split(":").map(Number);
40551
+ const [endHour, endMinute] = shift.checkOut.split(":").map(Number);
40552
+ const shiftStart = (0, import_moment_timezone.default)(checkInLocal).set({
40553
+ hour: startHour,
40554
+ minute: startMinute,
40555
+ second: 0,
40556
+ millisecond: 0
40557
+ }).subtract(default_early_checkIn, "hour");
40558
+ const shiftEnd = (0, import_moment_timezone.default)(checkInLocal).set({
40559
+ hour: endHour,
40560
+ minute: endMinute,
40561
+ second: 0,
40562
+ millisecond: 0
40563
+ }).subtract(default_early_checkIn, "hour");
40564
+ if (shiftEnd.isBefore(shiftStart))
40565
+ shiftEnd.add(1, "day");
40566
+ return checkInLocal.isBetween(shiftStart, shiftEnd, null, "[]");
40567
+ });
40568
+ totalCountPerShift3.push(data.length);
40569
+ }
40570
+ const shiftInsertMap = {
40571
+ "Day Shift": (data2) => data2.push(0),
40572
+ "Afternoon Shift": (data2) => data2.splice(1, 0, 0),
40573
+ "Night Shift": (data2) => data2.unshift(0)
40574
+ };
40575
+ if (shiftData.length === 1) {
40576
+ const shiftName = shiftData[0]?.name;
40577
+ const insertFn = shiftInsertMap[shiftName];
40578
+ if (insertFn) {
40579
+ insertFn(totalCountPerShift3);
40580
+ }
40581
+ }
40582
+ return totalCountPerShift3;
40583
+ }
40584
+ function filterByStatus(attendance, shiftData, timezone, format, status) {
40585
+ return attendance.filter((item) => {
40586
+ if (!item.checkIn)
40587
+ return false;
40588
+ const checkInLocal = (0, import_moment_timezone.default)(item.checkIn, format);
40589
+ if (!checkInLocal.isValid())
40590
+ return false;
40591
+ const [lateHour, lateMinute] = shiftData.lateCheckInAlert.split(":").map(Number);
40592
+ const lateLoginTime = (0, import_moment_timezone.default)(checkInLocal).set({
40593
+ hour: lateHour,
40594
+ minute: lateMinute,
40595
+ second: 0,
40596
+ millisecond: 0
40597
+ });
40598
+ if (status == "onTime") {
40599
+ return checkInLocal.isBefore(lateLoginTime);
40600
+ } else if (status == "late") {
40601
+ return checkInLocal.isAfter(lateLoginTime);
40602
+ }
40603
+ });
40604
+ }
40196
40605
  function sleep(ms) {
40197
40606
  return new Promise((resolve) => setTimeout(resolve, ms));
40198
40607
  }
@@ -40226,9 +40635,189 @@ async function fetchSites({ siteUrl, token }) {
40226
40635
  } while (attempt < maxRetries);
40227
40636
  throw lastError;
40228
40637
  }
40638
+ async function totalCountPerStatus(attendance, shiftName, shiftData, timezone, format, totalShifts) {
40639
+ const totalCountPerStatus3 = {
40640
+ onTime: 0,
40641
+ late: 0,
40642
+ noShow: 0,
40643
+ earlyOut: 0,
40644
+ totalCount: 0
40645
+ };
40646
+ const seenGlobal = /* @__PURE__ */ new Set();
40647
+ const parseTime = (timeStr) => {
40648
+ const [hour, minute] = timeStr.split(":").map(Number);
40649
+ return { hour, minute };
40650
+ };
40651
+ for (const shift of shiftData) {
40652
+ const shiftStartTime = parseTime(shift.checkIn);
40653
+ const shiftEndTime = parseTime(shift.checkOut);
40654
+ const lateTime = parseTime(shift.lateCheckInAlert);
40655
+ const uniqueAttendanceData = shiftName === "all" ? await filterByShiftTime(attendance, shift, timezone, format) : attendance;
40656
+ for (const item of uniqueAttendanceData) {
40657
+ const {
40658
+ checkIn: checkInStr,
40659
+ checkOut: checkOutStr,
40660
+ identificationNumber
40661
+ } = item;
40662
+ if (!checkInStr || seenGlobal.has(identificationNumber))
40663
+ continue;
40664
+ const checkIn = (0, import_moment_timezone.default)(checkInStr, format);
40665
+ const checkOut = checkOutStr ? (0, import_moment_timezone.default)(checkOutStr, format) : null;
40666
+ const checkOutChecker = checkOut ? (0, import_moment_timezone.default)(checkOutStr, format) : checkIn;
40667
+ if (!checkIn.isValid())
40668
+ continue;
40669
+ const shiftStart = (0, import_moment_timezone.default)(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
40670
+ const shiftEnd = (0, import_moment_timezone.default)(checkOutChecker).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
40671
+ const lateCheckIn = (0, import_moment_timezone.default)(checkIn).set({
40672
+ ...lateTime,
40673
+ second: 59,
40674
+ millisecond: 59
40675
+ });
40676
+ if (shiftEnd.isBefore(shiftStart))
40677
+ shiftEnd.add(1, "day");
40678
+ if (checkIn.isBetween(shiftStart, shiftEnd, null, "[]")) {
40679
+ seenGlobal.add(identificationNumber);
40680
+ if (checkIn.isSameOrBefore(lateCheckIn)) {
40681
+ totalCountPerStatus3.onTime++;
40682
+ } else {
40683
+ totalCountPerStatus3.late++;
40684
+ }
40685
+ if (checkOut && item.timeDiff < 12) {
40686
+ totalCountPerStatus3.earlyOut++;
40687
+ }
40688
+ }
40689
+ }
40690
+ }
40691
+ const shiftMap = {
40692
+ "Day Shift": totalShifts.morningShift,
40693
+ "Afternoon Shift": totalShifts.afternoonShift,
40694
+ "Night Shift": totalShifts.nightShift,
40695
+ all: totalShifts.morningShift + totalShifts.afternoonShift + totalShifts.nightShift
40696
+ };
40697
+ const totalPresent = totalCountPerStatus3.onTime + totalCountPerStatus3.late;
40698
+ totalCountPerStatus3.noShow = shiftMap[shiftName] - totalPresent;
40699
+ totalCountPerStatus3.totalCount = shiftMap[shiftName];
40700
+ return totalCountPerStatus3;
40701
+ }
40702
+ async function chartCountData(attendance, shiftData, timezone, format, totalShifts, startDateStr, endDateStr, status = "all") {
40703
+ const categorizedData = [];
40704
+ const seenPerDay = /* @__PURE__ */ new Set();
40705
+ const parseTime = (timeStr) => {
40706
+ const [hour, minute] = timeStr.split(":").map(Number);
40707
+ return { hour, minute };
40708
+ };
40709
+ const startDate = (0, import_moment_timezone.default)(startDateStr, "DD-MM-YYYY");
40710
+ const endDate = (0, import_moment_timezone.default)(endDateStr, "DD-MM-YYYY");
40711
+ const daysInRange = [];
40712
+ for (let day = startDate.clone(); day.isSameOrBefore(endDate); day.add(1, "day")) {
40713
+ daysInRange.push(day.format("DD-MM-YYYY"));
40714
+ }
40715
+ for (const day of daysInRange) {
40716
+ const dailyData = { date: day, late: 0, under: 0, over: 0, normal: 0 };
40717
+ const dailyAttendance = attendance.filter((item) => {
40718
+ const checkInDate = item.checkIn.split(" ")[0];
40719
+ return checkInDate === day;
40720
+ });
40721
+ const [morningCount, nightCount] = totalCountPerShift(
40722
+ dailyAttendance,
40723
+ shiftData,
40724
+ timezone,
40725
+ format
40726
+ );
40727
+ if (status === "all" || status === "under" || status === "over") {
40728
+ const shifts = [
40729
+ {
40730
+ label: "morningShift",
40731
+ expected: totalShifts.morningShift,
40732
+ actual: morningCount
40733
+ },
40734
+ {
40735
+ label: "nightShift",
40736
+ expected: totalShifts.nightShift,
40737
+ actual: nightCount
40738
+ }
40739
+ ];
40740
+ const today = /* @__PURE__ */ new Date();
40741
+ today.setHours(0, 0, 0, 0);
40742
+ for (const { label, expected, actual } of shifts) {
40743
+ const [dayPart, month, year] = day.split("-");
40744
+ const currentDay = /* @__PURE__ */ new Date(`${year}-${month}-${dayPart}`);
40745
+ currentDay.setHours(0, 0, 0, 0);
40746
+ if (currentDay <= today) {
40747
+ if (status === "all") {
40748
+ if (actual < expected)
40749
+ dailyData.under++;
40750
+ else if (actual > expected)
40751
+ dailyData.over++;
40752
+ else
40753
+ dailyData.normal++;
40754
+ } else if (status === "under" && actual < expected) {
40755
+ dailyData.under++;
40756
+ } else if (status === "over" && actual > expected) {
40757
+ dailyData.over++;
40758
+ }
40759
+ }
40760
+ }
40761
+ }
40762
+ if (status === "late" || status === "all") {
40763
+ for (const shift of shiftData) {
40764
+ const shiftStartTime = parseTime(shift.checkIn);
40765
+ const shiftEndTime = parseTime(shift.checkOut);
40766
+ const lateTime = parseTime(shift.lateCheckInAlert);
40767
+ const uniqueAttendanceData = await filterByShiftTime(
40768
+ dailyAttendance,
40769
+ shift,
40770
+ timezone,
40771
+ format
40772
+ );
40773
+ for (const item of uniqueAttendanceData) {
40774
+ const {
40775
+ checkIn: checkInStr,
40776
+ checkOut: checkOutStr,
40777
+ identificationNumber
40778
+ } = item;
40779
+ if (!checkInStr)
40780
+ continue;
40781
+ const checkIn = (0, import_moment_timezone.default)(checkInStr, format);
40782
+ if (!checkIn.isValid())
40783
+ continue;
40784
+ const dayKey = `${identificationNumber}-${checkIn.format(
40785
+ "YYYY-MM-DD"
40786
+ )}`;
40787
+ if (seenPerDay.has(dayKey))
40788
+ continue;
40789
+ seenPerDay.add(dayKey);
40790
+ const checkOut = checkOutStr ? (0, import_moment_timezone.default)(checkOutStr, format) : checkIn;
40791
+ const shiftStart = (0, import_moment_timezone.default)(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
40792
+ const shiftEnd = (0, import_moment_timezone.default)(checkOut).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
40793
+ const lateCheckIn = (0, import_moment_timezone.default)(checkIn).set({
40794
+ ...lateTime,
40795
+ second: 59,
40796
+ millisecond: 59
40797
+ });
40798
+ if (shiftEnd.isBefore(shiftStart))
40799
+ shiftEnd.add(1, "day");
40800
+ if (checkIn.isBetween(shiftStart, shiftEnd, null, "[]") && checkIn.isAfter(lateCheckIn)) {
40801
+ dailyData.late++;
40802
+ }
40803
+ }
40804
+ }
40805
+ }
40806
+ categorizedData.push(dailyData);
40807
+ }
40808
+ return categorizedData;
40809
+ }
40229
40810
  var hrmlabs_attendance_util_default = {
40230
40811
  hrmLabsAuthentication,
40231
- fetchSites
40812
+ fetchAttendanceData,
40813
+ filterByShiftTime,
40814
+ paginate: paginate49,
40815
+ designationCount,
40816
+ totalCountPerShift,
40817
+ filterByStatus,
40818
+ fetchSites,
40819
+ totalCountPerStatus,
40820
+ chartCountData
40232
40821
  };
40233
40822
 
40234
40823
  // src/repositories/manpower-monitoring.repo.ts
@@ -40239,7 +40828,7 @@ function useManpowerMonitoringRepo() {
40239
40828
  if (!db) {
40240
40829
  throw new Error("Unable to connect to server.");
40241
40830
  }
40242
- const namespace_collection = "manpower-monitoring";
40831
+ const namespace_collection = "manpower-settings";
40243
40832
  const collection = db.collection(namespace_collection);
40244
40833
  const serviceProviderCollection = db.collection("site.service-providers");
40245
40834
  async function createManpowerMonitoringSettings(value, session) {
@@ -40423,17 +41012,202 @@ function useManpowerMonitoringRepo() {
40423
41012
  }
40424
41013
 
40425
41014
  // src/services/manpower-monitoring.service.ts
41015
+ var import_node_server_utils196 = require("@7365admin1/node-server-utils");
41016
+
41017
+ // src/repositories/manpower-remarks.repo.ts
40426
41018
  var import_node_server_utils195 = require("@7365admin1/node-server-utils");
40427
- var import_moment_timezone = __toESM(require("moment-timezone"));
41019
+
41020
+ // src/models/manpower-remarks.model.ts
41021
+ var import_joi112 = __toESM(require("joi"));
41022
+ var import_mongodb109 = require("mongodb");
41023
+ var remarksSchema = import_joi112.default.object({
41024
+ name: import_joi112.default.string().required(),
41025
+ remark: import_joi112.default.object({
41026
+ isAcknowledged: import_joi112.default.boolean().required(),
41027
+ status: import_joi112.default.string().optional().allow("", null),
41028
+ acknowledgementRemarks: import_joi112.default.string().optional().allow("", null),
41029
+ acknowledgedAt: import_joi112.default.string().optional().allow("", null)
41030
+ }).required()
41031
+ });
41032
+ var manpowerRemarksSchema = import_joi112.default.object({
41033
+ siteId: import_joi112.default.string().hex().optional(),
41034
+ siteName: import_joi112.default.string().optional(),
41035
+ remarks: import_joi112.default.array().items(remarksSchema).required(),
41036
+ createdBy: import_joi112.default.string().hex().optional().allow("", null),
41037
+ createdByName: import_joi112.default.string().optional().allow("", null),
41038
+ morningAlertTime: import_joi112.default.string().optional().allow("", null),
41039
+ afternoonAlertTime: import_joi112.default.string().optional().allow("", null),
41040
+ nightAlertTime: import_joi112.default.string().optional().allow("", null),
41041
+ serviceProviderId: import_joi112.default.string().hex().optional(),
41042
+ status: import_joi112.default.string().required()
41043
+ });
41044
+ var MManpowerRemarks = class {
41045
+ constructor(data) {
41046
+ this._id = new import_mongodb109.ObjectId();
41047
+ this.serviceProviderId = data.serviceProviderId || "";
41048
+ this.siteId = data.siteId || "";
41049
+ this.siteName = data.siteName || "";
41050
+ this.remarks = data.remarks || [];
41051
+ this.createdBy = data.createdBy || "";
41052
+ this.createdByName = data.createdByName || "";
41053
+ this.createdAt = /* @__PURE__ */ new Date();
41054
+ this.createdAtSGT = data.createdAtSGT || "";
41055
+ this.updatedAt = data.updatedAt || "";
41056
+ this.morningAlertTime = data.morningAlertTime || "";
41057
+ this.afternoonAlertTime = data.afternoonAlertTime || "";
41058
+ this.nightAlertTime = data.nightAlertTime || "";
41059
+ this.status = data.status || "active";
41060
+ }
41061
+ };
41062
+
41063
+ // src/repositories/manpower-remarks.repo.ts
41064
+ var import_mongodb110 = require("mongodb");
41065
+ var import_moment_timezone2 = __toESM(require("moment-timezone"));
41066
+ function useManpowerRemarksRepo() {
41067
+ const db = import_node_server_utils195.useAtlas.getDb();
41068
+ if (!db) {
41069
+ throw new Error("Unable to connect to server.");
41070
+ }
41071
+ const namespace_collection = "manpower-remarks";
41072
+ const collection = db.collection(namespace_collection);
41073
+ async function createManpowerRemarks(value, session) {
41074
+ try {
41075
+ value = new MManpowerRemarks(value);
41076
+ if (value.siteId)
41077
+ value.siteId = new import_mongodb110.ObjectId(value.siteId);
41078
+ if (value.serviceProviderId)
41079
+ value.serviceProviderId = new import_mongodb110.ObjectId(value.serviceProviderId);
41080
+ const result = await collection.insertOne(value, { session });
41081
+ return result;
41082
+ } catch (error) {
41083
+ throw new Error(error.message || error || "Server Internal Error");
41084
+ }
41085
+ }
41086
+ async function getManpowerRemarksAllSite({
41087
+ page = 1,
41088
+ limit = 10,
41089
+ serviceProviderId = "",
41090
+ search = "",
41091
+ status = "active",
41092
+ date = ""
41093
+ }) {
41094
+ try {
41095
+ page = page ? page - 1 : 0;
41096
+ limit = limit || 10;
41097
+ const searchQuery = {};
41098
+ const nowSGT = (0, import_moment_timezone2.default)().tz("Asia/Singapore");
41099
+ searchQuery.serviceProviderId = new import_mongodb110.ObjectId(serviceProviderId);
41100
+ if (search != "") {
41101
+ searchQuery.siteName = { $regex: search, $options: "i" };
41102
+ }
41103
+ if (status) {
41104
+ searchQuery.status = status;
41105
+ }
41106
+ if (date) {
41107
+ searchQuery.createdAtSGT = date;
41108
+ }
41109
+ const result = await collection.aggregate([
41110
+ { $match: searchQuery },
41111
+ {
41112
+ $facet: {
41113
+ totalCount: [{ $count: "count" }],
41114
+ items: [
41115
+ { $sort: { siteName: 1 } },
41116
+ { $skip: page * limit },
41117
+ { $limit: limit }
41118
+ ]
41119
+ }
41120
+ }
41121
+ ]).toArray();
41122
+ const total = result[0].totalCount[0]?.count || 0;
41123
+ const items = result[0].items;
41124
+ return (0, import_node_server_utils195.paginate)(items, page, limit, total);
41125
+ } catch (error) {
41126
+ throw new Error(error.message || "Server Internal Error");
41127
+ }
41128
+ }
41129
+ async function getManpowerRemarksBySiteId(_id, date, serviceProviderId) {
41130
+ try {
41131
+ _id = new import_mongodb110.ObjectId(_id);
41132
+ serviceProviderId = new import_mongodb110.ObjectId(serviceProviderId);
41133
+ } catch (error) {
41134
+ throw new Error("Invalid Site ID format.");
41135
+ }
41136
+ try {
41137
+ const data = await collection.findOne({
41138
+ siteId: _id,
41139
+ createdAtSGT: date,
41140
+ serviceProviderId
41141
+ });
41142
+ return data;
41143
+ } catch (error) {
41144
+ throw error;
41145
+ }
41146
+ }
41147
+ async function updateManpowerRemarks(_id, value) {
41148
+ try {
41149
+ _id = new import_mongodb110.ObjectId(_id);
41150
+ } catch (error) {
41151
+ throw new import_node_server_utils195.BadRequestError("Invalid ID format.");
41152
+ }
41153
+ try {
41154
+ if (value.createdBy) {
41155
+ value.createdBy = new import_mongodb110.ObjectId(value.createdBy);
41156
+ }
41157
+ const updateValue = {
41158
+ ...value,
41159
+ updatedAt: /* @__PURE__ */ new Date()
41160
+ };
41161
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
41162
+ if (res.modifiedCount === 0) {
41163
+ throw new Error("Unable to update remarks.");
41164
+ }
41165
+ return res.modifiedCount;
41166
+ } catch (error) {
41167
+ throw error;
41168
+ }
41169
+ }
41170
+ async function updateRemarksStatus(_id, value) {
41171
+ try {
41172
+ _id = new import_mongodb110.ObjectId(_id);
41173
+ } catch (error) {
41174
+ throw new import_node_server_utils195.BadRequestError("Invalid ID format.");
41175
+ }
41176
+ try {
41177
+ const updateValue = {
41178
+ ...value,
41179
+ updatedAt: /* @__PURE__ */ new Date()
41180
+ };
41181
+ const res = await collection.updateOne({ _id }, { $set: updateValue });
41182
+ if (res.modifiedCount === 0) {
41183
+ throw new Error("Unable to update remarks status.");
41184
+ }
41185
+ return res.modifiedCount;
41186
+ } catch (error) {
41187
+ throw error;
41188
+ }
41189
+ }
41190
+ return {
41191
+ createManpowerRemarks,
41192
+ getManpowerRemarksAllSite,
41193
+ getManpowerRemarksBySiteId,
41194
+ updateManpowerRemarks,
41195
+ updateRemarksStatus
41196
+ };
41197
+ }
41198
+
41199
+ // src/services/manpower-monitoring.service.ts
41200
+ var import_moment_timezone3 = __toESM(require("moment-timezone"));
40428
41201
  function useManpowerMonitoringSrvc() {
40429
41202
  const {
40430
41203
  createManpowerMonitoringSettings: _createManpowerMonitoringSettings
40431
41204
  } = useManpowerMonitoringRepo();
41205
+ const { createManpowerRemarks: _createManpowerRemarks } = useManpowerRemarksRepo();
40432
41206
  async function createManpowerMonitoringSettings(payload) {
40433
41207
  console.log("Im here now at service");
40434
- const session = import_node_server_utils195.useAtlas.getClient()?.startSession();
41208
+ const session = import_node_server_utils196.useAtlas.getClient()?.startSession();
40435
41209
  if (!session) {
40436
- throw new import_node_server_utils195.BadRequestError("Database session not available.");
41210
+ throw new import_node_server_utils196.BadRequestError("Database session not available.");
40437
41211
  }
40438
41212
  await session.startTransaction();
40439
41213
  const morningCheckInTime = payload?.shifts?.[payload.shiftType][0]?.checkIn;
@@ -40442,10 +41216,10 @@ function useManpowerMonitoringSrvc() {
40442
41216
  const morningAlertFrequencyMins = payload?.shifts?.[payload.shiftType][0]?.alertFrequencyMins;
40443
41217
  const afternoonAlertFrequencyMins = payload.shiftType == "3-shifts" ? payload?.shifts?.[payload.shiftType][1]?.alertFrequencyMins : null;
40444
41218
  const nightAlertFrequencyMins = payload.shiftType == "3-shifts" ? payload?.shifts?.[payload.shiftType][2]?.alertFrequencyMins : payload?.shifts?.[payload.shiftType][1]?.alertFrequencyMins;
40445
- const morningAlertTime = import_moment_timezone.default.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
40446
- const afternoonAlertTime = afternoonCheckInTime ? import_moment_timezone.default.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
40447
- const nightAlertTime = import_moment_timezone.default.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
40448
- const nowSGT = (0, import_moment_timezone.default)().tz("Asia/Singapore");
41219
+ const morningAlertTime = import_moment_timezone3.default.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
41220
+ const afternoonAlertTime = afternoonCheckInTime ? import_moment_timezone3.default.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
41221
+ const nightAlertTime = import_moment_timezone3.default.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
41222
+ const nowSGT = (0, import_moment_timezone3.default)().tz("Asia/Singapore");
40449
41223
  console.log("im done preparing the payload");
40450
41224
  try {
40451
41225
  const remarksPayload = {
@@ -40491,13 +41265,19 @@ function useManpowerMonitoringSrvc() {
40491
41265
  updatedAt: "",
40492
41266
  status: "active"
40493
41267
  };
40494
- console.log("im here at remarks payload");
41268
+ const manpowerRemark = await _createManpowerRemarks(
41269
+ remarksPayload,
41270
+ session
41271
+ );
41272
+ if (!manpowerRemark) {
41273
+ throw new Error("Failed to create manpower remarks");
41274
+ }
40495
41275
  const result = await _createManpowerMonitoringSettings(payload, session);
40496
41276
  await session.commitTransaction();
40497
41277
  return result;
40498
41278
  } catch (error) {
40499
41279
  await session.abortTransaction();
40500
- import_node_server_utils195.logger.error(error.message || error);
41280
+ import_node_server_utils196.logger.error(error.message || error);
40501
41281
  console.error("Error creating monitoring settings:", error);
40502
41282
  throw new Error(error?.message || "Internal Server Error!");
40503
41283
  } finally {
@@ -40510,8 +41290,8 @@ function useManpowerMonitoringSrvc() {
40510
41290
  }
40511
41291
 
40512
41292
  // src/controllers/manpower-monitoring.controller.ts
40513
- var import_node_server_utils196 = require("@7365admin1/node-server-utils");
40514
- var import_joi112 = __toESM(require("joi"));
41293
+ var import_node_server_utils197 = require("@7365admin1/node-server-utils");
41294
+ var import_joi113 = __toESM(require("joi"));
40515
41295
  function useManpowerMonitoringCtrl() {
40516
41296
  const {
40517
41297
  getAllManpowerSettings: _getAllManpowerSettings,
@@ -40528,13 +41308,13 @@ function useManpowerMonitoringCtrl() {
40528
41308
  const payload = { ...req.body };
40529
41309
  const { error } = manpowerMonitoringSchema.validate(payload);
40530
41310
  if (error) {
40531
- next(new import_node_server_utils196.BadRequestError(error.message));
41311
+ next(new import_node_server_utils197.BadRequestError(error.message));
40532
41312
  return;
40533
41313
  }
40534
41314
  const result = await _createManpowerMonitoringSettings(payload);
40535
41315
  return res.json(result);
40536
41316
  } catch (error) {
40537
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41317
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40538
41318
  next(error);
40539
41319
  return;
40540
41320
  }
@@ -40542,14 +41322,14 @@ function useManpowerMonitoringCtrl() {
40542
41322
  async function getAllManpowerSettings(req, res, next) {
40543
41323
  try {
40544
41324
  const { page, search, limit } = req.query;
40545
- const schema2 = import_joi112.default.object({
40546
- page: import_joi112.default.number().optional().allow("", null),
40547
- limit: import_joi112.default.number().optional().allow("", null),
40548
- search: import_joi112.default.string().optional().allow("", null)
41325
+ const schema2 = import_joi113.default.object({
41326
+ page: import_joi113.default.number().optional().allow("", null),
41327
+ limit: import_joi113.default.number().optional().allow("", null),
41328
+ search: import_joi113.default.string().optional().allow("", null)
40549
41329
  });
40550
41330
  const { error } = schema2.validate({ page, search, limit });
40551
41331
  if (error) {
40552
- next(new import_node_server_utils196.BadRequestError(error.message));
41332
+ next(new import_node_server_utils197.BadRequestError(error.message));
40553
41333
  return;
40554
41334
  }
40555
41335
  const result = await _getAllManpowerSettings({
@@ -40559,7 +41339,7 @@ function useManpowerMonitoringCtrl() {
40559
41339
  });
40560
41340
  return res.json(result);
40561
41341
  } catch (error) {
40562
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41342
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40563
41343
  next(error);
40564
41344
  return;
40565
41345
  }
@@ -40568,64 +41348,64 @@ function useManpowerMonitoringCtrl() {
40568
41348
  try {
40569
41349
  const _id = req.params.id;
40570
41350
  const serviceProviderId = req.params.serviceProviderId;
40571
- const schema2 = import_joi112.default.object({
40572
- _id: import_joi112.default.string().hex().required(),
40573
- serviceProviderId: import_joi112.default.string().hex().required()
41351
+ const schema2 = import_joi113.default.object({
41352
+ _id: import_joi113.default.string().hex().required(),
41353
+ serviceProviderId: import_joi113.default.string().hex().required()
40574
41354
  });
40575
41355
  const { error } = schema2.validate({ _id, serviceProviderId });
40576
41356
  if (error) {
40577
- next(new import_node_server_utils196.BadRequestError(error.message));
41357
+ next(new import_node_server_utils197.BadRequestError(error.message));
40578
41358
  return;
40579
41359
  }
40580
41360
  const result = await _getManpowerSettingsBySiteId(_id, serviceProviderId);
40581
41361
  return res.json(result);
40582
41362
  } catch (error) {
40583
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41363
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40584
41364
  next(error);
40585
41365
  return;
40586
41366
  }
40587
41367
  }
40588
41368
  async function updateManpowerMonitoringSettings(req, res, next) {
40589
41369
  try {
40590
- const validation = import_joi112.default.object({
40591
- _id: import_joi112.default.string().hex().required(),
40592
- shiftType: import_joi112.default.string().optional().allow("", null),
40593
- enabled: import_joi112.default.boolean().required(),
40594
- shifts: import_joi112.default.object({
40595
- "2-shifts": import_joi112.default.array().items(shiftSchema).optional(),
40596
- "3-shifts": import_joi112.default.array().items(shiftSchema).optional()
41370
+ const validation = import_joi113.default.object({
41371
+ _id: import_joi113.default.string().hex().required(),
41372
+ shiftType: import_joi113.default.string().optional().allow("", null),
41373
+ enabled: import_joi113.default.boolean().required(),
41374
+ shifts: import_joi113.default.object({
41375
+ "2-shifts": import_joi113.default.array().items(shiftSchema).optional(),
41376
+ "3-shifts": import_joi113.default.array().items(shiftSchema).optional()
40597
41377
  }).optional(),
40598
- emails: import_joi112.default.array().items(import_joi112.default.string().email()).optional()
41378
+ emails: import_joi113.default.array().items(import_joi113.default.string().email()).optional()
40599
41379
  });
40600
41380
  const _id = req.params.id;
40601
41381
  const payload = { ...req.body };
40602
41382
  console.log("_id", _id);
40603
41383
  const { error } = validation.validate({ _id, ...payload });
40604
41384
  if (error) {
40605
- next(new import_node_server_utils196.BadRequestError(error.message));
41385
+ next(new import_node_server_utils197.BadRequestError(error.message));
40606
41386
  return;
40607
41387
  }
40608
41388
  const result = await _updateManpowerMonitoringSettings(_id, payload);
40609
41389
  return res.json(result);
40610
41390
  } catch (error) {
40611
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41391
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40612
41392
  next(error);
40613
41393
  return;
40614
41394
  }
40615
41395
  }
40616
41396
  async function multipleManpowerMonitoringSettings(req, res, next) {
40617
41397
  try {
40618
- const validation = import_joi112.default.array().items(manpowerMonitoringSchema);
41398
+ const validation = import_joi113.default.array().items(manpowerMonitoringSchema);
40619
41399
  const payload = req.body;
40620
41400
  const { error } = validation.validate(payload);
40621
41401
  if (error) {
40622
- next(new import_node_server_utils196.BadRequestError(error.message));
41402
+ next(new import_node_server_utils197.BadRequestError(error.message));
40623
41403
  return;
40624
41404
  }
40625
41405
  const result = await _multipleManpowerMonitoringSettings(payload);
40626
41406
  return res.json(result);
40627
41407
  } catch (error) {
40628
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41408
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40629
41409
  next(error);
40630
41410
  return;
40631
41411
  }
@@ -40633,18 +41413,18 @@ function useManpowerMonitoringCtrl() {
40633
41413
  async function getAllSites(req, res, next) {
40634
41414
  try {
40635
41415
  const serviceProviderId = req.query.serviceProviderId;
40636
- const validation = import_joi112.default.object({
40637
- serviceProviderId: import_joi112.default.string().hex().required()
41416
+ const validation = import_joi113.default.object({
41417
+ serviceProviderId: import_joi113.default.string().hex().required()
40638
41418
  });
40639
41419
  const { error } = validation.validate({ serviceProviderId });
40640
41420
  if (error) {
40641
- next(new import_node_server_utils196.BadRequestError(error.message));
41421
+ next(new import_node_server_utils197.BadRequestError(error.message));
40642
41422
  return;
40643
41423
  }
40644
41424
  const result = await _getAllSites(serviceProviderId);
40645
41425
  return res.json(result);
40646
41426
  } catch (error) {
40647
- import_node_server_utils196.logger.log({ level: "error", message: error.message });
41427
+ import_node_server_utils197.logger.log({ level: "error", message: error.message });
40648
41428
  next(error);
40649
41429
  return;
40650
41430
  }
@@ -40660,27 +41440,27 @@ function useManpowerMonitoringCtrl() {
40660
41440
  }
40661
41441
 
40662
41442
  // src/models/manpower-designations.model.ts
40663
- var import_joi113 = __toESM(require("joi"));
40664
- var import_mongodb109 = require("mongodb");
40665
- var designationsSchema = import_joi113.default.object({
40666
- title: import_joi113.default.string().required(),
40667
- shifts: import_joi113.default.object({
40668
- morningShift: import_joi113.default.number().required(),
40669
- afternoonShift: import_joi113.default.number().optional(),
40670
- nightShift: import_joi113.default.number().required()
41443
+ var import_joi114 = __toESM(require("joi"));
41444
+ var import_mongodb111 = require("mongodb");
41445
+ var designationsSchema = import_joi114.default.object({
41446
+ title: import_joi114.default.string().required(),
41447
+ shifts: import_joi114.default.object({
41448
+ morningShift: import_joi114.default.number().required(),
41449
+ afternoonShift: import_joi114.default.number().optional(),
41450
+ nightShift: import_joi114.default.number().required()
40671
41451
  }).required()
40672
41452
  });
40673
- var manpowerDesignationsSchema = import_joi113.default.object({
40674
- siteId: import_joi113.default.string().hex().required(),
40675
- siteName: import_joi113.default.string().required(),
40676
- serviceProviderId: import_joi113.default.string().hex().optional(),
40677
- designations: import_joi113.default.array().items(designationsSchema).required(),
40678
- createdBy: import_joi113.default.string().hex().required(),
40679
- createdByName: import_joi113.default.string().optional().allow("", null)
41453
+ var manpowerDesignationsSchema = import_joi114.default.object({
41454
+ siteId: import_joi114.default.string().hex().required(),
41455
+ siteName: import_joi114.default.string().required(),
41456
+ serviceProviderId: import_joi114.default.string().hex().optional(),
41457
+ designations: import_joi114.default.array().items(designationsSchema).required(),
41458
+ createdBy: import_joi114.default.string().hex().required(),
41459
+ createdByName: import_joi114.default.string().optional().allow("", null)
40680
41460
  });
40681
41461
  var MManpowerDesignations = class {
40682
41462
  constructor(data) {
40683
- this._id = new import_mongodb109.ObjectId();
41463
+ this._id = new import_mongodb111.ObjectId();
40684
41464
  this.siteId = data.siteId || "";
40685
41465
  this.siteName = data.siteName || "";
40686
41466
  this.serviceProviderId = data.serviceProviderId || "";
@@ -40693,10 +41473,10 @@ var MManpowerDesignations = class {
40693
41473
  };
40694
41474
 
40695
41475
  // src/repositories/manpower-designations.repo.ts
40696
- var import_node_server_utils197 = require("@7365admin1/node-server-utils");
40697
- var import_mongodb110 = require("mongodb");
41476
+ var import_node_server_utils198 = require("@7365admin1/node-server-utils");
41477
+ var import_mongodb112 = require("mongodb");
40698
41478
  function useManpowerDesignationRepo() {
40699
- const db = import_node_server_utils197.useAtlas.getDb();
41479
+ const db = import_node_server_utils198.useAtlas.getDb();
40700
41480
  if (!db) {
40701
41481
  throw new Error("Unable to connect to server.");
40702
41482
  }
@@ -40706,11 +41486,11 @@ function useManpowerDesignationRepo() {
40706
41486
  try {
40707
41487
  value = new MManpowerDesignations(value);
40708
41488
  if (value.createdBy)
40709
- value.createdBy = new import_mongodb110.ObjectId(value.createdBy);
41489
+ value.createdBy = new import_mongodb112.ObjectId(value.createdBy);
40710
41490
  if (value.siteId)
40711
- value.siteId = new import_mongodb110.ObjectId(value.siteId);
41491
+ value.siteId = new import_mongodb112.ObjectId(value.siteId);
40712
41492
  if (value.serviceProviderId)
40713
- value.serviceProviderId = new import_mongodb110.ObjectId(value.serviceProviderId);
41493
+ value.serviceProviderId = new import_mongodb112.ObjectId(value.serviceProviderId);
40714
41494
  const result = await collection.insertOne(value);
40715
41495
  return result;
40716
41496
  } catch (error) {
@@ -40719,8 +41499,8 @@ function useManpowerDesignationRepo() {
40719
41499
  }
40720
41500
  async function getManpowerDesignationsBySiteId(_id, serviceProviderId) {
40721
41501
  try {
40722
- _id = new import_mongodb110.ObjectId(_id);
40723
- serviceProviderId = new import_mongodb110.ObjectId(serviceProviderId);
41502
+ _id = new import_mongodb112.ObjectId(_id);
41503
+ serviceProviderId = new import_mongodb112.ObjectId(serviceProviderId);
40724
41504
  } catch (error) {
40725
41505
  throw new Error("Invalid Site ID format.");
40726
41506
  }
@@ -40736,7 +41516,7 @@ function useManpowerDesignationRepo() {
40736
41516
  }
40737
41517
  async function updateManpowerDesignations(_id, value) {
40738
41518
  try {
40739
- _id = new import_mongodb110.ObjectId(_id);
41519
+ _id = new import_mongodb112.ObjectId(_id);
40740
41520
  } catch (error) {
40741
41521
  throw new Error("Invalid ID format.");
40742
41522
  }
@@ -40762,8 +41542,8 @@ function useManpowerDesignationRepo() {
40762
41542
  }
40763
41543
 
40764
41544
  // src/controllers/manpower-designations.controller.ts
40765
- var import_node_server_utils198 = require("@7365admin1/node-server-utils");
40766
- var import_joi114 = __toESM(require("joi"));
41545
+ var import_node_server_utils199 = require("@7365admin1/node-server-utils");
41546
+ var import_joi115 = __toESM(require("joi"));
40767
41547
  function useManpowerDesignationCtrl() {
40768
41548
  const {
40769
41549
  createManpowerDesignations: _createManpowerDesignations,
@@ -40775,13 +41555,13 @@ function useManpowerDesignationCtrl() {
40775
41555
  const payload = { ...req.body };
40776
41556
  const { error } = manpowerDesignationsSchema.validate(payload);
40777
41557
  if (error) {
40778
- next(new import_node_server_utils198.BadRequestError(error.message));
41558
+ next(new import_node_server_utils199.BadRequestError(error.message));
40779
41559
  return;
40780
41560
  }
40781
41561
  const result = await _createManpowerDesignations(payload);
40782
41562
  return res.json(result);
40783
41563
  } catch (error) {
40784
- import_node_server_utils198.logger.log({ level: "error", message: error.message });
41564
+ import_node_server_utils199.logger.log({ level: "error", message: error.message });
40785
41565
  next(error);
40786
41566
  return;
40787
41567
  }
@@ -40789,13 +41569,13 @@ function useManpowerDesignationCtrl() {
40789
41569
  async function getManpowerSettingsBySiteId(req, res, next) {
40790
41570
  try {
40791
41571
  const { id, serviceProviderId } = req.params;
40792
- const schema2 = import_joi114.default.object({
40793
- id: import_joi114.default.string().hex().required(),
40794
- serviceProviderId: import_joi114.default.string().hex().required()
41572
+ const schema2 = import_joi115.default.object({
41573
+ id: import_joi115.default.string().hex().required(),
41574
+ serviceProviderId: import_joi115.default.string().hex().required()
40795
41575
  });
40796
41576
  const { error } = schema2.validate({ id, serviceProviderId });
40797
41577
  if (error) {
40798
- next(new import_node_server_utils198.BadRequestError(error.message));
41578
+ next(new import_node_server_utils199.BadRequestError(error.message));
40799
41579
  return;
40800
41580
  }
40801
41581
  const result = await _getManpowerDesignationsBySiteId(
@@ -40804,28 +41584,28 @@ function useManpowerDesignationCtrl() {
40804
41584
  );
40805
41585
  return res.json(result);
40806
41586
  } catch (error) {
40807
- import_node_server_utils198.logger.log({ level: "error", message: error.message });
41587
+ import_node_server_utils199.logger.log({ level: "error", message: error.message });
40808
41588
  next(error);
40809
41589
  return;
40810
41590
  }
40811
41591
  }
40812
41592
  async function updateManpowerDesignations(req, res, next) {
40813
41593
  try {
40814
- const validation = import_joi114.default.object({
40815
- _id: import_joi114.default.string().hex().required(),
40816
- designations: import_joi114.default.array().items(designationsSchema).required()
41594
+ const validation = import_joi115.default.object({
41595
+ _id: import_joi115.default.string().hex().required(),
41596
+ designations: import_joi115.default.array().items(designationsSchema).required()
40817
41597
  });
40818
41598
  const _id = req.params.id;
40819
41599
  const payload = { ...req.body };
40820
41600
  const { error } = validation.validate({ _id, ...payload });
40821
41601
  if (error) {
40822
- next(new import_node_server_utils198.BadRequestError(error.message));
41602
+ next(new import_node_server_utils199.BadRequestError(error.message));
40823
41603
  return;
40824
41604
  }
40825
41605
  const result = await _updateManpowerDesignations(_id, payload);
40826
41606
  return res.json(result);
40827
41607
  } catch (error) {
40828
- import_node_server_utils198.logger.log({ level: "error", message: error.message });
41608
+ import_node_server_utils199.logger.log({ level: "error", message: error.message });
40829
41609
  next(error);
40830
41610
  return;
40831
41611
  }
@@ -40838,20 +41618,30 @@ function useManpowerDesignationCtrl() {
40838
41618
  }
40839
41619
 
40840
41620
  // src/models/overnight-parking.model.ts
40841
- var import_joi115 = __toESM(require("joi"));
40842
- var import_mongodb111 = require("mongodb");
40843
- var dayScheduleSchema = import_joi115.default.object({
40844
- isEnabled: import_joi115.default.boolean().required(),
40845
- startTime: import_joi115.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).required().messages({
41621
+ var import_joi116 = __toESM(require("joi"));
41622
+ var import_mongodb113 = require("mongodb");
41623
+ var dayScheduleSchema = import_joi116.default.object({
41624
+ isEnabled: import_joi116.default.boolean().required(),
41625
+ startTime: import_joi116.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
40846
41626
  "string.pattern.base": "startTime must be in HH:mm format"
40847
41627
  }),
40848
- endTime: import_joi115.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).required().messages({
41628
+ endTime: import_joi116.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
40849
41629
  "string.pattern.base": "endTime must be in HH:mm format"
40850
41630
  })
40851
- }).required();
40852
- var schemaOvernightParkingApprovalHours = import_joi115.default.object({
40853
- _id: import_joi115.default.string().hex().length(24).optional(),
40854
- site: import_joi115.default.string().hex().length(24).required(),
41631
+ }).optional().allow(null);
41632
+ var DayOfWeek = /* @__PURE__ */ ((DayOfWeek2) => {
41633
+ DayOfWeek2["SUNDAY"] = "sunday";
41634
+ DayOfWeek2["MONDAY"] = "monday";
41635
+ DayOfWeek2["TUESDAY"] = "tuesday";
41636
+ DayOfWeek2["WEDNESDAY"] = "wednesday";
41637
+ DayOfWeek2["THURSDAY"] = "thursday";
41638
+ DayOfWeek2["FRIDAY"] = "friday";
41639
+ DayOfWeek2["SATURDAY"] = "saturday";
41640
+ return DayOfWeek2;
41641
+ })(DayOfWeek || {});
41642
+ var schemaOvernightParkingApprovalHours = import_joi116.default.object({
41643
+ _id: import_joi116.default.string().hex().length(24).optional(),
41644
+ site: import_joi116.default.string().hex().length(24).required(),
40855
41645
  monday: dayScheduleSchema,
40856
41646
  tuesday: dayScheduleSchema,
40857
41647
  wednesday: dayScheduleSchema,
@@ -40859,9 +41649,10 @@ var schemaOvernightParkingApprovalHours = import_joi115.default.object({
40859
41649
  friday: dayScheduleSchema,
40860
41650
  saturday: dayScheduleSchema,
40861
41651
  sunday: dayScheduleSchema,
40862
- createdAt: import_joi115.default.date().optional(),
40863
- updatedAt: import_joi115.default.date().optional(),
40864
- deletedAt: import_joi115.default.date().optional().allow(null)
41652
+ autoApproveOvernightParking: import_joi116.default.boolean().optional().allow(null).default(false),
41653
+ createdAt: import_joi116.default.date().optional(),
41654
+ updatedAt: import_joi116.default.date().optional(),
41655
+ deletedAt: import_joi116.default.date().optional().allow(null)
40865
41656
  });
40866
41657
  function MOvernightParkingApprovalHours(value) {
40867
41658
  const { error } = schemaOvernightParkingApprovalHours.validate(value);
@@ -40870,29 +41661,37 @@ function MOvernightParkingApprovalHours(value) {
40870
41661
  }
40871
41662
  if (value.site && typeof value.site === "string") {
40872
41663
  try {
40873
- value.site = new import_mongodb111.ObjectId(value.site);
41664
+ value.site = new import_mongodb113.ObjectId(value.site);
40874
41665
  } catch {
40875
41666
  throw new Error("Invalid site ID.");
40876
41667
  }
40877
41668
  }
40878
41669
  const now = (/* @__PURE__ */ new Date()).toISOString();
40879
41670
  return {
40880
- ...value,
41671
+ site: value.site,
41672
+ monday: value.monday ?? null,
41673
+ tuesday: value.tuesday ?? null,
41674
+ wednesday: value.wednesday ?? null,
41675
+ thursday: value.thursday ?? null,
41676
+ friday: value.friday ?? null,
41677
+ saturday: value.saturday ?? null,
41678
+ sunday: value.sunday ?? null,
41679
+ autoApproveOvernightParking: value.autoApproveOvernightParking ?? false,
40881
41680
  createdAt: value.createdAt ?? now,
40882
41681
  updatedAt: value.updatedAt ?? now
40883
41682
  };
40884
41683
  }
40885
41684
 
40886
41685
  // src/repositories/overnight-parking.repo.ts
40887
- var import_node_server_utils199 = require("@7365admin1/node-server-utils");
41686
+ var import_node_server_utils200 = require("@7365admin1/node-server-utils");
40888
41687
  var overnight_parking_namespace_collection = "site.overnight-parking";
40889
41688
  function useOvernightParkingRepo() {
40890
- const db = import_node_server_utils199.useAtlas.getDb();
41689
+ const db = import_node_server_utils200.useAtlas.getDb();
40891
41690
  if (!db) {
40892
- throw new import_node_server_utils199.InternalServerError("Unable to connect to server.");
41691
+ throw new import_node_server_utils200.InternalServerError("Unable to connect to server.");
40893
41692
  }
40894
41693
  const collection = db.collection(overnight_parking_namespace_collection);
40895
- const { delNamespace, setCache, getCache } = (0, import_node_server_utils199.useCache)(
41694
+ const { delNamespace, setCache, getCache } = (0, import_node_server_utils200.useCache)(
40896
41695
  overnight_parking_namespace_collection
40897
41696
  );
40898
41697
  async function createIndexes() {
@@ -40916,7 +41715,7 @@ function useOvernightParkingRepo() {
40916
41715
  await collection.createIndexes(indexesToCreate);
40917
41716
  }
40918
41717
  } catch (error) {
40919
- throw new import_node_server_utils199.InternalServerError("Failed to create collection indexes.");
41718
+ throw new import_node_server_utils200.InternalServerError("Failed to create collection indexes.");
40920
41719
  }
40921
41720
  }
40922
41721
  async function upsert(value, session) {
@@ -40934,6 +41733,7 @@ function useOvernightParkingRepo() {
40934
41733
  friday: value.friday,
40935
41734
  saturday: value.saturday,
40936
41735
  sunday: value.sunday,
41736
+ autoApproveOvernightParking: value.autoApproveOvernightParking,
40937
41737
  updatedAt: now
40938
41738
  },
40939
41739
  $setOnInsert: {
@@ -40944,11 +41744,11 @@ function useOvernightParkingRepo() {
40944
41744
  { upsert: true, session }
40945
41745
  );
40946
41746
  delNamespace().then(() => {
40947
- import_node_server_utils199.logger.info(
41747
+ import_node_server_utils200.logger.info(
40948
41748
  `Cache cleared for namespace: ${overnight_parking_namespace_collection}`
40949
41749
  );
40950
41750
  }).catch((err) => {
40951
- import_node_server_utils199.logger.error(
41751
+ import_node_server_utils200.logger.error(
40952
41752
  `Failed to clear cache for namespace: ${overnight_parking_namespace_collection}`,
40953
41753
  err
40954
41754
  );
@@ -40959,24 +41759,24 @@ function useOvernightParkingRepo() {
40959
41759
  }
40960
41760
  }
40961
41761
  async function getSiteOvernightParking(site) {
40962
- const siteId = (0, import_node_server_utils199.toObjectId)(site);
40963
- const cacheKey = (0, import_node_server_utils199.makeCacheKey)(overnight_parking_namespace_collection, {
41762
+ const siteId = (0, import_node_server_utils200.toObjectId)(site);
41763
+ const cacheKey = (0, import_node_server_utils200.makeCacheKey)(overnight_parking_namespace_collection, {
40964
41764
  site
40965
41765
  });
40966
41766
  const cachedData = await getCache(cacheKey);
40967
41767
  if (cachedData) {
40968
- import_node_server_utils199.logger.info(`Cache hit for key: ${cacheKey}`);
41768
+ import_node_server_utils200.logger.info(`Cache hit for key: ${cacheKey}`);
40969
41769
  return cachedData;
40970
41770
  }
40971
41771
  try {
40972
41772
  const data = await collection.findOne({
40973
41773
  site: siteId,
40974
- deletedAt: null
41774
+ deletedAt: { $nin: ["", null] }
40975
41775
  });
40976
41776
  setCache(cacheKey, data, 15 * 60).then(() => {
40977
- import_node_server_utils199.logger.info(`Cache set for key: ${cacheKey}`);
41777
+ import_node_server_utils200.logger.info(`Cache set for key: ${cacheKey}`);
40978
41778
  }).catch((err) => {
40979
- import_node_server_utils199.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
41779
+ import_node_server_utils200.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
40980
41780
  });
40981
41781
  return data;
40982
41782
  } catch (error) {
@@ -40991,8 +41791,8 @@ function useOvernightParkingRepo() {
40991
41791
  }
40992
41792
 
40993
41793
  // src/controllers/overnight-parking.controller.ts
40994
- var import_joi116 = __toESM(require("joi"));
40995
- var import_node_server_utils200 = require("@7365admin1/node-server-utils");
41794
+ var import_joi117 = __toESM(require("joi"));
41795
+ var import_node_server_utils201 = require("@7365admin1/node-server-utils");
40996
41796
  function useOvernightParkingController() {
40997
41797
  const { upsert: _upsert, getSiteOvernightParking: _getSiteOvernightParking } = useOvernightParkingRepo();
40998
41798
  async function upsert(req, res, next) {
@@ -41007,22 +41807,22 @@ function useOvernightParkingController() {
41007
41807
  );
41008
41808
  if (error) {
41009
41809
  const messages = error.details.map((d) => d.message).join(", ");
41010
- import_node_server_utils200.logger.log({ level: "error", message: messages });
41011
- next(new import_node_server_utils200.BadRequestError(messages));
41810
+ import_node_server_utils201.logger.log({ level: "error", message: messages });
41811
+ next(new import_node_server_utils201.BadRequestError(messages));
41012
41812
  return;
41013
41813
  }
41014
41814
  const data = await _upsert(value);
41015
41815
  res.status(201).json(data);
41016
41816
  return;
41017
41817
  } catch (error) {
41018
- import_node_server_utils200.logger.log({ level: "error", message: error.message });
41818
+ import_node_server_utils201.logger.log({ level: "error", message: error.message });
41019
41819
  next(error);
41020
41820
  return;
41021
41821
  }
41022
41822
  }
41023
41823
  async function getSiteOvernightParking(req, res, next) {
41024
- const schema2 = import_joi116.default.object({
41025
- site: import_joi116.default.string().hex().length(24).required()
41824
+ const schema2 = import_joi117.default.object({
41825
+ site: import_joi117.default.string().hex().length(24).required()
41026
41826
  });
41027
41827
  try {
41028
41828
  const { error, value } = schema2.validate(
@@ -41033,8 +41833,8 @@ function useOvernightParkingController() {
41033
41833
  );
41034
41834
  if (error) {
41035
41835
  const messages = error.details.map((d) => d.message).join(", ");
41036
- import_node_server_utils200.logger.log({ level: "error", message: messages });
41037
- next(new import_node_server_utils200.BadRequestError(messages));
41836
+ import_node_server_utils201.logger.log({ level: "error", message: messages });
41837
+ next(new import_node_server_utils201.BadRequestError(messages));
41038
41838
  return;
41039
41839
  }
41040
41840
  const { site } = value;
@@ -41042,7 +41842,7 @@ function useOvernightParkingController() {
41042
41842
  res.status(201).json(data);
41043
41843
  return;
41044
41844
  } catch (error) {
41045
- import_node_server_utils200.logger.log({ level: "error", message: error.message });
41845
+ import_node_server_utils201.logger.log({ level: "error", message: error.message });
41046
41846
  next(error);
41047
41847
  return;
41048
41848
  }
@@ -41052,6 +41852,2102 @@ function useOvernightParkingController() {
41052
41852
  getSiteOvernightParking
41053
41853
  };
41054
41854
  }
41855
+
41856
+ // src/models/overnight-parking-request.model.ts
41857
+ var import_joi118 = __toESM(require("joi"));
41858
+ var import_node_server_utils202 = require("@7365admin1/node-server-utils");
41859
+ var OvernightParkingRequestStatus = /* @__PURE__ */ ((OvernightParkingRequestStatus2) => {
41860
+ OvernightParkingRequestStatus2["PENDING"] = "pending";
41861
+ OvernightParkingRequestStatus2["APPROVED"] = "approved";
41862
+ OvernightParkingRequestStatus2["REJECTED"] = "rejected";
41863
+ OvernightParkingRequestStatus2["DELETED"] = "deleted";
41864
+ OvernightParkingRequestStatus2["EXPIRED"] = "expired";
41865
+ return OvernightParkingRequestStatus2;
41866
+ })(OvernightParkingRequestStatus || {});
41867
+ var OvernightParkingRequestSort = /* @__PURE__ */ ((OvernightParkingRequestSort2) => {
41868
+ OvernightParkingRequestSort2["ID"] = "_id";
41869
+ OvernightParkingRequestSort2["CREATED_AT"] = "createdAt";
41870
+ return OvernightParkingRequestSort2;
41871
+ })(OvernightParkingRequestSort || {});
41872
+ var schemaOvernightParkingRequest = import_joi118.default.object({
41873
+ _id: import_joi118.default.string().hex().length(24).optional(),
41874
+ site: import_joi118.default.string().hex().length(24).required(),
41875
+ name: import_joi118.default.string().required(),
41876
+ contact: import_joi118.default.string().required(),
41877
+ email: import_joi118.default.string().email().required(),
41878
+ isOvernightParking: import_joi118.default.boolean().optional(),
41879
+ numberOfPassengers: import_joi118.default.number().integer().min(0).optional().default(0),
41880
+ purposeOfVisit: import_joi118.default.string().optional().allow("", null),
41881
+ status: import_joi118.default.string().valid(...Object.values(OvernightParkingRequestStatus)).optional().allow(null, "").default("pending" /* PENDING */),
41882
+ remarks: import_joi118.default.string().optional().allow(null, "")
41883
+ });
41884
+ var schemaUpdateOvernightParkingRequest = import_joi118.default.object({
41885
+ _id: import_joi118.default.string().hex().length(24).required(),
41886
+ status: import_joi118.default.string().valid(...Object.values(OvernightParkingRequestStatus)).required(),
41887
+ remarks: import_joi118.default.string().optional().allow(null, "")
41888
+ });
41889
+ function MOvernightParkingRequest(value) {
41890
+ const { error } = schemaOvernightParkingRequest.validate(value);
41891
+ if (error) {
41892
+ throw new Error(error.details[0].message);
41893
+ }
41894
+ if (value.site && typeof value.site === "string")
41895
+ value.site = (0, import_node_server_utils202.toObjectId)(value.site);
41896
+ const data = {
41897
+ ...value,
41898
+ createdAt: value.createdAt ? new Date(value.createdAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
41899
+ updatedAt: value.updatedAt,
41900
+ deletedAt: value.deletedAt
41901
+ };
41902
+ return data;
41903
+ }
41904
+
41905
+ // src/repositories/overnight-parking-request.repository.ts
41906
+ var import_node_server_utils203 = require("@7365admin1/node-server-utils");
41907
+ var overnight_parking_requests_namespace_collection = "site.overnight-parking-requests";
41908
+ function useOvernightParkingRequestRepo() {
41909
+ const db = import_node_server_utils203.useAtlas.getDb();
41910
+ if (!db) {
41911
+ throw new import_node_server_utils203.InternalServerError("Unable to connect to server.");
41912
+ }
41913
+ const collection = db.collection(
41914
+ overnight_parking_requests_namespace_collection
41915
+ );
41916
+ const { delNamespace, getCache, setCache } = (0, import_node_server_utils203.useCache)(
41917
+ overnight_parking_requests_namespace_collection
41918
+ );
41919
+ async function createIndexes() {
41920
+ try {
41921
+ const existingIndexes = await collection.indexes();
41922
+ const existingNames = new Set(existingIndexes.map((i) => i.name));
41923
+ const indexesToEnsure = [
41924
+ {
41925
+ key: { site: 1 },
41926
+ name: "site-index"
41927
+ },
41928
+ {
41929
+ key: { status: 1 },
41930
+ name: "status-index"
41931
+ }
41932
+ ];
41933
+ const indexesToCreate = indexesToEnsure.filter(
41934
+ (index) => index.name && !existingNames.has(index.name)
41935
+ );
41936
+ if (indexesToCreate.length > 0) {
41937
+ await collection.createIndexes(indexesToCreate);
41938
+ }
41939
+ } catch (error) {
41940
+ throw new import_node_server_utils203.InternalServerError("Failed to create collection indexes.");
41941
+ }
41942
+ }
41943
+ async function add(value, session) {
41944
+ try {
41945
+ value = MOvernightParkingRequest(value);
41946
+ const res = await collection.insertOne(value, { session });
41947
+ delNamespace().then(() => {
41948
+ import_node_server_utils203.logger.info(
41949
+ `Cache cleared for namespace: ${overnight_parking_requests_namespace_collection}`
41950
+ );
41951
+ }).catch((err) => {
41952
+ import_node_server_utils203.logger.error(
41953
+ `Failed to clear cache for namespace: ${overnight_parking_requests_namespace_collection}`,
41954
+ err
41955
+ );
41956
+ });
41957
+ return res.insertedId;
41958
+ } catch (error) {
41959
+ throw error;
41960
+ }
41961
+ }
41962
+ async function getAll({
41963
+ site = "",
41964
+ page = 1,
41965
+ limit = 10,
41966
+ sort = {},
41967
+ status = ""
41968
+ }) {
41969
+ page = page ? page - 1 : 0;
41970
+ const skip = page * limit;
41971
+ const siteId = (0, import_node_server_utils203.toObjectId)(site);
41972
+ const query = {
41973
+ site: siteId,
41974
+ ...status && { status }
41975
+ };
41976
+ const cacheOptions = {
41977
+ site,
41978
+ page,
41979
+ limit,
41980
+ sort: JSON.stringify(sort),
41981
+ ...status && { status }
41982
+ };
41983
+ const cacheKey = (0, import_node_server_utils203.makeCacheKey)(
41984
+ overnight_parking_requests_namespace_collection,
41985
+ cacheOptions
41986
+ );
41987
+ const cachedData = await getCache(cacheKey);
41988
+ if (cachedData) {
41989
+ import_node_server_utils203.logger.info(`Cache hit for key: ${cacheKey}`);
41990
+ return cachedData;
41991
+ }
41992
+ try {
41993
+ const items = await collection.aggregate([
41994
+ { $match: query },
41995
+ { $sort: sort },
41996
+ { $skip: skip },
41997
+ { $limit: limit }
41998
+ ]).toArray();
41999
+ const length = await collection.countDocuments(query);
42000
+ const data = (0, import_node_server_utils203.paginate)(items, page, limit, length);
42001
+ setCache(cacheKey, data, 15 * 60).then(() => {
42002
+ import_node_server_utils203.logger.info(`Cache set for key: ${cacheKey}`);
42003
+ }).catch((err) => {
42004
+ import_node_server_utils203.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
42005
+ });
42006
+ return data;
42007
+ } catch (error) {
42008
+ throw error;
42009
+ }
42010
+ }
42011
+ async function getOvernightParkingRequestById(id) {
42012
+ try {
42013
+ const cacheKey = (0, import_node_server_utils203.makeCacheKey)(
42014
+ overnight_parking_requests_namespace_collection,
42015
+ { id }
42016
+ );
42017
+ const cachedData = await getCache(cacheKey);
42018
+ if (cachedData) {
42019
+ import_node_server_utils203.logger.info(`Cache hit for key: ${cacheKey}`);
42020
+ return cachedData;
42021
+ }
42022
+ const _id = (0, import_node_server_utils203.toObjectId)(id);
42023
+ const data = await collection.findOne({ _id });
42024
+ if (!data)
42025
+ throw new import_node_server_utils203.BadRequestError("Overnight parking request not found.");
42026
+ setCache(cacheKey, data, 15 * 60).then(() => {
42027
+ import_node_server_utils203.logger.info(`Cache set for key: ${cacheKey}`);
42028
+ }).catch((err) => {
42029
+ import_node_server_utils203.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
42030
+ });
42031
+ return data;
42032
+ } catch (error) {
42033
+ throw error;
42034
+ }
42035
+ }
42036
+ async function updateOvernightParkingRequestById(id, value, session) {
42037
+ try {
42038
+ const _id = (0, import_node_server_utils203.toObjectId)(id);
42039
+ value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
42040
+ const data = await collection.updateOne(
42041
+ { _id },
42042
+ { $set: value },
42043
+ { session }
42044
+ );
42045
+ if (data.matchedCount === 0)
42046
+ throw new import_node_server_utils203.BadRequestError("Overnight parking request not found.");
42047
+ delNamespace().then(() => {
42048
+ import_node_server_utils203.logger.info(
42049
+ `Cache cleared for namespace: ${overnight_parking_requests_namespace_collection}`
42050
+ );
42051
+ }).catch((err) => {
42052
+ import_node_server_utils203.logger.error(
42053
+ `Failed to clear cache for namespace: ${overnight_parking_requests_namespace_collection}`,
42054
+ err
42055
+ );
42056
+ });
42057
+ return data;
42058
+ } catch (error) {
42059
+ throw error;
42060
+ }
42061
+ }
42062
+ async function deleteOvernightParkingRequestById(id, session) {
42063
+ try {
42064
+ const _id = (0, import_node_server_utils203.toObjectId)(id);
42065
+ const value = {
42066
+ deletedAt: (/* @__PURE__ */ new Date()).toISOString(),
42067
+ status: "deleted" /* DELETED */
42068
+ };
42069
+ const data = await collection.updateOne(
42070
+ { _id },
42071
+ { $set: value },
42072
+ { session }
42073
+ );
42074
+ if (data.matchedCount === 0)
42075
+ throw new import_node_server_utils203.BadRequestError("Overnight parking request not found.");
42076
+ delNamespace().then(() => {
42077
+ import_node_server_utils203.logger.info(
42078
+ `Cache cleared for namespace: ${overnight_parking_requests_namespace_collection}`
42079
+ );
42080
+ }).catch((err) => {
42081
+ import_node_server_utils203.logger.error(
42082
+ `Failed to clear cache for namespace: ${overnight_parking_requests_namespace_collection}`,
42083
+ err
42084
+ );
42085
+ });
42086
+ return data;
42087
+ } catch (error) {
42088
+ throw error;
42089
+ }
42090
+ }
42091
+ async function updateExpiredRequests(site, session) {
42092
+ try {
42093
+ const _site = (0, import_node_server_utils203.toObjectId)(site);
42094
+ const value = {
42095
+ status: "expired" /* EXPIRED */
42096
+ };
42097
+ const now = (/* @__PURE__ */ new Date()).toISOString();
42098
+ const data = await collection.updateMany(
42099
+ {
42100
+ site: _site,
42101
+ createdAt: { $lte: now },
42102
+ status: "pending" /* PENDING */
42103
+ },
42104
+ { $set: value },
42105
+ { session }
42106
+ );
42107
+ delNamespace().then(() => {
42108
+ import_node_server_utils203.logger.info(
42109
+ `Cache cleared for namespace: ${overnight_parking_requests_namespace_collection}`
42110
+ );
42111
+ }).catch((err) => {
42112
+ import_node_server_utils203.logger.error(
42113
+ `Failed to clear cache for namespace: ${overnight_parking_requests_namespace_collection}`,
42114
+ err
42115
+ );
42116
+ });
42117
+ return data;
42118
+ } catch (error) {
42119
+ throw error;
42120
+ }
42121
+ }
42122
+ return {
42123
+ add,
42124
+ getAll,
42125
+ getOvernightParkingRequestById,
42126
+ updateOvernightParkingRequestById,
42127
+ deleteOvernightParkingRequestById,
42128
+ updateExpiredRequests,
42129
+ createIndexes
42130
+ };
42131
+ }
42132
+
42133
+ // src/services/overnight-parking-request.service.ts
42134
+ var import_node_server_utils204 = require("@7365admin1/node-server-utils");
42135
+ function getDayKey(date = /* @__PURE__ */ new Date()) {
42136
+ const days = [
42137
+ "sunday" /* SUNDAY */,
42138
+ "monday" /* MONDAY */,
42139
+ "tuesday" /* TUESDAY */,
42140
+ "wednesday" /* WEDNESDAY */,
42141
+ "thursday" /* THURSDAY */,
42142
+ "friday" /* FRIDAY */,
42143
+ "saturday" /* SATURDAY */
42144
+ ];
42145
+ return days[date.getDay()];
42146
+ }
42147
+ function timeToMinutes(time) {
42148
+ const [hours, minutes] = time.split(":").map(Number);
42149
+ return hours * 60 + minutes;
42150
+ }
42151
+ function isCurrentTimeWithinRange(startTime, endTime, now = /* @__PURE__ */ new Date()) {
42152
+ const currentMinutes = now.getHours() * 60 + now.getMinutes();
42153
+ const startMinutes = timeToMinutes(startTime);
42154
+ const endMinutes = timeToMinutes(endTime);
42155
+ if (startMinutes <= endMinutes) {
42156
+ return currentMinutes >= startMinutes && currentMinutes <= endMinutes;
42157
+ }
42158
+ return currentMinutes >= startMinutes || currentMinutes <= endMinutes;
42159
+ }
42160
+ function shouldAutoApprove(overnightParking, now = /* @__PURE__ */ new Date()) {
42161
+ if (!overnightParking)
42162
+ return false;
42163
+ if (overnightParking.autoApproveOvernightParking !== true) {
42164
+ return false;
42165
+ }
42166
+ const dayKey = getDayKey(now);
42167
+ const daySchedule = overnightParking[dayKey];
42168
+ if (!daySchedule)
42169
+ return false;
42170
+ if (daySchedule.isEnabled !== true)
42171
+ return false;
42172
+ if (!daySchedule.startTime || !daySchedule.endTime)
42173
+ return false;
42174
+ return isCurrentTimeWithinRange(
42175
+ daySchedule.startTime,
42176
+ daySchedule.endTime,
42177
+ now
42178
+ );
42179
+ }
42180
+ function useOvernightParkingRequestService() {
42181
+ const {
42182
+ add: _add,
42183
+ updateOvernightParkingRequestById: _updateOvernightParkingRequestById,
42184
+ deleteOvernightParkingRequestById: _deleteOvernightParkingRequestById,
42185
+ updateExpiredRequests: _updateExpiredRequests
42186
+ } = useOvernightParkingRequestRepo();
42187
+ const { getAllSitesUnpaginated: _getAllSitesUnpaginated } = useSiteRepo();
42188
+ const { getSiteOvernightParking: _getSiteOvernightParking } = useOvernightParkingRepo();
42189
+ async function add(value) {
42190
+ const session = import_node_server_utils204.useAtlas.getClient()?.startSession();
42191
+ try {
42192
+ session?.startTransaction();
42193
+ const overnightParking = await _getSiteOvernightParking(value.site);
42194
+ const payload = {
42195
+ ...value,
42196
+ status: shouldAutoApprove(overnightParking) ? "approved" /* APPROVED */ : "pending" /* PENDING */
42197
+ };
42198
+ const result = await _add(payload, session);
42199
+ await session?.commitTransaction();
42200
+ return result;
42201
+ } catch (error) {
42202
+ await session?.abortTransaction();
42203
+ throw error;
42204
+ } finally {
42205
+ session?.endSession();
42206
+ }
42207
+ }
42208
+ async function updateOvernightParkingRequestById(id, value) {
42209
+ const session = import_node_server_utils204.useAtlas.getClient()?.startSession();
42210
+ try {
42211
+ session?.startTransaction();
42212
+ const result = await _updateOvernightParkingRequestById(id, value);
42213
+ await session?.commitTransaction();
42214
+ return result;
42215
+ } catch (error) {
42216
+ await session?.abortTransaction();
42217
+ throw error;
42218
+ } finally {
42219
+ session?.endSession();
42220
+ }
42221
+ }
42222
+ async function deleteOvernightParkingRequestById(id) {
42223
+ const session = import_node_server_utils204.useAtlas.getClient()?.startSession();
42224
+ try {
42225
+ session?.startTransaction();
42226
+ const result = await _deleteOvernightParkingRequestById(id, session);
42227
+ await session?.commitTransaction();
42228
+ return result;
42229
+ } catch (error) {
42230
+ await session?.abortTransaction();
42231
+ throw error;
42232
+ } finally {
42233
+ session?.endSession();
42234
+ }
42235
+ }
42236
+ async function processExpiredRequests() {
42237
+ const sites = await _getAllSitesUnpaginated();
42238
+ for (const site of sites) {
42239
+ const session = import_node_server_utils204.useAtlas.getClient()?.startSession();
42240
+ try {
42241
+ session?.startTransaction();
42242
+ await _updateExpiredRequests(site._id, session);
42243
+ await session?.commitTransaction();
42244
+ } catch (error) {
42245
+ await session?.abortTransaction();
42246
+ import_node_server_utils204.logger.error(`Failed processing site ${site._id}`, error);
42247
+ } finally {
42248
+ session?.endSession();
42249
+ }
42250
+ }
42251
+ }
42252
+ return {
42253
+ add,
42254
+ updateOvernightParkingRequestById,
42255
+ deleteOvernightParkingRequestById,
42256
+ processExpiredRequests
42257
+ };
42258
+ }
42259
+
42260
+ // src/controllers/overnight-parking-request.controller.ts
42261
+ var import_joi119 = __toESM(require("joi"));
42262
+ var import_node_server_utils205 = require("@7365admin1/node-server-utils");
42263
+ function useOvernightParkingRequestController() {
42264
+ const {
42265
+ add: _add,
42266
+ updateOvernightParkingRequestById: _updateOvernightParkingRequestById,
42267
+ deleteOvernightParkingRequestById: _deleteOvernightParkingRequestById
42268
+ } = useOvernightParkingRequestService();
42269
+ const {
42270
+ getAll: _getAll,
42271
+ getOvernightParkingRequestById: _getOvernightParkingRequestById
42272
+ } = useOvernightParkingRequestRepo();
42273
+ async function add(req, res, next) {
42274
+ try {
42275
+ const { error, value } = schemaOvernightParkingRequest.validate(
42276
+ req.body,
42277
+ {
42278
+ abortEarly: false
42279
+ }
42280
+ );
42281
+ if (error) {
42282
+ const messages = error.details.map((d) => d.message).join(", ");
42283
+ import_node_server_utils205.logger.log({ level: "error", message: messages });
42284
+ next(new import_node_server_utils205.BadRequestError(messages));
42285
+ return;
42286
+ }
42287
+ const data = await _add(value);
42288
+ res.status(201).json(data);
42289
+ return;
42290
+ } catch (error) {
42291
+ import_node_server_utils205.logger.log({ level: "error", message: error.message });
42292
+ next(error);
42293
+ return;
42294
+ }
42295
+ }
42296
+ async function getAll(req, res, next) {
42297
+ try {
42298
+ const validation = import_joi119.default.object({
42299
+ page: import_joi119.default.number().integer().min(1).optional().default(1),
42300
+ limit: import_joi119.default.number().integer().min(1).max(100).optional().default(10),
42301
+ sort: import_joi119.default.string().valid(...Object.values(OvernightParkingRequestSort)).optional().allow(null, ""),
42302
+ status: import_joi119.default.string().valid(...Object.values(OvernightParkingRequestStatus)).optional().allow(null, ""),
42303
+ site: import_joi119.default.string().hex().length(24).optional().allow(null, ""),
42304
+ order: import_joi119.default.string().valid(...Object.values(SortOrder)).default("asc" /* ASC */)
42305
+ });
42306
+ const { error, value } = validation.validate(req.query, {
42307
+ abortEarly: false
42308
+ });
42309
+ if (error) {
42310
+ const messages = error.details.map((d) => d.message).join(", ");
42311
+ import_node_server_utils205.logger.log({ level: "error", message: messages });
42312
+ next(new import_node_server_utils205.BadRequestError(messages));
42313
+ return;
42314
+ }
42315
+ const { site, page, limit, status, sort, order } = value;
42316
+ const sortObj = {
42317
+ [sort ? sort : "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
42318
+ };
42319
+ const data = await _getAll({
42320
+ site,
42321
+ page,
42322
+ limit,
42323
+ sort: sortObj,
42324
+ status
42325
+ });
42326
+ res.status(200).json(data);
42327
+ return;
42328
+ } catch (error) {
42329
+ import_node_server_utils205.logger.log({ level: "error", message: error.message });
42330
+ next(error);
42331
+ return;
42332
+ }
42333
+ }
42334
+ async function getOvernightParkingRequestById(req, res, next) {
42335
+ try {
42336
+ const validation = import_joi119.default.object({
42337
+ _id: import_joi119.default.string().hex().length(24).required()
42338
+ });
42339
+ const { error, value } = validation.validate(
42340
+ { _id: req.params.id },
42341
+ {
42342
+ abortEarly: false
42343
+ }
42344
+ );
42345
+ if (error) {
42346
+ const messages = error.details.map((d) => d.message).join(", ");
42347
+ import_node_server_utils205.logger.log({ level: "error", message: messages });
42348
+ next(new import_node_server_utils205.BadRequestError(messages));
42349
+ return;
42350
+ }
42351
+ const { _id } = value;
42352
+ const data = await _getOvernightParkingRequestById(_id);
42353
+ res.status(200).json(data);
42354
+ return;
42355
+ } catch (error) {
42356
+ import_node_server_utils205.logger.log({ level: "error", message: error.message });
42357
+ next(error);
42358
+ return;
42359
+ }
42360
+ }
42361
+ async function updateOvernightParkingRequestById(req, res, next) {
42362
+ try {
42363
+ const { error, value } = schemaUpdateOvernightParkingRequest.validate(
42364
+ { _id: req.params.id, ...req.body },
42365
+ {
42366
+ abortEarly: false
42367
+ }
42368
+ );
42369
+ if (error) {
42370
+ const messages = error.details.map((d) => d.message).join(", ");
42371
+ import_node_server_utils205.logger.log({ level: "error", message: messages });
42372
+ next(new import_node_server_utils205.BadRequestError(messages));
42373
+ return;
42374
+ }
42375
+ const { _id, ...rest } = value;
42376
+ await _updateOvernightParkingRequestById(_id, rest);
42377
+ res.status(200).json({ message: "Successfully updated overnight parking request" });
42378
+ return;
42379
+ } catch (error) {
42380
+ import_node_server_utils205.logger.log({ level: "error", message: error.message });
42381
+ next(error);
42382
+ return;
42383
+ }
42384
+ }
42385
+ async function deleteOvernightParkingRequestById(req, res, next) {
42386
+ try {
42387
+ const schema2 = import_joi119.default.object({
42388
+ _id: import_joi119.default.string().hex().length(24).required()
42389
+ });
42390
+ const { error, value } = schema2.validate(
42391
+ { _id: req.params.id },
42392
+ {
42393
+ abortEarly: false
42394
+ }
42395
+ );
42396
+ if (error) {
42397
+ const messages = error.details.map((d) => d.message).join(", ");
42398
+ import_node_server_utils205.logger.log({ level: "error", message: messages });
42399
+ next(new import_node_server_utils205.BadRequestError(messages));
42400
+ return;
42401
+ }
42402
+ const { _id } = value;
42403
+ await _deleteOvernightParkingRequestById(_id);
42404
+ res.status(200).json({ message: "Successfully deleted overnight parking request" });
42405
+ return;
42406
+ } catch (error) {
42407
+ import_node_server_utils205.logger.log({ level: "error", message: error.message });
42408
+ next(error);
42409
+ return;
42410
+ }
42411
+ }
42412
+ return {
42413
+ add,
42414
+ getAll,
42415
+ getOvernightParkingRequestById,
42416
+ updateOvernightParkingRequestById,
42417
+ deleteOvernightParkingRequestById
42418
+ };
42419
+ }
42420
+
42421
+ // src/services/hrmlabs-attendance.service.ts
42422
+ var import_node_server_utils206 = require("@7365admin1/node-server-utils");
42423
+ var {
42424
+ hrmLabsAuthentication: hrmLabsAuthentication3,
42425
+ fetchAttendanceData: fetchAttendanceData2,
42426
+ filterByShiftTime: filterByShiftTime2,
42427
+ paginate: paginate55,
42428
+ designationCount: designationCount2,
42429
+ totalCountPerShift: totalCountPerShift2,
42430
+ filterByStatus: filterByStatus2,
42431
+ totalCountPerStatus: totalCountPerStatus2,
42432
+ chartCountData: chartCountData2
42433
+ } = hrmlabs_attendance_util_default;
42434
+ function useHrmLabsAttendanceSrvc() {
42435
+ const { getManpowerSettingsBySiteId: _getManpowerSettingsBySiteId } = useManpowerMonitoringRepo();
42436
+ const { getManpowerDesignationsBySiteId: _getManpowerDesignationsBySiteId } = useManpowerDesignationRepo();
42437
+ async function getAttendanceData(payload) {
42438
+ const {
42439
+ startDate,
42440
+ endDate,
42441
+ siteName,
42442
+ siteId,
42443
+ shiftName,
42444
+ search,
42445
+ page = 1,
42446
+ limit = 10,
42447
+ status = "all",
42448
+ serviceProviderId
42449
+ } = payload;
42450
+ const username = process.env.HRMLABS_USERNAME;
42451
+ const domain = process.env.HRMLABS_DOMAIN;
42452
+ const password = process.env.HRMLABS_PASSWORD;
42453
+ const authUrl = process.env.HRMLABS_AUTH_URL;
42454
+ const attendanceUrl = process.env.HRMLABS_ATTENDANCE_URL;
42455
+ const timeZone = "Asia/Singapore";
42456
+ const dateFormat = "DD-MM-YYYY HH:mm:ss";
42457
+ if (!startDate) {
42458
+ return { success: false, message: "Start Date should not be empty" };
42459
+ }
42460
+ try {
42461
+ const config2 = await _getManpowerSettingsBySiteId(
42462
+ siteId,
42463
+ serviceProviderId
42464
+ );
42465
+ if (!config2) {
42466
+ return {
42467
+ success: false,
42468
+ message: "Manpower monitoring settings not found for the provided site ID."
42469
+ };
42470
+ }
42471
+ const shiftType = config2.shiftType === "2-shifts" ? "2-shifts" : "3-shifts";
42472
+ const shiftData = config2.shifts[shiftType].find(
42473
+ (s) => s.name === shiftName
42474
+ );
42475
+ if (!shiftData) {
42476
+ return {
42477
+ success: false,
42478
+ message: "Shift not found in configuration."
42479
+ };
42480
+ }
42481
+ const token = await hrmLabsAuthentication3({
42482
+ authUrl,
42483
+ username,
42484
+ password,
42485
+ domain
42486
+ });
42487
+ const attendanceData = await fetchAttendanceData2({
42488
+ attendanceUrl,
42489
+ token,
42490
+ startDate,
42491
+ endDate,
42492
+ siteName,
42493
+ search
42494
+ });
42495
+ if (!attendanceData?.success) {
42496
+ return {
42497
+ success: false,
42498
+ message: "Failed to fetch attendance data from HRMLabs.",
42499
+ items: [],
42500
+ pages: 0,
42501
+ pageRange: "0-0 of 0",
42502
+ count: {}
42503
+ };
42504
+ }
42505
+ let filteredAttendance;
42506
+ if (status === "all") {
42507
+ filteredAttendance = filterByShiftTime2(
42508
+ attendanceData.data,
42509
+ shiftData,
42510
+ timeZone,
42511
+ dateFormat
42512
+ );
42513
+ } else {
42514
+ const filteredByShift = filterByShiftTime2(
42515
+ attendanceData.data,
42516
+ shiftData,
42517
+ timeZone,
42518
+ dateFormat
42519
+ );
42520
+ filteredAttendance = filterByStatus2(
42521
+ filteredByShift,
42522
+ shiftData,
42523
+ timeZone,
42524
+ dateFormat,
42525
+ status
42526
+ );
42527
+ }
42528
+ const paginatedItems = paginate55(filteredAttendance, page, limit);
42529
+ return {
42530
+ items: paginatedItems.items,
42531
+ pages: paginatedItems.pages,
42532
+ pageRange: paginatedItems.pageRange
42533
+ };
42534
+ } catch (error) {
42535
+ import_node_server_utils206.logger.error(error.message || error);
42536
+ console.log("Error fetching attendance data:", error);
42537
+ throw new Error(error?.message || "Internal Server Error!");
42538
+ }
42539
+ }
42540
+ async function getAttendanceDataCount(payload) {
42541
+ const { startDate, endDate, siteName, siteId, search, serviceProviderId } = payload;
42542
+ const username = process.env.HRMLABS_USERNAME;
42543
+ const domain = process.env.HRMLABS_DOMAIN;
42544
+ const password = process.env.HRMLABS_PASSWORD;
42545
+ const authUrl = process.env.HRMLABS_AUTH_URL;
42546
+ const attendanceUrl = process.env.HRMLABS_ATTENDANCE_URL;
42547
+ const timeZone = "Asia/Singapore";
42548
+ const dateFormat = "DD-MM-YYYY HH:mm:ss";
42549
+ let totalCount;
42550
+ if (!startDate) {
42551
+ return { success: false, message: "Start Date should not be empty" };
42552
+ }
42553
+ try {
42554
+ const config2 = await _getManpowerSettingsBySiteId(
42555
+ siteId,
42556
+ serviceProviderId
42557
+ );
42558
+ if (!config2) {
42559
+ return {
42560
+ success: false,
42561
+ message: "Manpower monitoring settings not found for the provided site ID."
42562
+ };
42563
+ }
42564
+ const shiftType = config2.shiftType;
42565
+ const shiftData = config2.shifts[shiftType];
42566
+ if (!shiftData) {
42567
+ return {
42568
+ success: false,
42569
+ message: "Shift not found in configuration."
42570
+ };
42571
+ }
42572
+ const designationConfig = await _getManpowerDesignationsBySiteId(
42573
+ siteId,
42574
+ serviceProviderId
42575
+ );
42576
+ if (!designationConfig) {
42577
+ return {
42578
+ success: false,
42579
+ message: "Manpower monitoring designations not found for the provided site ID."
42580
+ };
42581
+ }
42582
+ const totalShifts = designationConfig.designations.reduce(
42583
+ (acc, item) => {
42584
+ acc.morningShift += item.shifts.morningShift;
42585
+ acc.afternoonShift += item.shifts.afternoonShift;
42586
+ acc.nightShift += item.shifts.nightShift;
42587
+ return acc;
42588
+ },
42589
+ {
42590
+ morningShift: 0,
42591
+ afternoonShift: 0,
42592
+ nightShift: 0
42593
+ }
42594
+ );
42595
+ const token = await hrmLabsAuthentication3({
42596
+ authUrl,
42597
+ username,
42598
+ password,
42599
+ domain
42600
+ });
42601
+ const attendanceData = await fetchAttendanceData2({
42602
+ attendanceUrl,
42603
+ token,
42604
+ startDate,
42605
+ endDate,
42606
+ siteName,
42607
+ search
42608
+ });
42609
+ if (!attendanceData?.success) {
42610
+ return {
42611
+ totalCount: {
42612
+ dayShift: {
42613
+ actual: 0,
42614
+ expected: totalShifts.morningShift
42615
+ },
42616
+ afternoonShift: {
42617
+ actual: 0,
42618
+ expected: totalShifts.afternoonShift
42619
+ },
42620
+ nightShift: {
42621
+ actual: 0,
42622
+ expected: totalShifts.nightShift
42623
+ }
42624
+ }
42625
+ };
42626
+ }
42627
+ const result = totalCountPerShift2(
42628
+ attendanceData.data,
42629
+ shiftData,
42630
+ timeZone,
42631
+ dateFormat
42632
+ );
42633
+ totalCount = {
42634
+ dayShift: {
42635
+ actual: result[0],
42636
+ expected: totalShifts.morningShift
42637
+ },
42638
+ afternoonShift: {
42639
+ actual: shiftType == "2-shifts" ? 0 : result[1],
42640
+ expected: totalShifts.afternoonShift
42641
+ },
42642
+ nightShift: {
42643
+ actual: shiftType == "2-shifts" ? result[1] : result[2],
42644
+ expected: totalShifts.nightShift
42645
+ }
42646
+ };
42647
+ return { totalCount };
42648
+ } catch (error) {
42649
+ import_node_server_utils206.logger.error(error.message || error);
42650
+ console.log("Error fetching attendance data count:", error);
42651
+ throw new Error(error?.message || "Internal Server Error!");
42652
+ }
42653
+ }
42654
+ async function getAllAttendance(payload) {
42655
+ const { startDate, endDate, siteName, siteId, search, serviceProviderId } = payload;
42656
+ let { shiftName } = payload;
42657
+ const username = process.env.HRMLABS_USERNAME;
42658
+ const domain = process.env.HRMLABS_DOMAIN;
42659
+ const password = process.env.HRMLABS_PASSWORD;
42660
+ const authUrl = process.env.HRMLABS_AUTH_URL;
42661
+ const attendanceUrl = process.env.HRMLABS_ATTENDANCE_URL;
42662
+ const timeZone = "Asia/Singapore";
42663
+ const dateFormat = "DD-MM-YYYY HH:mm:ss";
42664
+ if (!startDate) {
42665
+ return { success: false, message: "Start Date should not be empty" };
42666
+ }
42667
+ try {
42668
+ const config2 = await _getManpowerSettingsBySiteId(
42669
+ siteId,
42670
+ serviceProviderId
42671
+ );
42672
+ if (!config2) {
42673
+ return {
42674
+ success: false,
42675
+ message: "Manpower monitoring settings not found for the provided site ID."
42676
+ };
42677
+ }
42678
+ const designationConfig = await _getManpowerDesignationsBySiteId(
42679
+ siteId,
42680
+ serviceProviderId
42681
+ );
42682
+ if (!designationConfig) {
42683
+ return {
42684
+ success: false,
42685
+ message: "Manpower monitoring designations not found for the provided site ID."
42686
+ };
42687
+ }
42688
+ let shiftData = [];
42689
+ const shiftType = config2.shiftType === "2-shifts" ? "2-shifts" : "3-shifts";
42690
+ if (shiftName == "all") {
42691
+ shiftData = config2.shifts[shiftType];
42692
+ } else {
42693
+ shiftName = shiftName.split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
42694
+ const filteredShiftData = config2.shifts[shiftType].find(
42695
+ (s) => s.name === shiftName
42696
+ );
42697
+ shiftData.push(filteredShiftData);
42698
+ }
42699
+ if (!shiftData) {
42700
+ return {
42701
+ success: false,
42702
+ message: "Shift not found in configuration."
42703
+ };
42704
+ }
42705
+ const totalShifts = designationConfig.designations.reduce(
42706
+ (acc, item) => {
42707
+ acc.morningShift += item.shifts.morningShift;
42708
+ acc.afternoonShift += item.shifts.afternoonShift;
42709
+ acc.nightShift += item.shifts.nightShift;
42710
+ return acc;
42711
+ },
42712
+ {
42713
+ morningShift: 0,
42714
+ afternoonShift: 0,
42715
+ nightShift: 0
42716
+ }
42717
+ );
42718
+ const token = await hrmLabsAuthentication3({
42719
+ authUrl,
42720
+ username,
42721
+ password,
42722
+ domain
42723
+ });
42724
+ const attendanceData = await fetchAttendanceData2({
42725
+ attendanceUrl,
42726
+ token,
42727
+ startDate,
42728
+ endDate,
42729
+ siteName,
42730
+ search
42731
+ });
42732
+ if (!attendanceData?.success) {
42733
+ const jobTitleCount2 = designationCount2(
42734
+ attendanceData.data,
42735
+ designationConfig,
42736
+ shiftName
42737
+ );
42738
+ const totalCount2 = {
42739
+ dayShift: {
42740
+ actual: 0,
42741
+ expected: totalShifts.morningShift
42742
+ },
42743
+ afternoonShift: {
42744
+ actual: 0,
42745
+ expected: totalShifts.afternoonShift
42746
+ },
42747
+ nightShift: {
42748
+ actual: 0,
42749
+ expected: totalShifts.nightShift
42750
+ }
42751
+ };
42752
+ const countPerStatus2 = await totalCountPerStatus2(
42753
+ attendanceData.data,
42754
+ shiftName,
42755
+ shiftData,
42756
+ timeZone,
42757
+ dateFormat,
42758
+ totalShifts
42759
+ );
42760
+ return {
42761
+ success: false,
42762
+ message: "Failed to fetch attendance data from HRMLabs.",
42763
+ items: [],
42764
+ count: {},
42765
+ countPerJobTitle: jobTitleCount2,
42766
+ totalCount: totalCount2,
42767
+ countPerStatus: countPerStatus2
42768
+ };
42769
+ }
42770
+ let filteredAttendance;
42771
+ if (shiftName === "all") {
42772
+ filteredAttendance = attendanceData.data;
42773
+ } else {
42774
+ filteredAttendance = filterByShiftTime2(
42775
+ attendanceData.data,
42776
+ shiftData[0],
42777
+ timeZone,
42778
+ dateFormat
42779
+ );
42780
+ }
42781
+ const jobTitleCount = designationCount2(
42782
+ filteredAttendance,
42783
+ designationConfig,
42784
+ shiftName
42785
+ );
42786
+ const result = totalCountPerShift2(
42787
+ attendanceData.data,
42788
+ shiftData,
42789
+ timeZone,
42790
+ dateFormat
42791
+ );
42792
+ const totalCount = {
42793
+ dayShift: {
42794
+ actual: result[0],
42795
+ expected: totalShifts.morningShift
42796
+ },
42797
+ afternoonShift: {
42798
+ actual: shiftType == "2-shifts" ? 0 : result[1],
42799
+ expected: totalShifts.afternoonShift
42800
+ },
42801
+ nightShift: {
42802
+ actual: shiftType == "2-shifts" ? result[1] : result[2],
42803
+ expected: totalShifts.nightShift
42804
+ }
42805
+ };
42806
+ const countPerStatus = await totalCountPerStatus2(
42807
+ filteredAttendance,
42808
+ shiftName,
42809
+ shiftData,
42810
+ timeZone,
42811
+ dateFormat,
42812
+ totalShifts
42813
+ );
42814
+ return {
42815
+ items: filteredAttendance,
42816
+ countPerJobTitle: jobTitleCount,
42817
+ totalCount,
42818
+ countPerStatus
42819
+ };
42820
+ } catch (error) {
42821
+ import_node_server_utils206.logger.error(error.message || error);
42822
+ console.log("Error fetching attendance data:", error);
42823
+ throw new Error(error?.message || "Internal Server Error!");
42824
+ }
42825
+ }
42826
+ async function getChartAttendanceData(payload) {
42827
+ const {
42828
+ startDate,
42829
+ endDate,
42830
+ siteName,
42831
+ siteId,
42832
+ search,
42833
+ serviceProviderId,
42834
+ status
42835
+ } = payload;
42836
+ let { shiftName } = payload;
42837
+ const username = process.env.HRMLABS_USERNAME;
42838
+ const domain = process.env.HRMLABS_DOMAIN;
42839
+ const password = process.env.HRMLABS_PASSWORD;
42840
+ const authUrl = process.env.HRMLABS_AUTH_URL;
42841
+ const attendanceUrl = process.env.HRMLABS_ATTENDANCE_URL;
42842
+ const timeZone = "Asia/Singapore";
42843
+ const dateFormat = "DD-MM-YYYY HH:mm:ss";
42844
+ if (!startDate) {
42845
+ return { success: false, message: "Start Date should not be empty" };
42846
+ }
42847
+ try {
42848
+ const config2 = await _getManpowerSettingsBySiteId(
42849
+ siteId,
42850
+ serviceProviderId
42851
+ );
42852
+ if (!config2) {
42853
+ return {
42854
+ success: false,
42855
+ message: "Manpower monitoring settings not found for the provided site ID."
42856
+ };
42857
+ }
42858
+ const designationConfig = await _getManpowerDesignationsBySiteId(
42859
+ siteId,
42860
+ serviceProviderId
42861
+ );
42862
+ if (!designationConfig) {
42863
+ return {
42864
+ success: false,
42865
+ message: "Manpower monitoring designations not found for the provided site ID."
42866
+ };
42867
+ }
42868
+ const shiftType = config2.shiftType === "2-shifts" ? "2-shifts" : "3-shifts";
42869
+ const shiftData = config2.shifts[shiftType];
42870
+ if (!shiftData) {
42871
+ return {
42872
+ success: false,
42873
+ message: "Shift not found in configuration."
42874
+ };
42875
+ }
42876
+ const token = await hrmLabsAuthentication3({
42877
+ authUrl,
42878
+ username,
42879
+ password,
42880
+ domain
42881
+ });
42882
+ const attendanceData = await fetchAttendanceData2({
42883
+ attendanceUrl,
42884
+ token,
42885
+ startDate,
42886
+ endDate,
42887
+ siteName,
42888
+ search
42889
+ });
42890
+ if (!attendanceData?.success) {
42891
+ return {
42892
+ success: false,
42893
+ message: "Failed to fetch attendance data from HRMLabs.",
42894
+ items: [],
42895
+ pages: 0,
42896
+ pageRange: "0-0 of 0",
42897
+ count: {}
42898
+ };
42899
+ }
42900
+ const filteredAttendance = attendanceData.data;
42901
+ const totalShifts = designationConfig.designations.reduce(
42902
+ (acc, item) => {
42903
+ acc.morningShift += item.shifts.morningShift;
42904
+ acc.afternoonShift += item.shifts.afternoonShift;
42905
+ acc.nightShift += item.shifts.nightShift;
42906
+ return acc;
42907
+ },
42908
+ {
42909
+ morningShift: 0,
42910
+ afternoonShift: 0,
42911
+ nightShift: 0
42912
+ }
42913
+ );
42914
+ const chartCount = await chartCountData2(
42915
+ filteredAttendance,
42916
+ shiftData,
42917
+ timeZone,
42918
+ dateFormat,
42919
+ totalShifts,
42920
+ startDate,
42921
+ endDate,
42922
+ status
42923
+ );
42924
+ return {
42925
+ chartCount
42926
+ };
42927
+ } catch (error) {
42928
+ import_node_server_utils206.logger.error(error.message || error);
42929
+ console.log("Error fetching attendance data:", error);
42930
+ throw new Error(error?.message || "Internal Server Error!");
42931
+ }
42932
+ }
42933
+ return {
42934
+ getAttendanceData,
42935
+ getAttendanceDataCount,
42936
+ getAllAttendance,
42937
+ getChartAttendanceData
42938
+ };
42939
+ }
42940
+
42941
+ // src/controllers/hrmlabs-attendance.controller.ts
42942
+ var import_node_server_utils207 = require("@7365admin1/node-server-utils");
42943
+ var import_joi120 = __toESM(require("joi"));
42944
+ function useHrmLabsAttendanceCtrl() {
42945
+ const hrmLabsAttendanceSrvc = useHrmLabsAttendanceSrvc();
42946
+ async function getAttendanceData(req, res, next) {
42947
+ try {
42948
+ const {
42949
+ startDate,
42950
+ endDate,
42951
+ siteName,
42952
+ siteId,
42953
+ shiftName,
42954
+ page,
42955
+ limit,
42956
+ search,
42957
+ status,
42958
+ serviceProviderId
42959
+ } = req.body;
42960
+ const schema2 = import_joi120.default.object({
42961
+ startDate: import_joi120.default.string().optional().allow("", null),
42962
+ endDate: import_joi120.default.string().optional().allow("", null),
42963
+ siteName: import_joi120.default.string().optional().allow("", null),
42964
+ siteId: import_joi120.default.string().required(),
42965
+ shiftName: import_joi120.default.string().optional().allow("", null),
42966
+ page: import_joi120.default.number().optional().allow("", null),
42967
+ limit: import_joi120.default.number().optional().allow("", null),
42968
+ search: import_joi120.default.string().optional().allow("", null),
42969
+ status: import_joi120.default.string().optional().allow("", null),
42970
+ serviceProviderId: import_joi120.default.string().required()
42971
+ });
42972
+ const { error } = schema2.validate({
42973
+ startDate,
42974
+ endDate,
42975
+ siteName,
42976
+ siteId,
42977
+ shiftName,
42978
+ page,
42979
+ limit,
42980
+ search,
42981
+ status,
42982
+ serviceProviderId
42983
+ });
42984
+ if (error) {
42985
+ next(new import_node_server_utils207.BadRequestError(error.message));
42986
+ return;
42987
+ }
42988
+ const result = await hrmLabsAttendanceSrvc.getAttendanceData(req.body);
42989
+ return res.json(result);
42990
+ } catch (error) {
42991
+ import_node_server_utils207.logger.log({ level: "error", message: error.message });
42992
+ next(error);
42993
+ return;
42994
+ }
42995
+ }
42996
+ async function getAttendanceDataCount(req, res, next) {
42997
+ try {
42998
+ const { startDate, endDate, siteName, siteId, serviceProviderId } = req.body;
42999
+ const schema2 = import_joi120.default.object({
43000
+ startDate: import_joi120.default.string().optional().allow("", null),
43001
+ endDate: import_joi120.default.string().optional().allow("", null),
43002
+ siteName: import_joi120.default.string().optional().allow("", null),
43003
+ siteId: import_joi120.default.string().required(),
43004
+ serviceProviderId: import_joi120.default.string().required()
43005
+ });
43006
+ const { error } = schema2.validate({
43007
+ startDate,
43008
+ endDate,
43009
+ siteName,
43010
+ siteId,
43011
+ serviceProviderId
43012
+ });
43013
+ if (error) {
43014
+ next(new import_node_server_utils207.BadRequestError(error.message));
43015
+ return;
43016
+ }
43017
+ const result = await hrmLabsAttendanceSrvc.getAttendanceDataCount(
43018
+ req.body
43019
+ );
43020
+ return res.json(result);
43021
+ } catch (error) {
43022
+ import_node_server_utils207.logger.log({ level: "error", message: error.message });
43023
+ next(error);
43024
+ return;
43025
+ }
43026
+ }
43027
+ async function getAllAttendance(req, res, next) {
43028
+ try {
43029
+ const {
43030
+ startDate,
43031
+ endDate,
43032
+ siteName,
43033
+ siteId,
43034
+ shiftName,
43035
+ search,
43036
+ serviceProviderId
43037
+ } = req.body;
43038
+ const schema2 = import_joi120.default.object({
43039
+ startDate: import_joi120.default.string().optional().allow("", null),
43040
+ endDate: import_joi120.default.string().optional().allow("", null),
43041
+ siteName: import_joi120.default.string().optional().allow("", null),
43042
+ siteId: import_joi120.default.string().required(),
43043
+ shiftName: import_joi120.default.string().optional().allow("", null),
43044
+ search: import_joi120.default.string().optional().allow("", null),
43045
+ serviceProviderId: import_joi120.default.string().required()
43046
+ });
43047
+ const { error } = schema2.validate({
43048
+ startDate,
43049
+ endDate,
43050
+ siteName,
43051
+ siteId,
43052
+ shiftName,
43053
+ search,
43054
+ serviceProviderId
43055
+ });
43056
+ if (error) {
43057
+ next(new import_node_server_utils207.BadRequestError(error.message));
43058
+ return;
43059
+ }
43060
+ const result = await hrmLabsAttendanceSrvc.getAllAttendance(req.body);
43061
+ return res.json(result);
43062
+ } catch (error) {
43063
+ import_node_server_utils207.logger.log({ level: "error", message: error.message });
43064
+ next(error);
43065
+ return;
43066
+ }
43067
+ }
43068
+ async function getChartAttendanceData(req, res, next) {
43069
+ try {
43070
+ const {
43071
+ startDate,
43072
+ endDate,
43073
+ siteName,
43074
+ siteId,
43075
+ search = "",
43076
+ serviceProviderId,
43077
+ status
43078
+ } = req.body;
43079
+ const schema2 = import_joi120.default.object({
43080
+ startDate: import_joi120.default.string().optional().allow("", null),
43081
+ endDate: import_joi120.default.string().optional().allow("", null),
43082
+ siteName: import_joi120.default.string().optional().allow("", null),
43083
+ siteId: import_joi120.default.string().required(),
43084
+ search: import_joi120.default.string().optional().allow("", null),
43085
+ serviceProviderId: import_joi120.default.string().required(),
43086
+ status: import_joi120.default.string().optional().allow("", null)
43087
+ });
43088
+ const { error } = schema2.validate({
43089
+ startDate,
43090
+ endDate,
43091
+ siteName,
43092
+ siteId,
43093
+ search,
43094
+ serviceProviderId,
43095
+ status
43096
+ });
43097
+ if (error) {
43098
+ next(new import_node_server_utils207.BadRequestError(error.message));
43099
+ return;
43100
+ }
43101
+ const result = await hrmLabsAttendanceSrvc.getChartAttendanceData(
43102
+ req.body
43103
+ );
43104
+ return res.json(result);
43105
+ } catch (error) {
43106
+ import_node_server_utils207.logger.log({ level: "error", message: error.message });
43107
+ next(error);
43108
+ return;
43109
+ }
43110
+ }
43111
+ return {
43112
+ getAttendanceData,
43113
+ getAttendanceDataCount,
43114
+ getAllAttendance,
43115
+ getChartAttendanceData
43116
+ };
43117
+ }
43118
+
43119
+ // src/controllers/manpower-remarks.controller.ts
43120
+ var import_node_server_utils208 = require("@7365admin1/node-server-utils");
43121
+ var import_joi121 = __toESM(require("joi"));
43122
+ function useManpowerRemarkCtrl() {
43123
+ const {
43124
+ createManpowerRemarks: _createManpowerRemarks,
43125
+ getManpowerRemarksAllSite: _getManpowerRemarksAllSite,
43126
+ updateRemarksStatus: _updateRemarksStatus,
43127
+ getManpowerRemarksBySiteId: _getManpowerRemarksBySiteId,
43128
+ updateManpowerRemarks: _updateManpowerRemarks
43129
+ } = useManpowerRemarksRepo();
43130
+ async function createManpowerRemark(req, res, next) {
43131
+ try {
43132
+ const payload = { ...req.body };
43133
+ const { error } = manpowerRemarksSchema.validate(payload);
43134
+ if (error) {
43135
+ next(new import_node_server_utils208.BadRequestError(error.message));
43136
+ return;
43137
+ }
43138
+ const result = await _createManpowerRemarks(payload);
43139
+ return res.json(result);
43140
+ } catch (error) {
43141
+ import_node_server_utils208.logger.log({ level: "error", message: error.message });
43142
+ next(error);
43143
+ return;
43144
+ }
43145
+ }
43146
+ async function getManpowerRemarksAllSite(req, res, next) {
43147
+ try {
43148
+ const { page, limit, serviceProviderId, search, status, date } = req.query;
43149
+ const schema2 = import_joi121.default.object({
43150
+ page: import_joi121.default.number().optional().allow("", null),
43151
+ limit: import_joi121.default.number().optional().allow("", null),
43152
+ serviceProviderId: import_joi121.default.string().hex().optional().allow("", null),
43153
+ search: import_joi121.default.string().optional().allow("", null),
43154
+ status: import_joi121.default.string().required(),
43155
+ date: import_joi121.default.string().required()
43156
+ });
43157
+ const { error } = schema2.validate({
43158
+ page,
43159
+ limit,
43160
+ serviceProviderId,
43161
+ search,
43162
+ status,
43163
+ date
43164
+ });
43165
+ if (error) {
43166
+ next(new import_node_server_utils208.BadRequestError(error.message));
43167
+ return;
43168
+ }
43169
+ const result = await _getManpowerRemarksAllSite({
43170
+ page: Number(page),
43171
+ limit: Number(limit),
43172
+ serviceProviderId: serviceProviderId?.toString() || "",
43173
+ search: search?.toString() || "",
43174
+ status: status?.toString() || "",
43175
+ date: date?.toString() || ""
43176
+ });
43177
+ return res.json(result);
43178
+ } catch (error) {
43179
+ import_node_server_utils208.logger.log({ level: "error", message: error.message });
43180
+ next(error);
43181
+ return;
43182
+ }
43183
+ }
43184
+ async function getManpowerRemarksBySiteId(req, res, next) {
43185
+ try {
43186
+ const { id, serviceProviderId } = req.params;
43187
+ const date = req.query.date;
43188
+ const schema2 = import_joi121.default.object({
43189
+ id: import_joi121.default.string().hex().required(),
43190
+ date: import_joi121.default.string().required(),
43191
+ serviceProviderId: import_joi121.default.string().hex().required()
43192
+ });
43193
+ const { error } = schema2.validate({
43194
+ id,
43195
+ date,
43196
+ serviceProviderId
43197
+ });
43198
+ if (error) {
43199
+ next(new import_node_server_utils208.BadRequestError(error.message));
43200
+ return;
43201
+ }
43202
+ const result = await _getManpowerRemarksBySiteId(
43203
+ id,
43204
+ date,
43205
+ serviceProviderId
43206
+ );
43207
+ return res.json(result);
43208
+ } catch (error) {
43209
+ import_node_server_utils208.logger.log({ level: "error", message: error.message });
43210
+ next(error);
43211
+ return;
43212
+ }
43213
+ }
43214
+ async function updateManpowerMonitoringSettings(req, res, next) {
43215
+ try {
43216
+ const validation = import_joi121.default.object({
43217
+ _id: import_joi121.default.string().hex().required(),
43218
+ remarks: import_joi121.default.array().items(remarksSchema).required(),
43219
+ createdBy: import_joi121.default.string().hex().optional().allow("", null),
43220
+ createdByName: import_joi121.default.string().optional().allow("", null)
43221
+ });
43222
+ const _id = req.params.id;
43223
+ const payload = { ...req.body };
43224
+ const { error } = validation.validate({ _id, ...payload });
43225
+ if (error) {
43226
+ next(new import_node_server_utils208.BadRequestError(error.message));
43227
+ return;
43228
+ }
43229
+ const result = await _updateManpowerRemarks(_id, payload);
43230
+ return res.json(result);
43231
+ } catch (error) {
43232
+ import_node_server_utils208.logger.log({ level: "error", message: error.message });
43233
+ next(error);
43234
+ return;
43235
+ }
43236
+ }
43237
+ async function updateRemarksStatus(req, res, next) {
43238
+ try {
43239
+ const validation = import_joi121.default.object({
43240
+ _id: import_joi121.default.string().hex().required(),
43241
+ status: import_joi121.default.string().required()
43242
+ });
43243
+ const _id = req.params.id;
43244
+ const payload = { ...req.body };
43245
+ const { error } = validation.validate({ _id, ...payload });
43246
+ if (error) {
43247
+ next(new import_node_server_utils208.BadRequestError(error.message));
43248
+ return;
43249
+ }
43250
+ const result = await _updateRemarksStatus(_id, payload);
43251
+ return res.json(result);
43252
+ } catch (error) {
43253
+ import_node_server_utils208.logger.log({ level: "error", message: error.message });
43254
+ next(error);
43255
+ return;
43256
+ }
43257
+ }
43258
+ return {
43259
+ createManpowerRemark,
43260
+ getManpowerRemarksAllSite,
43261
+ getManpowerRemarksBySiteId,
43262
+ updateManpowerMonitoringSettings,
43263
+ updateRemarksStatus
43264
+ };
43265
+ }
43266
+
43267
+ // src/models/manpower-sites.model.ts
43268
+ var import_joi122 = __toESM(require("joi"));
43269
+ var import_mongodb114 = require("mongodb");
43270
+ var manpowerSitesSchema = import_joi122.default.object({
43271
+ id: import_joi122.default.string().hex().required(),
43272
+ text: import_joi122.default.string().hex().optional().allow("", null),
43273
+ contractID: import_joi122.default.string().optional().allow("", null),
43274
+ contractName: import_joi122.default.string().optional().allow("", null),
43275
+ type: import_joi122.default.string().optional().allow("", null),
43276
+ status: import_joi122.default.number().optional().allow("", null)
43277
+ });
43278
+ var MManpowerSites = class {
43279
+ constructor(data) {
43280
+ this._id = new import_mongodb114.ObjectId();
43281
+ this.id = data.id || "";
43282
+ this.text = data.text || "";
43283
+ this.contractID = data.contractID || "";
43284
+ this.contractName = data.contractName || "";
43285
+ this.type = data.type || "";
43286
+ this.status = data.status || "";
43287
+ }
43288
+ };
43289
+
43290
+ // src/repositories/manpower-sites.repo.ts
43291
+ var import_node_server_utils209 = require("@7365admin1/node-server-utils");
43292
+ function useManpowerSitesRepo() {
43293
+ const db = import_node_server_utils209.useAtlas.getDb();
43294
+ if (!db) {
43295
+ throw new Error("Unable to connect to server.");
43296
+ }
43297
+ const namespace_collection = "manpower-sites";
43298
+ const collection = db.collection(namespace_collection);
43299
+ async function createManpowerSites(value) {
43300
+ try {
43301
+ value = new MManpowerSites(value);
43302
+ const result = await collection.insertOne(value);
43303
+ return result;
43304
+ } catch (error) {
43305
+ throw new Error(error.message || error || "Server Internal Error");
43306
+ }
43307
+ }
43308
+ async function getAllManpowerSites({
43309
+ page = 1,
43310
+ limit = 10,
43311
+ search = ""
43312
+ }) {
43313
+ try {
43314
+ page = page ? page - 1 : 0;
43315
+ limit = limit || 10;
43316
+ const searchQuery = {};
43317
+ if (search) {
43318
+ searchQuery.siteName = { $regex: search, $options: "i" };
43319
+ }
43320
+ const result = await collection.aggregate([
43321
+ { $match: searchQuery },
43322
+ {
43323
+ $facet: {
43324
+ totalCount: [{ $count: "count" }],
43325
+ items: [
43326
+ { $sort: { _id: 1 } },
43327
+ {
43328
+ $project: {
43329
+ _id: 0
43330
+ }
43331
+ },
43332
+ { $skip: page * limit },
43333
+ { $limit: limit }
43334
+ ]
43335
+ }
43336
+ }
43337
+ ]).toArray();
43338
+ const items = result[0].items;
43339
+ return items;
43340
+ } catch (error) {
43341
+ throw new Error(error.message || "Server Internal Error");
43342
+ }
43343
+ }
43344
+ async function deleteManpowerSites(siteId) {
43345
+ try {
43346
+ const result = await collection.deleteOne({
43347
+ id: siteId.toString()
43348
+ });
43349
+ return result;
43350
+ } catch (error) {
43351
+ throw new Error(error.message || "Server Internal Error");
43352
+ }
43353
+ }
43354
+ return {
43355
+ createManpowerSites,
43356
+ getAllManpowerSites,
43357
+ deleteManpowerSites
43358
+ };
43359
+ }
43360
+
43361
+ // src/services/manpower-sites.service.ts
43362
+ var import_node_server_utils210 = require("@7365admin1/node-server-utils");
43363
+ function useManpowerSitesSrvc() {
43364
+ const manpowerSitesRepo = useManpowerSitesRepo();
43365
+ const manpowerMonitoringRepo = useManpowerMonitoringRepo();
43366
+ async function createManpowerSites(payload) {
43367
+ const session = import_node_server_utils210.useAtlas.getClient()?.startSession();
43368
+ if (!session) {
43369
+ throw new import_node_server_utils210.BadRequestError("Database session not available.");
43370
+ }
43371
+ await session.startTransaction();
43372
+ try {
43373
+ const manpowerSites = await manpowerMonitoringRepo.getAllSites(payload);
43374
+ for (const site of manpowerSites) {
43375
+ await manpowerSitesRepo.createManpowerSites(site);
43376
+ }
43377
+ await session.commitTransaction();
43378
+ return "Created Succesfully";
43379
+ } catch (error) {
43380
+ await session.abortTransaction();
43381
+ import_node_server_utils210.logger.error(error.message || error);
43382
+ console.error("Error creating monitoring settings:", error);
43383
+ throw new Error(error?.message || "Internal Server Error!");
43384
+ } finally {
43385
+ session.endSession();
43386
+ }
43387
+ }
43388
+ async function checkManpowerSites() {
43389
+ try {
43390
+ const serviceProviderId = "69bb9dbff572cf9d260d7ce3";
43391
+ const hrmLabsSites = await manpowerMonitoringRepo.getAllSites(
43392
+ serviceProviderId
43393
+ );
43394
+ const manpowerSites = await manpowerSitesRepo.getAllManpowerSites({
43395
+ page: 1,
43396
+ limit: 1e3,
43397
+ search: ""
43398
+ });
43399
+ const added = hrmLabsSites.filter(
43400
+ (hrmSite) => !manpowerSites.some((mpSite) => mpSite.id === hrmSite.id)
43401
+ );
43402
+ const deleted = manpowerSites.filter(
43403
+ (mpSite) => !hrmLabsSites.some((hrmSite) => hrmSite.id === mpSite.id)
43404
+ );
43405
+ if (added.length > 0) {
43406
+ await Promise.all(
43407
+ added.map((site) => manpowerSitesRepo.createManpowerSites(site))
43408
+ );
43409
+ }
43410
+ if (deleted.length > 0) {
43411
+ await Promise.all(
43412
+ deleted.map(
43413
+ (site) => manpowerSitesRepo.deleteManpowerSites(site.id)
43414
+ )
43415
+ );
43416
+ }
43417
+ return "Manpower Sites Updated Successfully";
43418
+ } catch (error) {
43419
+ import_node_server_utils210.logger.error(error.message || error);
43420
+ console.error("Error checking manpower sites:", error);
43421
+ throw new Error(error?.message || "Internal Server Error!");
43422
+ }
43423
+ }
43424
+ return {
43425
+ createManpowerSites,
43426
+ checkManpowerSites
43427
+ };
43428
+ }
43429
+
43430
+ // src/controllers/manpower-sites.controller.ts
43431
+ var import_node_server_utils211 = require("@7365admin1/node-server-utils");
43432
+ var import_joi123 = __toESM(require("joi"));
43433
+ function useManpowerSitesCtrl() {
43434
+ const { createManpowerSites: _createManpowerSites } = useManpowerSitesSrvc();
43435
+ const { getAllManpowerSites: _getAllManpowerSites } = useManpowerSitesRepo();
43436
+ async function createManpowerSites(req, res, next) {
43437
+ try {
43438
+ const payload = req.query.serviceProviderId;
43439
+ const schema2 = import_joi123.default.object({
43440
+ serviceProviderId: import_joi123.default.string().hex().required()
43441
+ });
43442
+ const { error } = schema2.validate({
43443
+ serviceProviderId: payload
43444
+ });
43445
+ if (error) {
43446
+ next(new import_node_server_utils211.BadRequestError(error.message));
43447
+ return;
43448
+ }
43449
+ const result = await _createManpowerSites(payload);
43450
+ return res.json(result);
43451
+ } catch (error) {
43452
+ import_node_server_utils211.logger.log({ level: "error", message: error.message });
43453
+ next(error);
43454
+ return;
43455
+ }
43456
+ }
43457
+ async function getAllManpowerSites(req, res, next) {
43458
+ try {
43459
+ const { page, search, limit } = req.query;
43460
+ const schema2 = import_joi123.default.object({
43461
+ page: import_joi123.default.number().optional().allow("", null),
43462
+ limit: import_joi123.default.number().optional().allow("", null),
43463
+ search: import_joi123.default.string().optional().allow("", null)
43464
+ });
43465
+ const { error } = schema2.validate({ page, search, limit });
43466
+ if (error) {
43467
+ next(new import_node_server_utils211.BadRequestError(error.message));
43468
+ return;
43469
+ }
43470
+ const result = await _getAllManpowerSites({
43471
+ page: Number(page),
43472
+ limit: Number(limit),
43473
+ search
43474
+ });
43475
+ return res.json(result);
43476
+ } catch (error) {
43477
+ import_node_server_utils211.logger.log({ level: "error", message: error.message });
43478
+ next(error);
43479
+ return;
43480
+ }
43481
+ }
43482
+ return {
43483
+ createManpowerSites,
43484
+ getAllManpowerSites
43485
+ };
43486
+ }
43487
+
43488
+ // src/utils/cron.util.ts
43489
+ var import_node_server_utils212 = require("@7365admin1/node-server-utils");
43490
+ var import_mongodb115 = require("mongodb");
43491
+ var import_moment_timezone4 = __toESM(require("moment-timezone"));
43492
+ var createManpowerRemarksDaily = async () => {
43493
+ const db = import_node_server_utils212.useAtlas.getDb();
43494
+ if (!db) {
43495
+ throw new Error("Unable to connect to server.");
43496
+ }
43497
+ const namespace_collection = "manpower-settings";
43498
+ const settings = db.collection(namespace_collection);
43499
+ const remarks = db.collection("manpower-remarks");
43500
+ const serviceProviders = db.collection("site.service-providers");
43501
+ const items = [];
43502
+ const yesterday = (0, import_moment_timezone4.default)().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
43503
+ try {
43504
+ const nowSGT = (0, import_moment_timezone4.default)().tz("Asia/Singapore");
43505
+ const servideProvider = await serviceProviders.findOne({
43506
+ name: { $regex: process.env.HRMLABS_DOMAIN, $options: "i" }
43507
+ });
43508
+ if (!servideProvider) {
43509
+ throw new Error("Servide Provider not found.");
43510
+ }
43511
+ const remark = await remarks.find({
43512
+ createdAtSGT: yesterday,
43513
+ serviceProviderId: servideProvider._id,
43514
+ status: "active"
43515
+ }).toArray();
43516
+ for (const site of remark) {
43517
+ const existingRemark = await settings.findOne({
43518
+ siteId: site.siteId,
43519
+ enabled: true
43520
+ });
43521
+ if (existingRemark) {
43522
+ const setting = await settings.findOne({
43523
+ siteId: site.siteId,
43524
+ enabled: true
43525
+ });
43526
+ const shiftType = setting?.shiftType;
43527
+ const morningCheckInTime = setting?.shifts?.[shiftType][0]?.checkIn;
43528
+ const afternoonCheckInTime = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][1]?.checkIn : null;
43529
+ const nightCheckInTime = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][2]?.checkIn : setting?.shifts?.[shiftType][1]?.checkIn;
43530
+ const morningAlertFrequencyMins = setting?.shifts?.[shiftType][0]?.alertFrequencyMins;
43531
+ const afternoonAlertFrequencyMins = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][1]?.alertFrequencyMins : null;
43532
+ const nightAlertFrequencyMins = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][2]?.alertFrequencyMins : setting?.shifts?.[shiftType][1]?.alertFrequencyMins;
43533
+ const morningAlertTime = import_moment_timezone4.default.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
43534
+ const afternoonAlertTime = afternoonCheckInTime ? import_moment_timezone4.default.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
43535
+ const nightAlertTime = import_moment_timezone4.default.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
43536
+ const remark2 = {
43537
+ siteId: site.siteId,
43538
+ siteName: site.siteName,
43539
+ serviceProviderId: servideProvider._id,
43540
+ remarks: [
43541
+ {
43542
+ name: "Morning Shift",
43543
+ remark: {
43544
+ isAcknowledged: true,
43545
+ status: "",
43546
+ acknowledgementRemarks: "",
43547
+ acknowledgedAt: ""
43548
+ }
43549
+ },
43550
+ {
43551
+ name: "Afternoon Shift",
43552
+ remark: {
43553
+ isAcknowledged: true,
43554
+ status: "",
43555
+ acknowledgementRemarks: "",
43556
+ acknowledgedAt: ""
43557
+ }
43558
+ },
43559
+ {
43560
+ name: "Night Shift",
43561
+ remark: {
43562
+ isAcknowledged: true,
43563
+ status: "",
43564
+ acknowledgementRemarks: "",
43565
+ acknowledgedAt: ""
43566
+ }
43567
+ }
43568
+ ],
43569
+ createdBy: "",
43570
+ createdByName: "",
43571
+ morningAlertTime,
43572
+ afternoonAlertTime,
43573
+ nightAlertTime,
43574
+ createdAt: /* @__PURE__ */ new Date(),
43575
+ createdAtSGT: nowSGT.format("DD-MM-YYYY"),
43576
+ updatedAt: "",
43577
+ status: "active"
43578
+ };
43579
+ items.push(remark2);
43580
+ }
43581
+ }
43582
+ if (items.length > 0) {
43583
+ await remarks.insertMany(items);
43584
+ }
43585
+ console.log("Daily manpower remarks created successfully.");
43586
+ } catch (error) {
43587
+ console.error("Error creating daily manpower remarks:", error);
43588
+ }
43589
+ };
43590
+ var updateRemarksisAcknowledged = async () => {
43591
+ const { getAttendanceDataCount: _getAttendanceDataCount } = useHrmLabsAttendanceSrvc();
43592
+ const nowSGT = (0, import_moment_timezone4.default)().tz("Asia/Singapore").format("DD-MM-YYYY");
43593
+ const db = import_node_server_utils212.useAtlas.getDb();
43594
+ if (!db) {
43595
+ throw new Error("Unable to connect to server.");
43596
+ }
43597
+ const namespace_collection = "manpower-remarks";
43598
+ const remarks = db.collection(namespace_collection);
43599
+ const timeNow = (0, import_moment_timezone4.default)().tz("Asia/Singapore").format("HH:mm");
43600
+ const settings = db.collection("manpower-settings");
43601
+ try {
43602
+ const matchingDocs = await remarks.find({
43603
+ createdAtSGT: nowSGT,
43604
+ $or: [
43605
+ {
43606
+ morningAlertTime: timeNow,
43607
+ "remarks.0.remark.isAcknowledged": true
43608
+ },
43609
+ {
43610
+ afternoonAlertTime: timeNow,
43611
+ "remarks.1.remark.isAcknowledged": true
43612
+ },
43613
+ { nightAlertTime: timeNow, "remarks.2.remark.isAcknowledged": true }
43614
+ ]
43615
+ }).project({ _id: 1 }).toArray();
43616
+ if (matchingDocs.length === 0) {
43617
+ return;
43618
+ }
43619
+ const updatedIds = matchingDocs.map((doc) => doc._id);
43620
+ await remarks.updateMany(
43621
+ {
43622
+ _id: { $in: updatedIds },
43623
+ morningAlertTime: timeNow,
43624
+ createdAtSGT: nowSGT,
43625
+ "remarks.0.remark.isAcknowledged": true
43626
+ },
43627
+ { $set: { "remarks.0.remark.isAcknowledged": false } }
43628
+ );
43629
+ await remarks.updateMany(
43630
+ {
43631
+ _id: { $in: updatedIds },
43632
+ afternoonAlertTime: timeNow,
43633
+ createdAtSGT: nowSGT,
43634
+ "remarks.1.remark.isAcknowledged": true
43635
+ },
43636
+ { $set: { "remarks.1.remark.isAcknowledged": false } }
43637
+ );
43638
+ await remarks.updateMany(
43639
+ {
43640
+ _id: { $in: updatedIds },
43641
+ nightAlertTime: timeNow,
43642
+ createdAtSGT: nowSGT,
43643
+ "remarks.2.remark.isAcknowledged": true
43644
+ },
43645
+ { $set: { "remarks.2.remark.isAcknowledged": false } }
43646
+ );
43647
+ for (const id of updatedIds) {
43648
+ const doc = await remarks.findOne({ _id: id });
43649
+ const setting = await settings.findOne(
43650
+ { siteId: new import_mongodb115.ObjectId(doc?.siteId) },
43651
+ { projection: { emails: 1 } }
43652
+ );
43653
+ const payload = {
43654
+ startDate: doc?.createdAtSGT,
43655
+ endDate: doc?.createdAtSGT,
43656
+ siteName: doc?.siteName,
43657
+ siteId: doc?.siteId.toString(),
43658
+ serviceProviderId: doc?.serviceProviderId.toString()
43659
+ };
43660
+ const result = await _getAttendanceDataCount(payload);
43661
+ const shifts = [
43662
+ { key: "dayShift", alertTime: doc?.morningAlertTime },
43663
+ { key: "afternoonShift", alertTime: doc?.afternoonAlertTime },
43664
+ { key: "nightShift", alertTime: doc?.nightAlertTime }
43665
+ ];
43666
+ let shiftType;
43667
+ let actual = 0;
43668
+ let expected = 0;
43669
+ for (const shift of shifts) {
43670
+ if (shift.alertTime && isWithinHour(shift.alertTime, timeNow)) {
43671
+ shiftType = shift.key;
43672
+ actual = result?.totalCount?.[shift.key]?.actual || 0;
43673
+ expected = result?.totalCount?.[shift.key]?.expected || 0;
43674
+ break;
43675
+ }
43676
+ }
43677
+ let newStatus = "Normal";
43678
+ if (actual > expected)
43679
+ newStatus = "Over";
43680
+ else if (actual < expected)
43681
+ newStatus = "Under";
43682
+ sendEmailWithAttachmentsTo({
43683
+ email: setting?.emails,
43684
+ subject: "Manpower Alert",
43685
+ message: "",
43686
+ siteName: doc?.siteName || "",
43687
+ handlebar: "alert-email",
43688
+ date: nowSGT,
43689
+ actual,
43690
+ expected,
43691
+ status: newStatus
43692
+ });
43693
+ }
43694
+ } catch (error) {
43695
+ console.error("Error updating remarks:", error);
43696
+ }
43697
+ };
43698
+ var updateRemarksStatusEod = async () => {
43699
+ const { getAttendanceDataCount: _getAttendanceDataCount } = useHrmLabsAttendanceSrvc();
43700
+ const db = import_node_server_utils212.useAtlas.getDb();
43701
+ if (!db) {
43702
+ throw new Error("Unable to connect to server.");
43703
+ }
43704
+ const remarks = db.collection("manpower-remarks");
43705
+ const settings = db.collection("manpower-settings");
43706
+ const nowSGT = (0, import_moment_timezone4.default)().tz("Asia/Singapore").format("DD-MM-YYYY");
43707
+ const yesterdaySGT = (0, import_moment_timezone4.default)().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
43708
+ const timeNow = (0, import_moment_timezone4.default)().tz("Asia/Singapore").format("HH:mm");
43709
+ const docs = await remarks.find({
43710
+ $or: [
43711
+ // Morning & Afternoon from today
43712
+ {
43713
+ createdAtSGT: nowSGT,
43714
+ $or: [
43715
+ {
43716
+ "remarks.0.remark.status": "",
43717
+ "remarks.0.remark.isAcknowledged": false
43718
+ },
43719
+ {
43720
+ "remarks.1.remark.status": "",
43721
+ "remarks.1.remark.isAcknowledged": false
43722
+ }
43723
+ ]
43724
+ },
43725
+ // Night shift from yesterday
43726
+ {
43727
+ createdAtSGT: yesterdaySGT,
43728
+ "remarks.2.remark.status": "",
43729
+ "remarks.2.remark.isAcknowledged": false
43730
+ }
43731
+ ]
43732
+ }).toArray();
43733
+ for (const doc of docs) {
43734
+ let shiftsToCheck = [];
43735
+ const endShiftTime = await settings.findOne(
43736
+ { siteId: new import_mongodb115.ObjectId(doc.siteId) },
43737
+ { projection: { shifts: 1, shiftType: 1 } }
43738
+ );
43739
+ if (doc.createdAtSGT === nowSGT) {
43740
+ const shiftType = endShiftTime?.shiftType || "2-shifts";
43741
+ if (timeNow >= endShiftTime?.shifts[shiftType][0]?.checkOut)
43742
+ shiftsToCheck.push({ index: 0, key: "dayShift" });
43743
+ if (shiftType == "3-shifts" && timeNow >= endShiftTime?.shifts[shiftType][1]?.checkOut)
43744
+ shiftsToCheck.push({ index: 1, key: "afternoonShift" });
43745
+ }
43746
+ if (doc.createdAtSGT === yesterdaySGT) {
43747
+ const index = endShiftTime?.shiftType === "2-shifts" ? 1 : 2;
43748
+ if (timeNow >= endShiftTime?.shifts[endShiftTime?.shiftType][index]?.checkOut)
43749
+ shiftsToCheck.push({ index: 2, key: "nightShift" });
43750
+ }
43751
+ if (shiftsToCheck.length === 0)
43752
+ continue;
43753
+ const payload = {
43754
+ startDate: doc.createdAtSGT,
43755
+ endDate: doc.createdAtSGT,
43756
+ siteName: doc.siteName,
43757
+ siteId: doc.siteId.toString(),
43758
+ serviceProviderId: doc.serviceProviderId.toString()
43759
+ };
43760
+ const result = await _getAttendanceDataCount(payload);
43761
+ if (!result?.totalCount) {
43762
+ continue;
43763
+ }
43764
+ for (const shift of shiftsToCheck) {
43765
+ const actual = result?.totalCount[shift?.key]?.actual || 0;
43766
+ const expected = result?.totalCount[shift?.key]?.expected || 0;
43767
+ if (doc.remarks[shift.index].remark.status === "") {
43768
+ let newStatus = "Normal";
43769
+ if (actual > expected)
43770
+ newStatus = "Over";
43771
+ else if (actual < expected)
43772
+ newStatus = "Under";
43773
+ await remarks.updateOne(
43774
+ { _id: doc._id },
43775
+ {
43776
+ $set: {
43777
+ [`remarks.${shift.index}.remark.status`]: newStatus,
43778
+ [`remarks.${shift.index}.remark.isAcknowledged`]: true,
43779
+ [`remarks.${shift.index}.remark.acknowledgedAt`]: (/* @__PURE__ */ new Date()).toISOString()
43780
+ }
43781
+ }
43782
+ );
43783
+ }
43784
+ }
43785
+ }
43786
+ };
43787
+ function sendEmailWithAttachmentsTo({
43788
+ email = "",
43789
+ subject = "",
43790
+ message = "",
43791
+ siteName = "",
43792
+ handlebar = "",
43793
+ date = "",
43794
+ actual = 0,
43795
+ expected = 0,
43796
+ status = ""
43797
+ }) {
43798
+ const MailerConfig = {
43799
+ host: MAILER_TRANSPORT_HOST,
43800
+ port: MAILER_TRANSPORT_PORT,
43801
+ secure: MAILER_TRANSPORT_SECURE,
43802
+ email: MAILER_EMAIL,
43803
+ password: MAILER_PASSWORD
43804
+ };
43805
+ const mailer = new import_node_server_utils212.useMailer(MailerConfig);
43806
+ const dir = __dirname;
43807
+ const type = "alert-email";
43808
+ const filePath = (0, import_node_server_utils212.getDirectory)(dir, `./public/handlebars/${type}`);
43809
+ const emailContent = (0, import_node_server_utils212.compileHandlebar)({
43810
+ context: {
43811
+ siteName,
43812
+ date,
43813
+ actual,
43814
+ expected,
43815
+ status
43816
+ },
43817
+ filePath
43818
+ });
43819
+ mailer.sendMail({
43820
+ to: email,
43821
+ subject,
43822
+ html: emailContent,
43823
+ sender: "iService365"
43824
+ }).catch((error) => {
43825
+ import_node_server_utils212.logger.log({
43826
+ level: "error",
43827
+ message: `Error sending user ${type} email: ${error}`
43828
+ });
43829
+ });
43830
+ return { message };
43831
+ }
43832
+ var isWithinHour = (alertTime, timeNow) => {
43833
+ const [ah, am] = alertTime.split(":").map(Number);
43834
+ const [nh, nm] = timeNow.split(":").map(Number);
43835
+ const alertMinutes = ah * 60 + am;
43836
+ const nowMinutes = nh * 60 + nm;
43837
+ return nowMinutes >= alertMinutes && nowMinutes <= alertMinutes + 60;
43838
+ };
43839
+
43840
+ // src/events/manpower.event.ts
43841
+ var import_node_server_utils213 = require("@7365admin1/node-server-utils");
43842
+ var import_mongodb116 = require("mongodb");
43843
+ var import_moment_timezone5 = __toESM(require("moment-timezone"));
43844
+ async function manpowerEvents(io) {
43845
+ console.log("Manpower events initialized");
43846
+ let intervalId = null;
43847
+ let activeConnections = 0;
43848
+ const { getAttendanceDataCount: _getAttendanceDataCount } = useHrmLabsAttendanceSrvc();
43849
+ const updateRemarksStatus = async (date) => {
43850
+ const db = import_node_server_utils213.useAtlas.getDb();
43851
+ if (!db) {
43852
+ throw new Error("Unable to connect to server.");
43853
+ }
43854
+ const remarks = db.collection("manpower-remarks");
43855
+ const settings = db.collection("manpower-settings");
43856
+ const selectedDateMoment = import_moment_timezone5.default.tz(date, "DD-MM-YYYY", "Asia/Singapore");
43857
+ const selectedDateSGT = selectedDateMoment.format("DD-MM-YYYY");
43858
+ const currentSGT = (0, import_moment_timezone5.default)().tz("Asia/Singapore");
43859
+ const docs = await remarks.find({
43860
+ createdAtSGT: selectedDateSGT,
43861
+ $or: [
43862
+ { "remarks.0.remark.status": "" },
43863
+ { "remarks.1.remark.status": "" },
43864
+ { "remarks.2.remark.status": "" }
43865
+ ]
43866
+ }).toArray();
43867
+ for (const doc of docs) {
43868
+ const siteSettings = await settings.findOne(
43869
+ { siteId: new import_mongodb116.ObjectId(doc.siteId), enabled: true },
43870
+ { projection: { shifts: 1, shiftType: 1 } }
43871
+ );
43872
+ const shiftType = siteSettings?.shiftType || "2-shifts";
43873
+ const shiftsToCheck = [];
43874
+ shiftsToCheck.push({ index: 0, key: "dayShift" });
43875
+ if (shiftType === "3-shifts") {
43876
+ shiftsToCheck.push({ index: 1, key: "afternoonShift" });
43877
+ }
43878
+ if (currentSGT.isSame(selectedDateMoment, "day")) {
43879
+ if (currentSGT.isSameOrAfter(
43880
+ import_moment_timezone5.default.tz("19:55", "HH:mm", "Asia/Singapore")
43881
+ )) {
43882
+ shiftsToCheck.push({ index: 2, key: "nightShift" });
43883
+ }
43884
+ } else if (currentSGT.isAfter(selectedDateMoment, "day")) {
43885
+ shiftsToCheck.push({ index: 2, key: "nightShift" });
43886
+ }
43887
+ if (shiftsToCheck.length === 0)
43888
+ continue;
43889
+ const payload = {
43890
+ startDate: doc.createdAtSGT,
43891
+ endDate: doc.createdAtSGT,
43892
+ siteName: doc.siteName,
43893
+ siteId: doc.siteId.toString(),
43894
+ serviceProviderId: doc.serviceProviderId.toString()
43895
+ };
43896
+ const result = await _getAttendanceDataCount(payload);
43897
+ for (const shift of shiftsToCheck) {
43898
+ const actual = result?.totalCount?.[shift.key]?.actual || 0;
43899
+ const expected = result?.totalCount?.[shift.key]?.expected || 0;
43900
+ let newStatus = "Normal";
43901
+ if (actual > expected)
43902
+ newStatus = "Over";
43903
+ else if (actual < expected)
43904
+ newStatus = "Under";
43905
+ const namespace = `/manpower`;
43906
+ io.of(namespace).emit("manpower-status-update", {
43907
+ siteId: doc.siteId,
43908
+ siteName: doc.siteName,
43909
+ shift: shift.key,
43910
+ status: newStatus,
43911
+ actual,
43912
+ expected,
43913
+ selectedDateSGT
43914
+ });
43915
+ }
43916
+ }
43917
+ };
43918
+ const startInterval = (date) => {
43919
+ if (!intervalId) {
43920
+ intervalId = setInterval(
43921
+ () => updateRemarksStatus(date?.toString() || ""),
43922
+ 15 * 1e3
43923
+ );
43924
+ console.log(" Interval started.");
43925
+ }
43926
+ };
43927
+ const stopInterval = () => {
43928
+ if (intervalId) {
43929
+ clearInterval(intervalId);
43930
+ intervalId = null;
43931
+ console.log(" Interval stopped.");
43932
+ }
43933
+ };
43934
+ io.of("/manpower").on("connection", (socket) => {
43935
+ activeConnections += 1;
43936
+ const date = socket.handshake.query.date;
43937
+ if (activeConnections === 1) {
43938
+ startInterval(date?.toString() || "");
43939
+ }
43940
+ updateRemarksStatus(date?.toString() || "");
43941
+ socket.on("disconnect", () => {
43942
+ activeConnections -= 1;
43943
+ console.log(`Client disconnected: ${socket.id}`);
43944
+ console.log(`Total active connections: ${activeConnections}`);
43945
+ if (activeConnections === 0) {
43946
+ stopInterval();
43947
+ }
43948
+ });
43949
+ });
43950
+ }
41055
43951
  // Annotate the CommonJS export names for ESM import in node:
41056
43952
  0 && (module.exports = {
41057
43953
  ANPRMode,
@@ -41062,6 +43958,7 @@ function useOvernightParkingController() {
41062
43958
  BulletinStatus,
41063
43959
  CameraType,
41064
43960
  DEVICE_STATUS,
43961
+ DayOfWeek,
41065
43962
  EAccessCardTypes,
41066
43963
  EAccessCardUserTypes,
41067
43964
  FacilitySort,
@@ -41091,6 +43988,8 @@ function useOvernightParkingController() {
41091
43988
  MIncidentReport,
41092
43989
  MManpowerDesignations,
41093
43990
  MManpowerMonitoring,
43991
+ MManpowerRemarks,
43992
+ MManpowerSites,
41094
43993
  MMember,
41095
43994
  MNfcPatrolLog,
41096
43995
  MNfcPatrolRoute,
@@ -41103,6 +44002,7 @@ function useOvernightParkingController() {
41103
44002
  MOnlineForm,
41104
44003
  MOrg,
41105
44004
  MOvernightParkingApprovalHours,
44005
+ MOvernightParkingRequest,
41106
44006
  MPatrolLog,
41107
44007
  MPatrolQuestion,
41108
44008
  MPatrolRoute,
@@ -41127,6 +44027,8 @@ function useOvernightParkingController() {
41127
44027
  MVisitorTransaction,
41128
44028
  MWorkOrder,
41129
44029
  OrgNature,
44030
+ OvernightParkingRequestSort,
44031
+ OvernightParkingRequestStatus,
41130
44032
  PERSON_TYPES,
41131
44033
  PMDashboardCollection,
41132
44034
  Period,
@@ -41135,6 +44037,7 @@ function useOvernightParkingController() {
41135
44037
  SiteStatus,
41136
44038
  SortFields,
41137
44039
  SortOrder,
44040
+ SubscriptionType,
41138
44041
  UseAccessManagementRepo,
41139
44042
  VehicleCategory,
41140
44043
  VehicleOrder,
@@ -41143,6 +44046,7 @@ function useOvernightParkingController() {
41143
44046
  VehicleType,
41144
44047
  VisitorSort,
41145
44048
  VisitorStatus,
44049
+ addressSchema,
41146
44050
  allowedFieldsSite,
41147
44051
  allowedNatures,
41148
44052
  attendanceSchema,
@@ -41151,6 +44055,7 @@ function useOvernightParkingController() {
41151
44055
  bulletin_boards_namespace_collection,
41152
44056
  calculatePercentage,
41153
44057
  chatSchema,
44058
+ createManpowerRemarksDaily,
41154
44059
  customerSchema,
41155
44060
  designationsSchema,
41156
44061
  events_namespace_collection,
@@ -41165,13 +44070,19 @@ function useOvernightParkingController() {
41165
44070
  landscapeDashboardCollection,
41166
44071
  mAndEDashboardCollection,
41167
44072
  manpowerDesignationsSchema,
44073
+ manpowerEvents,
41168
44074
  manpowerMonitoringSchema,
44075
+ manpowerRemarksSchema,
44076
+ manpowerSitesSchema,
41169
44077
  nfcPatrolSettingsSchema,
41170
44078
  nfcPatrolSettingsSchemaUpdate,
44079
+ occurrence_book_namespace_collection,
41171
44080
  orgSchema,
44081
+ overnight_parking_requests_namespace_collection,
41172
44082
  pestDashboardCollection,
41173
44083
  poolDashboardCollection,
41174
44084
  promoCodeSchema,
44085
+ remarksSchema,
41175
44086
  robotSchema,
41176
44087
  schema,
41177
44088
  schemaBilling,
@@ -41198,6 +44109,7 @@ function useOvernightParkingController() {
41198
44109
  schemaOccurrenceSubject,
41199
44110
  schemaOnlineForm,
41200
44111
  schemaOvernightParkingApprovalHours,
44112
+ schemaOvernightParkingRequest,
41201
44113
  schemaPatrolLog,
41202
44114
  schemaPatrolQuestion,
41203
44115
  schemaPatrolRoute,
@@ -41222,6 +44134,7 @@ function useOvernightParkingController() {
41222
44134
  schemaUpdateOccurrenceSubject,
41223
44135
  schemaUpdateOnlineForm,
41224
44136
  schemaUpdateOptions,
44137
+ schemaUpdateOvernightParkingRequest,
41225
44138
  schemaUpdatePatrolLog,
41226
44139
  schemaUpdatePatrolQuestion,
41227
44140
  schemaUpdatePatrolRoute,
@@ -41244,6 +44157,8 @@ function useOvernightParkingController() {
41244
44157
  siteSchema,
41245
44158
  site_people_namespace_collection,
41246
44159
  tokenSchema,
44160
+ updateRemarksStatusEod,
44161
+ updateRemarksisAcknowledged,
41247
44162
  updateSiteSchema,
41248
44163
  useAccessManagementController,
41249
44164
  useAddressRepo,
@@ -41295,6 +44210,8 @@ function useOvernightParkingController() {
41295
44210
  useGuestManagementController,
41296
44211
  useGuestManagementRepo,
41297
44212
  useGuestManagementService,
44213
+ useHrmLabsAttendanceCtrl,
44214
+ useHrmLabsAttendanceSrvc,
41298
44215
  useIncidentReportController,
41299
44216
  useIncidentReportRepo,
41300
44217
  useIncidentReportService,
@@ -41306,6 +44223,11 @@ function useOvernightParkingController() {
41306
44223
  useManpowerMonitoringCtrl,
41307
44224
  useManpowerMonitoringRepo,
41308
44225
  useManpowerMonitoringSrvc,
44226
+ useManpowerRemarkCtrl,
44227
+ useManpowerRemarksRepo,
44228
+ useManpowerSitesCtrl,
44229
+ useManpowerSitesRepo,
44230
+ useManpowerSitesSrvc,
41309
44231
  useMemberController,
41310
44232
  useMemberRepo,
41311
44233
  useNewDashboardController,
@@ -41337,6 +44259,9 @@ function useOvernightParkingController() {
41337
44259
  useOrgRepo,
41338
44260
  useOvernightParkingController,
41339
44261
  useOvernightParkingRepo,
44262
+ useOvernightParkingRequestController,
44263
+ useOvernightParkingRequestRepo,
44264
+ useOvernightParkingRequestService,
41340
44265
  usePatrolLogController,
41341
44266
  usePatrolLogRepo,
41342
44267
  usePatrolQuestionController,