@7365admin1/module-hygiene 4.21.0 → 4.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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +35 -11
- package/dist/index.js +713 -408
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +728 -422
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -102,72 +102,57 @@ function useHygieneDashboardRepository() {
|
|
|
102
102
|
throw new import_node_server_utils.InternalServerError("Unable to connect to server.");
|
|
103
103
|
}
|
|
104
104
|
const dashboard_namespace_collection = "hygiene.dashboard";
|
|
105
|
-
const feedback_namespace_collection = "feedbacks";
|
|
106
105
|
const cleaning_schedule_namespace_collection = "site.cleaning.schedules";
|
|
107
106
|
const area_checklist_namespace_collection = "site.cleaning.schedule.areas";
|
|
108
|
-
const schedule_task_namespace_collection = "site.schedule-tasks";
|
|
109
107
|
const supply_namespace_collection = "site.supplies";
|
|
110
|
-
const
|
|
111
|
-
const feedbackCollection = db.collection(feedback_namespace_collection);
|
|
108
|
+
const work_order_namespace_collection = "work-orders2";
|
|
112
109
|
const areaChecklistCollection = db.collection(
|
|
113
110
|
area_checklist_namespace_collection
|
|
114
111
|
);
|
|
115
|
-
const scheduleTaskCollection = db.collection(
|
|
116
|
-
schedule_task_namespace_collection
|
|
117
|
-
);
|
|
118
112
|
const supplyCollection = db.collection(supply_namespace_collection);
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
);
|
|
113
|
+
const workOrderCollection = db.collection(work_order_namespace_collection);
|
|
114
|
+
const attendanceCollection = db.collection("site.attendances");
|
|
115
|
+
const feedbackCollection = db.collection("feedbacks2");
|
|
122
116
|
const { setCache, getCache } = (0, import_node_server_utils.useCache)(dashboard_namespace_collection);
|
|
117
|
+
const workOrderServiceMap = {
|
|
118
|
+
security_agency: "Security",
|
|
119
|
+
cleaning_services: "Cleaning",
|
|
120
|
+
mechanical_electrical_services: "M&E",
|
|
121
|
+
landscaping_services: "Landscape",
|
|
122
|
+
pest_control_services: "Pest Control",
|
|
123
|
+
pool_maintenance_services: "Pool Maintenance"
|
|
124
|
+
};
|
|
125
|
+
function areaChecklistScheduleLookup(site, serviceType, createdAtRange) {
|
|
126
|
+
return [
|
|
127
|
+
{ $match: { serviceType } },
|
|
128
|
+
{
|
|
129
|
+
$lookup: {
|
|
130
|
+
from: cleaning_schedule_namespace_collection,
|
|
131
|
+
localField: "schedule",
|
|
132
|
+
foreignField: "_id",
|
|
133
|
+
as: "scheduleDoc",
|
|
134
|
+
pipeline: [
|
|
135
|
+
{
|
|
136
|
+
$match: {
|
|
137
|
+
site,
|
|
138
|
+
serviceType,
|
|
139
|
+
createdAt: createdAtRange
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{ $unwind: { path: "$scheduleDoc", preserveNullAndEmptyArrays: false } }
|
|
146
|
+
];
|
|
147
|
+
}
|
|
123
148
|
async function getHygieneDashboard({
|
|
124
149
|
site,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
toiletAreaPeriod = "today",
|
|
128
|
-
scheduleTaskPeriod = "today",
|
|
129
|
-
supplyPeriod = "today",
|
|
130
|
-
requestItemPeriod = "today"
|
|
150
|
+
serviceType,
|
|
151
|
+
period = "today"
|
|
131
152
|
}) {
|
|
132
|
-
const
|
|
133
|
-
feedback: {},
|
|
134
|
-
commonArea: {},
|
|
135
|
-
toiletArea: {},
|
|
136
|
-
scheduleTask: {},
|
|
137
|
-
supply: {},
|
|
138
|
-
requestItem: {}
|
|
139
|
-
};
|
|
140
|
-
const yesterDayQueries = {
|
|
141
|
-
feedback: {},
|
|
142
|
-
commonArea: {},
|
|
143
|
-
toiletArea: {},
|
|
144
|
-
scheduleTask: {},
|
|
145
|
-
supply: {},
|
|
146
|
-
requestItem: {}
|
|
147
|
-
};
|
|
148
|
-
const todayQueries = {
|
|
149
|
-
feedback: {},
|
|
150
|
-
commonArea: {},
|
|
151
|
-
toiletArea: {},
|
|
152
|
-
scheduleTask: {},
|
|
153
|
-
supply: {},
|
|
154
|
-
requestItem: {}
|
|
155
|
-
};
|
|
156
|
-
const cacheOptions = {
|
|
157
|
-
feedbackPeriod,
|
|
158
|
-
commonAreaPeriod,
|
|
159
|
-
toiletAreaPeriod,
|
|
160
|
-
scheduleTaskPeriod,
|
|
161
|
-
supplyPeriod,
|
|
162
|
-
requestItemPeriod
|
|
163
|
-
};
|
|
153
|
+
const cacheOptions = { serviceType, period };
|
|
164
154
|
try {
|
|
165
155
|
site = new import_mongodb.ObjectId(site);
|
|
166
|
-
Object.keys(countQueries).forEach((key) => {
|
|
167
|
-
countQueries[key].site = site;
|
|
168
|
-
yesterDayQueries[key].site = site;
|
|
169
|
-
todayQueries[key].site = site;
|
|
170
|
-
});
|
|
171
156
|
cacheOptions.site = site.toString();
|
|
172
157
|
} catch (error) {
|
|
173
158
|
throw new import_node_server_utils.BadRequestError("Invalid site ID format.");
|
|
@@ -195,32 +180,28 @@ function useHygieneDashboardRepository() {
|
|
|
195
180
|
});
|
|
196
181
|
return singaporeMoment.toDate();
|
|
197
182
|
}
|
|
198
|
-
function
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
$gte: today,
|
|
204
|
-
$lte: formatEndDate(today)
|
|
205
|
-
};
|
|
206
|
-
} else if (period === "thisWeek" || period === "thisMonth") {
|
|
207
|
-
const filterDate = period === "thisWeek" ? 7 : 30;
|
|
208
|
-
const filterStartDate = /* @__PURE__ */ new Date();
|
|
209
|
-
filterStartDate.setDate(today.getDate() - filterDate);
|
|
210
|
-
filterStartDate.setHours(0, 0, 0, 0);
|
|
211
|
-
query.createdAt = {
|
|
212
|
-
$gte: filterStartDate,
|
|
213
|
-
$lte: formatEndDate(/* @__PURE__ */ new Date())
|
|
214
|
-
};
|
|
183
|
+
function getDateRange(p) {
|
|
184
|
+
const start = /* @__PURE__ */ new Date();
|
|
185
|
+
start.setHours(0, 0, 0, 0);
|
|
186
|
+
if (p === "today") {
|
|
187
|
+
return { $gte: start, $lte: formatEndDate(start) };
|
|
215
188
|
}
|
|
216
|
-
|
|
189
|
+
const days = p === "thisWeek" ? 7 : 30;
|
|
190
|
+
const rangeStart = /* @__PURE__ */ new Date();
|
|
191
|
+
rangeStart.setDate(start.getDate() - days);
|
|
192
|
+
rangeStart.setHours(0, 0, 0, 0);
|
|
193
|
+
return { $gte: rangeStart, $lte: formatEndDate(/* @__PURE__ */ new Date()) };
|
|
194
|
+
}
|
|
195
|
+
const calculatePercentageChange = (currentCount, previousCount) => {
|
|
196
|
+
if (previousCount === 0) {
|
|
197
|
+
return currentCount > 0 ? 100 : 0;
|
|
198
|
+
}
|
|
199
|
+
return Math.round(
|
|
200
|
+
(currentCount - previousCount) / previousCount * 100 * 100
|
|
201
|
+
) / 100;
|
|
202
|
+
};
|
|
203
|
+
const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
|
|
217
204
|
try {
|
|
218
|
-
applyPeriodToQuery(countQueries.feedback, feedbackPeriod);
|
|
219
|
-
applyPeriodToQuery(countQueries.commonArea, commonAreaPeriod);
|
|
220
|
-
applyPeriodToQuery(countQueries.toiletArea, toiletAreaPeriod);
|
|
221
|
-
applyPeriodToQuery(countQueries.scheduleTask, scheduleTaskPeriod);
|
|
222
|
-
applyPeriodToQuery(countQueries.supply, supplyPeriod);
|
|
223
|
-
applyPeriodToQuery(countQueries.requestItem, requestItemPeriod);
|
|
224
205
|
const today = /* @__PURE__ */ new Date();
|
|
225
206
|
today.setHours(0, 0, 0, 0);
|
|
226
207
|
const yesterday = /* @__PURE__ */ new Date();
|
|
@@ -228,359 +209,566 @@ function useHygieneDashboardRepository() {
|
|
|
228
209
|
yesterday.setHours(0, 0, 0, 0);
|
|
229
210
|
const yesterdayEnd = new Date(yesterday);
|
|
230
211
|
yesterdayEnd.setHours(23, 59, 59, 999);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
$gte: yesterday,
|
|
234
|
-
$lte: yesterdayEnd
|
|
235
|
-
};
|
|
236
|
-
});
|
|
237
|
-
Object.keys(todayQueries).forEach((key) => {
|
|
238
|
-
todayQueries[key].createdAt = {
|
|
239
|
-
$gte: today,
|
|
240
|
-
$lte: formatEndDate(/* @__PURE__ */ new Date())
|
|
241
|
-
};
|
|
242
|
-
});
|
|
243
|
-
const calculatePercentageChange = (currentCount, previousCount) => {
|
|
244
|
-
if (previousCount === 0) {
|
|
245
|
-
return currentCount > 0 ? 100 : 0;
|
|
246
|
-
}
|
|
247
|
-
return Math.round(
|
|
248
|
-
(currentCount - previousCount) / previousCount * 100 * 100
|
|
249
|
-
) / 100;
|
|
250
|
-
};
|
|
212
|
+
const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
|
|
213
|
+
const periodRange = getDateRange(period);
|
|
251
214
|
const [
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
215
|
+
workOrderReport,
|
|
216
|
+
supplyAlertReport,
|
|
217
|
+
taskCompletedReport,
|
|
218
|
+
yesterdayWorkOrderReport,
|
|
219
|
+
todayWorkOrderReport,
|
|
220
|
+
yesterdayTaskCompletedReport,
|
|
221
|
+
todayTaskCompletedReport
|
|
258
222
|
] = await Promise.all([
|
|
259
|
-
|
|
223
|
+
// 1. Open work orders (period-filtered) with inProgress breakdown
|
|
224
|
+
workOrderCollection.aggregate([
|
|
260
225
|
{
|
|
261
226
|
$match: {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
227
|
+
site,
|
|
228
|
+
service: workOrderService,
|
|
229
|
+
createdAt: periodRange,
|
|
230
|
+
status: { $nin: ["completed"] }
|
|
265
231
|
}
|
|
266
232
|
},
|
|
233
|
+
{
|
|
234
|
+
$facet: {
|
|
235
|
+
total: [{ $count: "count" }],
|
|
236
|
+
inProgress: [
|
|
237
|
+
{ $match: { status: "in-progress" } },
|
|
238
|
+
{ $count: "count" }
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
]).toArray(),
|
|
243
|
+
// 2. Supply alert — out-of-stock active supplies for site+serviceType
|
|
244
|
+
supplyCollection.aggregate([
|
|
245
|
+
{ $match: { site, serviceType, qty: 0, status: "active" } },
|
|
267
246
|
{ $count: "count" }
|
|
268
247
|
]).toArray(),
|
|
248
|
+
// 3. Task completed — area checklists (period-filtered via schedule join)
|
|
269
249
|
areaChecklistCollection.aggregate([
|
|
270
|
-
|
|
250
|
+
...areaChecklistScheduleLookup(site, serviceType, periodRange),
|
|
271
251
|
{
|
|
272
|
-
$
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
] : [{ $match: { site } }]
|
|
252
|
+
$facet: {
|
|
253
|
+
total: [{ $count: "count" }],
|
|
254
|
+
completed: [
|
|
255
|
+
{ $match: { status: "completed" } },
|
|
256
|
+
{ $count: "count" }
|
|
257
|
+
],
|
|
258
|
+
inProgress: [
|
|
259
|
+
{ $match: { status: { $in: ["open", "ongoing"] } } },
|
|
260
|
+
{ $count: "count" }
|
|
261
|
+
]
|
|
285
262
|
}
|
|
286
|
-
}
|
|
263
|
+
}
|
|
264
|
+
]).toArray(),
|
|
265
|
+
// 4. Yesterday open work orders (for % change)
|
|
266
|
+
workOrderCollection.aggregate([
|
|
287
267
|
{
|
|
288
|
-
$
|
|
289
|
-
|
|
290
|
-
|
|
268
|
+
$match: {
|
|
269
|
+
site,
|
|
270
|
+
service: workOrderService,
|
|
271
|
+
createdAt: { $gte: yesterday, $lte: yesterdayEnd },
|
|
272
|
+
status: { $nin: ["completed"] }
|
|
291
273
|
}
|
|
292
274
|
},
|
|
293
275
|
{ $count: "count" }
|
|
294
276
|
]).toArray(),
|
|
295
|
-
|
|
296
|
-
|
|
277
|
+
// 5. Today open work orders (for % change)
|
|
278
|
+
workOrderCollection.aggregate([
|
|
297
279
|
{
|
|
298
|
-
$
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
pipeline: countQueries.toiletArea.createdAt ? [
|
|
304
|
-
{
|
|
305
|
-
$match: {
|
|
306
|
-
site,
|
|
307
|
-
createdAt: countQueries.toiletArea.createdAt
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
] : [{ $match: { site } }]
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
$unwind: {
|
|
315
|
-
path: "$scheduleDoc",
|
|
316
|
-
preserveNullAndEmptyArrays: false
|
|
280
|
+
$match: {
|
|
281
|
+
site,
|
|
282
|
+
service: workOrderService,
|
|
283
|
+
createdAt: { $gte: today, $lte: todayEnd },
|
|
284
|
+
status: { $nin: ["completed"] }
|
|
317
285
|
}
|
|
318
286
|
},
|
|
319
287
|
{ $count: "count" }
|
|
320
288
|
]).toArray(),
|
|
321
|
-
|
|
322
|
-
|
|
289
|
+
// 6. Yesterday task completed — area checklists (for % change)
|
|
290
|
+
areaChecklistCollection.aggregate([
|
|
291
|
+
...areaChecklistScheduleLookup(site, serviceType, {
|
|
292
|
+
$gte: yesterday,
|
|
293
|
+
$lte: yesterdayEnd
|
|
294
|
+
}),
|
|
295
|
+
{ $match: { status: "completed" } },
|
|
323
296
|
{ $count: "count" }
|
|
324
297
|
]).toArray(),
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
298
|
+
// 7. Today task completed — area checklists (for % change)
|
|
299
|
+
areaChecklistCollection.aggregate([
|
|
300
|
+
...areaChecklistScheduleLookup(site, serviceType, {
|
|
301
|
+
$gte: today,
|
|
302
|
+
$lte: todayEnd
|
|
303
|
+
}),
|
|
304
|
+
{ $match: { status: "completed" } },
|
|
328
305
|
{ $count: "count" }
|
|
329
306
|
]).toArray()
|
|
330
307
|
]);
|
|
331
|
-
const [
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
308
|
+
const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
|
|
309
|
+
const tFacet = taskCompletedReport[0] ?? {
|
|
310
|
+
total: [],
|
|
311
|
+
completed: [],
|
|
312
|
+
inProgress: []
|
|
313
|
+
};
|
|
314
|
+
const result = {
|
|
315
|
+
openWorkOrder: {
|
|
316
|
+
count: wFacet.total[0]?.count ?? 0,
|
|
317
|
+
inProgress: wFacet.inProgress[0]?.count ?? 0,
|
|
318
|
+
percentage: calculatePercentageChange(
|
|
319
|
+
todayWorkOrderReport[0]?.count ?? 0,
|
|
320
|
+
yesterdayWorkOrderReport[0]?.count ?? 0
|
|
321
|
+
)
|
|
322
|
+
},
|
|
323
|
+
supplyAlert: {
|
|
324
|
+
count: supplyAlertReport[0]?.count ?? 0,
|
|
325
|
+
percentage: 0
|
|
326
|
+
},
|
|
327
|
+
taskCompleted: {
|
|
328
|
+
completed: tFacet.completed[0]?.count ?? 0,
|
|
329
|
+
total: tFacet.total[0]?.count ?? 0,
|
|
330
|
+
inProgress: tFacet.inProgress[0]?.count ?? 0,
|
|
331
|
+
percentage: calculatePercentageChange(
|
|
332
|
+
todayTaskCompletedReport[0]?.count ?? 0,
|
|
333
|
+
yesterdayTaskCompletedReport[0]?.count ?? 0
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
setCache(dashboardCacheKey, result, 15 * 60).then(() => {
|
|
338
|
+
import_node_server_utils.logger.info(`Cache set for dashboard: ${dashboardCacheKey}`);
|
|
339
|
+
}).catch((err) => {
|
|
340
|
+
import_node_server_utils.logger.error(
|
|
341
|
+
`Failed to set cache for dashboard: ${dashboardCacheKey}`,
|
|
342
|
+
err
|
|
343
|
+
);
|
|
344
|
+
});
|
|
345
|
+
return result;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function getWeeklyActivity({
|
|
351
|
+
site,
|
|
352
|
+
serviceType
|
|
353
|
+
}) {
|
|
354
|
+
const cacheOptions = { serviceType };
|
|
355
|
+
try {
|
|
356
|
+
site = new import_mongodb.ObjectId(site);
|
|
357
|
+
cacheOptions.site = site.toString();
|
|
358
|
+
} catch {
|
|
359
|
+
throw new import_node_server_utils.BadRequestError("Invalid site ID format.");
|
|
360
|
+
}
|
|
361
|
+
const cacheKey = (0, import_node_server_utils.makeCacheKey)(
|
|
362
|
+
`${dashboard_namespace_collection}:weeklyActivity`,
|
|
363
|
+
cacheOptions
|
|
364
|
+
);
|
|
365
|
+
const cachedData = await getCache(cacheKey);
|
|
366
|
+
if (cachedData) {
|
|
367
|
+
import_node_server_utils.logger.info(`Cache hit for weeklyActivity: ${cacheKey}`);
|
|
368
|
+
return cachedData;
|
|
369
|
+
}
|
|
370
|
+
const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
|
|
371
|
+
const weekStart = import_moment_timezone.default.tz("Asia/Singapore").startOf("isoWeek").toDate();
|
|
372
|
+
const weekEnd = import_moment_timezone.default.tz("Asia/Singapore").endOf("isoWeek").toDate();
|
|
373
|
+
const weekRange = { $gte: weekStart, $lte: weekEnd };
|
|
374
|
+
const dayLabels = {
|
|
375
|
+
1: "Sun",
|
|
376
|
+
2: "Mon",
|
|
377
|
+
3: "Tue",
|
|
378
|
+
4: "Wed",
|
|
379
|
+
5: "Thu",
|
|
380
|
+
6: "Fri",
|
|
381
|
+
7: "Sat"
|
|
382
|
+
};
|
|
383
|
+
const dayOrder = [2, 3, 4, 5, 6, 7, 1];
|
|
384
|
+
try {
|
|
385
|
+
const [workOrderByDay, taskCompletedByDay] = await Promise.all([
|
|
386
|
+
workOrderCollection.aggregate([
|
|
340
387
|
{
|
|
341
|
-
$match: {
|
|
342
|
-
...yesterDayQueries.feedback,
|
|
343
|
-
category: "cleaning_services",
|
|
344
|
-
status: "to-do"
|
|
345
|
-
}
|
|
388
|
+
$match: { site, service: workOrderService, createdAt: weekRange }
|
|
346
389
|
},
|
|
347
|
-
{
|
|
390
|
+
{
|
|
391
|
+
$group: { _id: { $dayOfWeek: "$createdAt" }, count: { $sum: 1 } }
|
|
392
|
+
}
|
|
348
393
|
]).toArray(),
|
|
349
394
|
areaChecklistCollection.aggregate([
|
|
350
|
-
|
|
395
|
+
...areaChecklistScheduleLookup(site, serviceType, weekRange),
|
|
396
|
+
{ $match: { status: "completed" } },
|
|
351
397
|
{
|
|
352
|
-
$
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
foreignField: "_id",
|
|
356
|
-
as: "scheduleDoc",
|
|
357
|
-
pipeline: [
|
|
358
|
-
{
|
|
359
|
-
$match: {
|
|
360
|
-
site,
|
|
361
|
-
createdAt: yesterDayQueries.commonArea.createdAt
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
]
|
|
398
|
+
$group: {
|
|
399
|
+
_id: { $dayOfWeek: "$completedAt" },
|
|
400
|
+
count: { $sum: 1 }
|
|
365
401
|
}
|
|
366
|
-
}
|
|
402
|
+
}
|
|
403
|
+
]).toArray()
|
|
404
|
+
]);
|
|
405
|
+
const workOrderMap = new Map(
|
|
406
|
+
workOrderByDay.map((d) => [d._id, d.count])
|
|
407
|
+
);
|
|
408
|
+
const taskMap = new Map(
|
|
409
|
+
taskCompletedByDay.map((d) => [d._id, d.count])
|
|
410
|
+
);
|
|
411
|
+
const result = dayOrder.map((dow) => ({
|
|
412
|
+
day: dayLabels[dow],
|
|
413
|
+
workOrder: workOrderMap.get(dow) ?? 0,
|
|
414
|
+
taskCompleted: taskMap.get(dow) ?? 0
|
|
415
|
+
}));
|
|
416
|
+
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
417
|
+
import_node_server_utils.logger.info(`Cache set for weeklyActivity: ${cacheKey}`);
|
|
418
|
+
}).catch((err) => {
|
|
419
|
+
import_node_server_utils.logger.error(
|
|
420
|
+
`Failed to set cache for weeklyActivity: ${cacheKey}`,
|
|
421
|
+
err
|
|
422
|
+
);
|
|
423
|
+
});
|
|
424
|
+
return result;
|
|
425
|
+
} catch (error) {
|
|
426
|
+
throw error;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
async function getTodayTaskSchedule({
|
|
430
|
+
site,
|
|
431
|
+
serviceType,
|
|
432
|
+
page = 1,
|
|
433
|
+
limit = 10
|
|
434
|
+
}) {
|
|
435
|
+
page = page > 0 ? page - 1 : 0;
|
|
436
|
+
const cacheOptions = { serviceType, page, limit };
|
|
437
|
+
try {
|
|
438
|
+
site = new import_mongodb.ObjectId(site);
|
|
439
|
+
cacheOptions.site = site.toString();
|
|
440
|
+
} catch {
|
|
441
|
+
throw new import_node_server_utils.BadRequestError("Invalid site ID format.");
|
|
442
|
+
}
|
|
443
|
+
const cacheKey = (0, import_node_server_utils.makeCacheKey)(
|
|
444
|
+
`${dashboard_namespace_collection}:todayTaskSchedule`,
|
|
445
|
+
cacheOptions
|
|
446
|
+
);
|
|
447
|
+
const cachedData = await getCache(cacheKey);
|
|
448
|
+
if (cachedData) {
|
|
449
|
+
import_node_server_utils.logger.info(`Cache hit for todayTaskSchedule: ${cacheKey}`);
|
|
450
|
+
return cachedData;
|
|
451
|
+
}
|
|
452
|
+
const todayStart = import_moment_timezone.default.tz("Asia/Singapore").startOf("day").toDate();
|
|
453
|
+
const todayEnd = import_moment_timezone.default.tz("Asia/Singapore").endOf("day").toDate();
|
|
454
|
+
const todayRange = { $gte: todayStart, $lte: todayEnd };
|
|
455
|
+
try {
|
|
456
|
+
const [items, countResult] = await Promise.all([
|
|
457
|
+
areaChecklistCollection.aggregate([
|
|
458
|
+
...areaChecklistScheduleLookup(site, serviceType, todayRange),
|
|
367
459
|
{
|
|
368
|
-
$
|
|
369
|
-
|
|
370
|
-
|
|
460
|
+
$addFields: {
|
|
461
|
+
_assigneeId: {
|
|
462
|
+
$reduce: {
|
|
463
|
+
input: { $ifNull: ["$checklist", []] },
|
|
464
|
+
initialValue: null,
|
|
465
|
+
in: {
|
|
466
|
+
$cond: {
|
|
467
|
+
if: { $ne: ["$$value", null] },
|
|
468
|
+
then: "$$value",
|
|
469
|
+
else: {
|
|
470
|
+
$reduce: {
|
|
471
|
+
input: { $ifNull: ["$$this.units", []] },
|
|
472
|
+
initialValue: null,
|
|
473
|
+
in: {
|
|
474
|
+
$cond: {
|
|
475
|
+
if: { $ne: ["$$value", null] },
|
|
476
|
+
then: "$$value",
|
|
477
|
+
else: {
|
|
478
|
+
$cond: {
|
|
479
|
+
if: { $gt: ["$$this.completedBy", null] },
|
|
480
|
+
then: "$$this.completedBy",
|
|
481
|
+
else: null
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
371
492
|
}
|
|
372
493
|
},
|
|
373
|
-
{ $count: "count" }
|
|
374
|
-
]).toArray(),
|
|
375
|
-
areaChecklistCollection.aggregate([
|
|
376
|
-
{ $match: { type: "toilet" } },
|
|
377
494
|
{
|
|
378
495
|
$lookup: {
|
|
379
|
-
from:
|
|
380
|
-
localField: "
|
|
496
|
+
from: "users",
|
|
497
|
+
localField: "_assigneeId",
|
|
381
498
|
foreignField: "_id",
|
|
382
|
-
as: "
|
|
383
|
-
pipeline: [
|
|
384
|
-
{
|
|
385
|
-
$match: {
|
|
386
|
-
site,
|
|
387
|
-
createdAt: yesterDayQueries.toiletArea.createdAt
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
]
|
|
499
|
+
as: "_assigneeDoc"
|
|
391
500
|
}
|
|
392
501
|
},
|
|
502
|
+
{ $sort: { createdAt: -1, _id: -1 } },
|
|
393
503
|
{
|
|
394
|
-
$
|
|
395
|
-
|
|
396
|
-
|
|
504
|
+
$project: {
|
|
505
|
+
name: 1,
|
|
506
|
+
type: 1,
|
|
507
|
+
status: 1,
|
|
508
|
+
assigneeName: { $arrayElemAt: ["$_assigneeDoc.name", 0] }
|
|
397
509
|
}
|
|
398
510
|
},
|
|
399
|
-
{ $
|
|
511
|
+
{ $skip: page * limit },
|
|
512
|
+
{ $limit: limit }
|
|
400
513
|
]).toArray(),
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
{ $count: "count" }
|
|
404
|
-
]).toArray(),
|
|
405
|
-
supplyCollection.aggregate([{ $match: yesterDayQueries.supply }, { $count: "count" }]).toArray(),
|
|
406
|
-
requestItemCollection.aggregate([
|
|
407
|
-
{ $match: yesterDayQueries.requestItem },
|
|
514
|
+
areaChecklistCollection.aggregate([
|
|
515
|
+
...areaChecklistScheduleLookup(site, serviceType, todayRange),
|
|
408
516
|
{ $count: "count" }
|
|
409
517
|
]).toArray()
|
|
410
518
|
]);
|
|
411
|
-
const [
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
519
|
+
const length = countResult[0]?.count ?? 0;
|
|
520
|
+
const data = (0, import_node_server_utils.paginate)(items, page, limit, length);
|
|
521
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
522
|
+
import_node_server_utils.logger.info(`Cache set for todayTaskSchedule: ${cacheKey}`);
|
|
523
|
+
}).catch((err) => {
|
|
524
|
+
import_node_server_utils.logger.error(
|
|
525
|
+
`Failed to set cache for todayTaskSchedule: ${cacheKey}`,
|
|
526
|
+
err
|
|
527
|
+
);
|
|
528
|
+
});
|
|
529
|
+
return data;
|
|
530
|
+
} catch (error) {
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async function getStaffAttendance({
|
|
535
|
+
site,
|
|
536
|
+
serviceType,
|
|
537
|
+
page = 1,
|
|
538
|
+
limit = 10
|
|
539
|
+
}) {
|
|
540
|
+
page = page > 0 ? page - 1 : 0;
|
|
541
|
+
const cacheOptions = { serviceType, page, limit };
|
|
542
|
+
try {
|
|
543
|
+
site = new import_mongodb.ObjectId(site);
|
|
544
|
+
cacheOptions.site = site.toString();
|
|
545
|
+
} catch {
|
|
546
|
+
throw new import_node_server_utils.BadRequestError("Invalid site ID format.");
|
|
547
|
+
}
|
|
548
|
+
const cacheKey = (0, import_node_server_utils.makeCacheKey)(
|
|
549
|
+
`${dashboard_namespace_collection}:staffAttendance`,
|
|
550
|
+
cacheOptions
|
|
551
|
+
);
|
|
552
|
+
const cachedData = await getCache(cacheKey);
|
|
553
|
+
if (cachedData) {
|
|
554
|
+
import_node_server_utils.logger.info(`Cache hit for staffAttendance: ${cacheKey}`);
|
|
555
|
+
return cachedData;
|
|
556
|
+
}
|
|
557
|
+
const todayStart = import_moment_timezone.default.tz("Asia/Singapore").startOf("day").toDate();
|
|
558
|
+
const todayEnd = import_moment_timezone.default.tz("Asia/Singapore").endOf("day").toDate();
|
|
559
|
+
const todayStartStr = todayStart.toISOString();
|
|
560
|
+
const todayEndStr = todayEnd.toISOString();
|
|
561
|
+
try {
|
|
562
|
+
const [items, length] = await Promise.all([
|
|
563
|
+
attendanceCollection.aggregate([
|
|
420
564
|
{
|
|
421
565
|
$match: {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
566
|
+
site,
|
|
567
|
+
serviceType,
|
|
568
|
+
$or: [
|
|
569
|
+
{ createdAt: { $gte: todayStart, $lte: todayEnd } },
|
|
570
|
+
{ createdAt: { $gte: todayStartStr, $lte: todayEndStr } }
|
|
571
|
+
]
|
|
425
572
|
}
|
|
426
573
|
},
|
|
427
|
-
{ $count: "count" }
|
|
428
|
-
]).toArray(),
|
|
429
|
-
areaChecklistCollection.aggregate([
|
|
430
|
-
{ $match: { type: "common" } },
|
|
431
574
|
{
|
|
432
575
|
$lookup: {
|
|
433
|
-
from:
|
|
434
|
-
localField: "
|
|
576
|
+
from: "users",
|
|
577
|
+
localField: "user",
|
|
435
578
|
foreignField: "_id",
|
|
436
|
-
as: "
|
|
579
|
+
as: "_userDoc"
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
$lookup: {
|
|
584
|
+
from: "members",
|
|
585
|
+
let: { userId: "$user", siteId: "$site", type: "$serviceType" },
|
|
437
586
|
pipeline: [
|
|
438
587
|
{
|
|
439
588
|
$match: {
|
|
440
|
-
|
|
441
|
-
|
|
589
|
+
$expr: {
|
|
590
|
+
$and: [
|
|
591
|
+
{ $eq: ["$user", "$$userId"] },
|
|
592
|
+
{ $eq: ["$siteId", "$$siteId"] },
|
|
593
|
+
{ $eq: ["$type", "$$type"] },
|
|
594
|
+
{ $ne: ["$status", "deleted"] }
|
|
595
|
+
]
|
|
596
|
+
}
|
|
442
597
|
}
|
|
443
598
|
}
|
|
444
|
-
]
|
|
599
|
+
],
|
|
600
|
+
as: "_memberDoc"
|
|
445
601
|
}
|
|
446
602
|
},
|
|
447
603
|
{
|
|
448
604
|
$unwind: {
|
|
449
|
-
path: "$
|
|
450
|
-
preserveNullAndEmptyArrays:
|
|
605
|
+
path: "$_memberDoc",
|
|
606
|
+
preserveNullAndEmptyArrays: true
|
|
451
607
|
}
|
|
452
608
|
},
|
|
453
|
-
{ $count: "count" }
|
|
454
|
-
]).toArray(),
|
|
455
|
-
areaChecklistCollection.aggregate([
|
|
456
|
-
{ $match: { type: "toilet" } },
|
|
457
609
|
{
|
|
458
610
|
$lookup: {
|
|
459
|
-
from:
|
|
460
|
-
localField: "
|
|
611
|
+
from: "roles",
|
|
612
|
+
localField: "_memberDoc.role",
|
|
461
613
|
foreignField: "_id",
|
|
462
|
-
as: "
|
|
463
|
-
pipeline: [
|
|
464
|
-
{
|
|
465
|
-
$match: {
|
|
466
|
-
site,
|
|
467
|
-
createdAt: todayQueries.toiletArea.createdAt
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
]
|
|
614
|
+
as: "_roleDoc"
|
|
471
615
|
}
|
|
472
616
|
},
|
|
473
617
|
{
|
|
474
618
|
$unwind: {
|
|
475
|
-
path: "$
|
|
476
|
-
preserveNullAndEmptyArrays:
|
|
619
|
+
path: "$_roleDoc",
|
|
620
|
+
preserveNullAndEmptyArrays: true
|
|
477
621
|
}
|
|
478
622
|
},
|
|
479
|
-
{ $
|
|
623
|
+
{ $sort: { createdAt: -1, _id: -1 } },
|
|
624
|
+
{
|
|
625
|
+
$project: {
|
|
626
|
+
checkIn: 1,
|
|
627
|
+
checkOut: 1,
|
|
628
|
+
createdAt: 1,
|
|
629
|
+
userName: { $arrayElemAt: ["$_userDoc.name", 0] },
|
|
630
|
+
userRole: { $ifNull: ["$_roleDoc.name", ""] },
|
|
631
|
+
totalHours: {
|
|
632
|
+
$round: [
|
|
633
|
+
{
|
|
634
|
+
$divide: [
|
|
635
|
+
{
|
|
636
|
+
$subtract: [
|
|
637
|
+
{
|
|
638
|
+
$toDate: {
|
|
639
|
+
$ifNull: ["$checkOut.timestamp", "$$NOW"]
|
|
640
|
+
}
|
|
641
|
+
},
|
|
642
|
+
{ $toDate: "$checkIn.timestamp" }
|
|
643
|
+
]
|
|
644
|
+
},
|
|
645
|
+
36e5
|
|
646
|
+
]
|
|
647
|
+
},
|
|
648
|
+
2
|
|
649
|
+
]
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
{ $skip: page * limit },
|
|
654
|
+
{ $limit: limit }
|
|
480
655
|
]).toArray(),
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
656
|
+
attendanceCollection.countDocuments({
|
|
657
|
+
site,
|
|
658
|
+
serviceType,
|
|
659
|
+
$or: [
|
|
660
|
+
{ createdAt: { $gte: todayStart, $lte: todayEnd } },
|
|
661
|
+
{ createdAt: { $gte: todayStartStr, $lte: todayEndStr } }
|
|
662
|
+
]
|
|
663
|
+
})
|
|
664
|
+
]);
|
|
665
|
+
const data = (0, import_node_server_utils.paginate)(items, page, limit, length);
|
|
666
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
667
|
+
import_node_server_utils.logger.info(`Cache set for staffAttendance: ${cacheKey}`);
|
|
668
|
+
}).catch((err) => {
|
|
669
|
+
import_node_server_utils.logger.error(
|
|
670
|
+
`Failed to set cache for staffAttendance: ${cacheKey}`,
|
|
671
|
+
err
|
|
672
|
+
);
|
|
673
|
+
});
|
|
674
|
+
return data;
|
|
675
|
+
} catch (error) {
|
|
676
|
+
throw error;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
async function getRecentFeedbacks({
|
|
680
|
+
site,
|
|
681
|
+
serviceType,
|
|
682
|
+
page = 1,
|
|
683
|
+
limit = 10
|
|
684
|
+
}) {
|
|
685
|
+
page = page > 0 ? page - 1 : 0;
|
|
686
|
+
const cacheOptions = { serviceType, page, limit };
|
|
687
|
+
try {
|
|
688
|
+
site = new import_mongodb.ObjectId(site);
|
|
689
|
+
cacheOptions.site = site.toString();
|
|
690
|
+
} catch {
|
|
691
|
+
throw new import_node_server_utils.BadRequestError("Invalid site ID format.");
|
|
692
|
+
}
|
|
693
|
+
const cacheKey = (0, import_node_server_utils.makeCacheKey)(
|
|
694
|
+
`${dashboard_namespace_collection}:recentFeedbacks`,
|
|
695
|
+
cacheOptions
|
|
696
|
+
);
|
|
697
|
+
const cachedData = await getCache(cacheKey);
|
|
698
|
+
if (cachedData) {
|
|
699
|
+
import_node_server_utils.logger.info(`Cache hit for recentFeedbacks: ${cacheKey}`);
|
|
700
|
+
return cachedData;
|
|
701
|
+
}
|
|
702
|
+
const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
|
|
703
|
+
try {
|
|
704
|
+
const [items, length] = await Promise.all([
|
|
705
|
+
feedbackCollection.aggregate([
|
|
706
|
+
{ $match: { site, service: workOrderService } },
|
|
707
|
+
{ $sort: { createdAt: -1, _id: -1 } },
|
|
708
|
+
{
|
|
709
|
+
$lookup: {
|
|
710
|
+
from: "users",
|
|
711
|
+
localField: "createdBy",
|
|
712
|
+
foreignField: "_id",
|
|
713
|
+
as: "_createdByDoc"
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
$project: {
|
|
718
|
+
description: 1,
|
|
719
|
+
subject: 1,
|
|
720
|
+
app: 1,
|
|
721
|
+
status: 1,
|
|
722
|
+
createdAt: 1,
|
|
723
|
+
createdByName: { $arrayElemAt: ["$_createdByDoc.name", 0] }
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
{ $skip: page * limit },
|
|
727
|
+
{ $limit: limit }
|
|
484
728
|
]).toArray(),
|
|
485
|
-
|
|
486
|
-
requestItemCollection.aggregate([
|
|
487
|
-
{ $match: todayQueries.requestItem },
|
|
488
|
-
{ $count: "count" }
|
|
489
|
-
]).toArray()
|
|
729
|
+
feedbackCollection.countDocuments({ site, service: workOrderService })
|
|
490
730
|
]);
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
toiletAreaChecklistCount: yesterdayToiletAreaChecklistCount[0]?.count || 0,
|
|
495
|
-
scheduleTaskCount: yesterdayScheduledTaskCount[0]?.count || 0,
|
|
496
|
-
supplyCount: yesterdaySupplyCount[0]?.count || 0,
|
|
497
|
-
requestItemCount: yesterdayRequestItemCount[0]?.count || 0
|
|
498
|
-
};
|
|
499
|
-
const resultToday = {
|
|
500
|
-
feedbackCount: todayFeedbackCount[0]?.count || 0,
|
|
501
|
-
commonAreaChecklistCount: todayCommonAreaChecklistCount[0]?.count || 0,
|
|
502
|
-
toiletAreaChecklistCount: todayToiletAreaChecklistCount[0]?.count || 0,
|
|
503
|
-
scheduleTaskCount: todayScheduledTaskCount[0]?.count || 0,
|
|
504
|
-
supplyCount: todaySupplyCount[0]?.count || 0,
|
|
505
|
-
requestItemCount: todayRequestItemCount[0]?.count || 0
|
|
506
|
-
};
|
|
507
|
-
const result = {
|
|
508
|
-
feedback: {
|
|
509
|
-
count: feedbackReport[0]?.count || 0,
|
|
510
|
-
percentage: calculatePercentageChange(
|
|
511
|
-
resultToday.feedbackCount,
|
|
512
|
-
resultYesterday.feedbackCount
|
|
513
|
-
)
|
|
514
|
-
},
|
|
515
|
-
commonAreaChecklist: {
|
|
516
|
-
count: commonAreaChecklistReport[0]?.count || 0,
|
|
517
|
-
percentage: calculatePercentageChange(
|
|
518
|
-
resultToday.commonAreaChecklistCount,
|
|
519
|
-
resultYesterday.commonAreaChecklistCount
|
|
520
|
-
)
|
|
521
|
-
},
|
|
522
|
-
toiletAreaChecklist: {
|
|
523
|
-
count: toiletAreaChecklistReport[0]?.count || 0,
|
|
524
|
-
percentage: calculatePercentageChange(
|
|
525
|
-
resultToday.toiletAreaChecklistCount,
|
|
526
|
-
resultYesterday.toiletAreaChecklistCount
|
|
527
|
-
)
|
|
528
|
-
},
|
|
529
|
-
scheduleTask: {
|
|
530
|
-
count: scheduleTaskReport[0]?.count || 0,
|
|
531
|
-
percentage: calculatePercentageChange(
|
|
532
|
-
resultToday.scheduleTaskCount,
|
|
533
|
-
resultYesterday.scheduleTaskCount
|
|
534
|
-
)
|
|
535
|
-
},
|
|
536
|
-
supply: {
|
|
537
|
-
count: supplyReport[0]?.count || 0,
|
|
538
|
-
percentage: calculatePercentageChange(
|
|
539
|
-
resultToday.supplyCount,
|
|
540
|
-
resultYesterday.supplyCount
|
|
541
|
-
)
|
|
542
|
-
},
|
|
543
|
-
requestItem: {
|
|
544
|
-
count: requestItemReport[0]?.count || 0,
|
|
545
|
-
percentage: calculatePercentageChange(
|
|
546
|
-
resultToday.requestItemCount,
|
|
547
|
-
resultYesterday.requestItemCount
|
|
548
|
-
)
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
setCache(dashboardCacheKey, result, 15 * 60).then(() => {
|
|
552
|
-
import_node_server_utils.logger.info(`Cache set for dashboard: ${dashboardCacheKey}`);
|
|
731
|
+
const data = (0, import_node_server_utils.paginate)(items, page, limit, length);
|
|
732
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
733
|
+
import_node_server_utils.logger.info(`Cache set for recentFeedbacks: ${cacheKey}`);
|
|
553
734
|
}).catch((err) => {
|
|
554
735
|
import_node_server_utils.logger.error(
|
|
555
|
-
`Failed to set cache for
|
|
736
|
+
`Failed to set cache for recentFeedbacks: ${cacheKey}`,
|
|
556
737
|
err
|
|
557
738
|
);
|
|
558
739
|
});
|
|
559
|
-
return
|
|
740
|
+
return data;
|
|
560
741
|
} catch (error) {
|
|
561
742
|
throw error;
|
|
562
743
|
}
|
|
563
744
|
}
|
|
564
745
|
return {
|
|
565
|
-
getHygieneDashboard
|
|
746
|
+
getHygieneDashboard,
|
|
747
|
+
getWeeklyActivity,
|
|
748
|
+
getTodayTaskSchedule,
|
|
749
|
+
getStaffAttendance,
|
|
750
|
+
getRecentFeedbacks
|
|
566
751
|
};
|
|
567
752
|
}
|
|
568
753
|
|
|
569
754
|
// src/controllers/hygiene-dashboard.controller.ts
|
|
570
755
|
var import_joi = __toESM(require("joi"));
|
|
571
756
|
var import_node_server_utils2 = require("@7365admin1/node-server-utils");
|
|
757
|
+
var import_core = require("@7365admin1/core");
|
|
572
758
|
function useHygieneDashboardController() {
|
|
573
|
-
const {
|
|
759
|
+
const {
|
|
760
|
+
getHygieneDashboard: _getHygieneDashboard,
|
|
761
|
+
getWeeklyActivity: _getWeeklyActivity,
|
|
762
|
+
getTodayTaskSchedule: _getTodayTaskSchedule,
|
|
763
|
+
getStaffAttendance: _getStaffAttendance,
|
|
764
|
+
getRecentFeedbacks: _getRecentFeedbacks
|
|
765
|
+
} = useHygieneDashboardRepository();
|
|
574
766
|
async function getHygieneDashboard(req, res, next) {
|
|
575
767
|
const query = { ...req.query, ...req.params };
|
|
576
768
|
const validation = import_joi.default.object({
|
|
577
769
|
site: import_joi.default.string().hex().required(),
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
toiletAreaPeriod: import_joi.default.string().valid(...allowedPeriods).optional(),
|
|
581
|
-
scheduleTaskPeriod: import_joi.default.string().valid(...allowedPeriods).optional(),
|
|
582
|
-
supplyPeriod: import_joi.default.string().valid(...allowedPeriods).optional(),
|
|
583
|
-
requestItemPeriod: import_joi.default.string().valid(...allowedPeriods).optional()
|
|
770
|
+
serviceType: import_joi.default.string().valid(...Object.values(import_core.AppServiceType)).required(),
|
|
771
|
+
period: import_joi.default.string().valid(...allowedPeriods).optional()
|
|
584
772
|
});
|
|
585
773
|
const { error } = validation.validate(query);
|
|
586
774
|
if (error) {
|
|
@@ -589,21 +777,136 @@ function useHygieneDashboardController() {
|
|
|
589
777
|
return;
|
|
590
778
|
}
|
|
591
779
|
const site = req.params.site ?? "";
|
|
592
|
-
const
|
|
593
|
-
const
|
|
594
|
-
const toiletAreaPeriod = req.query.toiletAreaPeriod || "today";
|
|
595
|
-
const scheduleTaskPeriod = req.query.scheduleTaskPeriod || "today";
|
|
596
|
-
const supplyPeriod = req.query.supplyPeriod || "today";
|
|
597
|
-
const requestItemPeriod = req.query.requestItemPeriod || "today";
|
|
780
|
+
const serviceType = req.params.serviceType;
|
|
781
|
+
const period = req.query.period || "today";
|
|
598
782
|
try {
|
|
599
783
|
const data = await _getHygieneDashboard({
|
|
600
784
|
site,
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
785
|
+
period,
|
|
786
|
+
serviceType
|
|
787
|
+
});
|
|
788
|
+
res.json(data);
|
|
789
|
+
return;
|
|
790
|
+
} catch (error2) {
|
|
791
|
+
import_node_server_utils2.logger.log({ level: "error", message: error2.message });
|
|
792
|
+
next(error2);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
async function getWeeklyActivity(req, res, next) {
|
|
797
|
+
const query = { ...req.params };
|
|
798
|
+
const validation = import_joi.default.object({
|
|
799
|
+
site: import_joi.default.string().hex().required(),
|
|
800
|
+
serviceType: import_joi.default.string().valid(...Object.values(import_core.AppServiceType)).required()
|
|
801
|
+
});
|
|
802
|
+
const { error } = validation.validate(query);
|
|
803
|
+
if (error) {
|
|
804
|
+
import_node_server_utils2.logger.log({ level: "error", message: error.message });
|
|
805
|
+
next(new import_node_server_utils2.BadRequestError(error.message));
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
const site = req.params.site;
|
|
809
|
+
const serviceType = req.params.serviceType;
|
|
810
|
+
try {
|
|
811
|
+
const data = await _getWeeklyActivity({ site, serviceType });
|
|
812
|
+
res.json(data);
|
|
813
|
+
return;
|
|
814
|
+
} catch (error2) {
|
|
815
|
+
import_node_server_utils2.logger.log({ level: "error", message: error2.message });
|
|
816
|
+
next(error2);
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
async function getTodayTaskSchedule(req, res, next) {
|
|
821
|
+
const query = { ...req.query, ...req.params };
|
|
822
|
+
const validation = import_joi.default.object({
|
|
823
|
+
site: import_joi.default.string().hex().required(),
|
|
824
|
+
serviceType: import_joi.default.string().valid(...Object.values(import_core.AppServiceType)).required(),
|
|
825
|
+
page: import_joi.default.number().min(1).optional().allow("", null),
|
|
826
|
+
limit: import_joi.default.number().min(1).optional().allow("", null)
|
|
827
|
+
});
|
|
828
|
+
const { error } = validation.validate(query);
|
|
829
|
+
if (error) {
|
|
830
|
+
import_node_server_utils2.logger.log({ level: "error", message: error.message });
|
|
831
|
+
next(new import_node_server_utils2.BadRequestError(error.message));
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
const site = req.params.site;
|
|
835
|
+
const serviceType = req.params.serviceType;
|
|
836
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
837
|
+
const limit = parseInt(req.query.limit) ?? 10;
|
|
838
|
+
try {
|
|
839
|
+
const data = await _getTodayTaskSchedule({
|
|
840
|
+
site,
|
|
841
|
+
serviceType,
|
|
842
|
+
page,
|
|
843
|
+
limit
|
|
844
|
+
});
|
|
845
|
+
res.json(data);
|
|
846
|
+
return;
|
|
847
|
+
} catch (error2) {
|
|
848
|
+
import_node_server_utils2.logger.log({ level: "error", message: error2.message });
|
|
849
|
+
next(error2);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
async function getStaffAttendance(req, res, next) {
|
|
854
|
+
const query = { ...req.query, ...req.params };
|
|
855
|
+
const validation = import_joi.default.object({
|
|
856
|
+
site: import_joi.default.string().hex().required(),
|
|
857
|
+
serviceType: import_joi.default.string().valid(...Object.values(import_core.AppServiceType)).required(),
|
|
858
|
+
page: import_joi.default.number().min(1).optional().allow("", null),
|
|
859
|
+
limit: import_joi.default.number().min(1).optional().allow("", null)
|
|
860
|
+
});
|
|
861
|
+
const { error } = validation.validate(query);
|
|
862
|
+
if (error) {
|
|
863
|
+
import_node_server_utils2.logger.log({ level: "error", message: error.message });
|
|
864
|
+
next(new import_node_server_utils2.BadRequestError(error.message));
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const site = req.params.site;
|
|
868
|
+
const serviceType = req.params.serviceType;
|
|
869
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
870
|
+
const limit = parseInt(req.query.limit) ?? 10;
|
|
871
|
+
try {
|
|
872
|
+
const data = await _getStaffAttendance({
|
|
873
|
+
site,
|
|
874
|
+
serviceType,
|
|
875
|
+
page,
|
|
876
|
+
limit
|
|
877
|
+
});
|
|
878
|
+
res.json(data);
|
|
879
|
+
return;
|
|
880
|
+
} catch (error2) {
|
|
881
|
+
import_node_server_utils2.logger.log({ level: "error", message: error2.message });
|
|
882
|
+
next(error2);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
async function getRecentFeedbacks(req, res, next) {
|
|
887
|
+
const query = { ...req.query, ...req.params };
|
|
888
|
+
const validation = import_joi.default.object({
|
|
889
|
+
site: import_joi.default.string().hex().required(),
|
|
890
|
+
serviceType: import_joi.default.string().valid(...Object.values(import_core.AppServiceType)).required(),
|
|
891
|
+
page: import_joi.default.number().min(1).optional().allow("", null),
|
|
892
|
+
limit: import_joi.default.number().min(1).optional().allow("", null)
|
|
893
|
+
});
|
|
894
|
+
const { error } = validation.validate(query);
|
|
895
|
+
if (error) {
|
|
896
|
+
import_node_server_utils2.logger.log({ level: "error", message: error.message });
|
|
897
|
+
next(new import_node_server_utils2.BadRequestError(error.message));
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
const site = req.params.site;
|
|
901
|
+
const serviceType = req.params.serviceType;
|
|
902
|
+
const page = parseInt(req.query.page) ?? 1;
|
|
903
|
+
const limit = parseInt(req.query.limit) ?? 10;
|
|
904
|
+
try {
|
|
905
|
+
const data = await _getRecentFeedbacks({
|
|
906
|
+
site,
|
|
907
|
+
serviceType,
|
|
908
|
+
page,
|
|
909
|
+
limit
|
|
607
910
|
});
|
|
608
911
|
res.json(data);
|
|
609
912
|
return;
|
|
@@ -614,7 +917,11 @@ function useHygieneDashboardController() {
|
|
|
614
917
|
}
|
|
615
918
|
}
|
|
616
919
|
return {
|
|
617
|
-
getHygieneDashboard
|
|
920
|
+
getHygieneDashboard,
|
|
921
|
+
getWeeklyActivity,
|
|
922
|
+
getTodayTaskSchedule,
|
|
923
|
+
getStaffAttendance,
|
|
924
|
+
getRecentFeedbacks
|
|
618
925
|
};
|
|
619
926
|
}
|
|
620
927
|
|
|
@@ -622,10 +929,10 @@ function useHygieneDashboardController() {
|
|
|
622
929
|
var import_joi2 = __toESM(require("joi"));
|
|
623
930
|
var import_mongodb2 = require("mongodb");
|
|
624
931
|
var import_node_server_utils3 = require("@7365admin1/node-server-utils");
|
|
625
|
-
var
|
|
932
|
+
var import_core2 = require("@7365admin1/core");
|
|
626
933
|
var areaSchema = import_joi2.default.object({
|
|
627
934
|
site: import_joi2.default.string().hex().required(),
|
|
628
|
-
serviceType: import_joi2.default.string().valid(...Object.values(
|
|
935
|
+
serviceType: import_joi2.default.string().valid(...Object.values(import_core2.AppServiceType)).required(),
|
|
629
936
|
name: import_joi2.default.string().required(),
|
|
630
937
|
type: import_joi2.default.string().valid(...allowedTypes).required(),
|
|
631
938
|
set: import_joi2.default.number().min(0).optional(),
|
|
@@ -1129,10 +1436,10 @@ var import_node_server_utils7 = require("@7365admin1/node-server-utils");
|
|
|
1129
1436
|
var import_joi3 = __toESM(require("joi"));
|
|
1130
1437
|
var import_mongodb4 = require("mongodb");
|
|
1131
1438
|
var import_node_server_utils6 = require("@7365admin1/node-server-utils");
|
|
1132
|
-
var
|
|
1439
|
+
var import_core3 = require("@7365admin1/core");
|
|
1133
1440
|
var unitSchema = import_joi3.default.object({
|
|
1134
1441
|
site: import_joi3.default.string().hex().required(),
|
|
1135
|
-
serviceType: import_joi3.default.string().valid(...Object.values(
|
|
1442
|
+
serviceType: import_joi3.default.string().valid(...Object.values(import_core3.AppServiceType)).required(),
|
|
1136
1443
|
name: import_joi3.default.string().required()
|
|
1137
1444
|
});
|
|
1138
1445
|
function MUnit(value) {
|
|
@@ -1553,7 +1860,7 @@ function useAreaService() {
|
|
|
1553
1860
|
// src/controllers/hygiene-area.controller.ts
|
|
1554
1861
|
var import_joi4 = __toESM(require("joi"));
|
|
1555
1862
|
var import_node_server_utils9 = require("@7365admin1/node-server-utils");
|
|
1556
|
-
var
|
|
1863
|
+
var import_core4 = require("@7365admin1/core");
|
|
1557
1864
|
|
|
1558
1865
|
// src/utils/convert-excel.util.ts
|
|
1559
1866
|
var import_stream = require("stream");
|
|
@@ -1618,7 +1925,7 @@ function useAreaController() {
|
|
|
1618
1925
|
search: import_joi4.default.string().optional().allow("", null),
|
|
1619
1926
|
type: import_joi4.default.string().valid("all", ...allowedTypes).optional().allow("", null),
|
|
1620
1927
|
site: import_joi4.default.string().hex().required(),
|
|
1621
|
-
serviceType: import_joi4.default.string().valid(...Object.values(
|
|
1928
|
+
serviceType: import_joi4.default.string().valid(...Object.values(import_core4.AppServiceType)).required()
|
|
1622
1929
|
});
|
|
1623
1930
|
const { error } = validation.validate(query);
|
|
1624
1931
|
if (error) {
|
|
@@ -1727,7 +2034,7 @@ function useAreaController() {
|
|
|
1727
2034
|
const query = { ...req.query, ...req.params };
|
|
1728
2035
|
const validation = import_joi4.default.object({
|
|
1729
2036
|
site: import_joi4.default.string().hex().required(),
|
|
1730
|
-
serviceType: import_joi4.default.string().valid(...Object.values(
|
|
2037
|
+
serviceType: import_joi4.default.string().valid(...Object.values(import_core4.AppServiceType)).required()
|
|
1731
2038
|
});
|
|
1732
2039
|
const { error, value } = validation.validate(query);
|
|
1733
2040
|
if (error) {
|
|
@@ -1750,7 +2057,7 @@ function useAreaController() {
|
|
|
1750
2057
|
const query = { ...req.query, ...req.params };
|
|
1751
2058
|
const validation = import_joi4.default.object({
|
|
1752
2059
|
site: import_joi4.default.string().hex().required(),
|
|
1753
|
-
serviceType: import_joi4.default.string().valid(...Object.values(
|
|
2060
|
+
serviceType: import_joi4.default.string().valid(...Object.values(import_core4.AppServiceType)).required()
|
|
1754
2061
|
});
|
|
1755
2062
|
const { error, value } = validation.validate(query);
|
|
1756
2063
|
if (error) {
|
|
@@ -2028,7 +2335,7 @@ function useUnitService() {
|
|
|
2028
2335
|
// src/controllers/hygiene-unit.controller.ts
|
|
2029
2336
|
var import_joi5 = __toESM(require("joi"));
|
|
2030
2337
|
var import_node_server_utils12 = require("@7365admin1/node-server-utils");
|
|
2031
|
-
var
|
|
2338
|
+
var import_core5 = require("@7365admin1/core");
|
|
2032
2339
|
function useUnitController() {
|
|
2033
2340
|
const { createUnit: _createUnit, getUnits: _getUnits } = useUnitRepository();
|
|
2034
2341
|
const {
|
|
@@ -2062,7 +2369,7 @@ function useUnitController() {
|
|
|
2062
2369
|
limit: import_joi5.default.number().min(1).optional().allow("", null),
|
|
2063
2370
|
search: import_joi5.default.string().optional().allow("", null),
|
|
2064
2371
|
site: import_joi5.default.string().hex().required(),
|
|
2065
|
-
serviceType: import_joi5.default.string().valid(...Object.values(
|
|
2372
|
+
serviceType: import_joi5.default.string().valid(...Object.values(import_core5.AppServiceType)).required()
|
|
2066
2373
|
});
|
|
2067
2374
|
const { error } = validation.validate(query);
|
|
2068
2375
|
if (error) {
|
|
@@ -2143,7 +2450,7 @@ function useUnitController() {
|
|
|
2143
2450
|
const query = { ...req.query, ...req.params };
|
|
2144
2451
|
const validation = import_joi5.default.object({
|
|
2145
2452
|
site: import_joi5.default.string().hex().required(),
|
|
2146
|
-
serviceType: import_joi5.default.string().valid(...Object.values(
|
|
2453
|
+
serviceType: import_joi5.default.string().valid(...Object.values(import_core5.AppServiceType)).required()
|
|
2147
2454
|
});
|
|
2148
2455
|
const { error, value } = validation.validate(query);
|
|
2149
2456
|
if (error) {
|
|
@@ -2166,7 +2473,7 @@ function useUnitController() {
|
|
|
2166
2473
|
const query = { ...req.query, ...req.params };
|
|
2167
2474
|
const validation = import_joi5.default.object({
|
|
2168
2475
|
site: import_joi5.default.string().hex().required(),
|
|
2169
|
-
serviceType: import_joi5.default.string().valid(...Object.values(
|
|
2476
|
+
serviceType: import_joi5.default.string().valid(...Object.values(import_core5.AppServiceType)).required()
|
|
2170
2477
|
});
|
|
2171
2478
|
const { error, value } = validation.validate(query);
|
|
2172
2479
|
if (error) {
|
|
@@ -2212,11 +2519,11 @@ function useUnitController() {
|
|
|
2212
2519
|
var import_joi6 = __toESM(require("joi"));
|
|
2213
2520
|
var import_mongodb6 = require("mongodb");
|
|
2214
2521
|
var import_node_server_utils13 = require("@7365admin1/node-server-utils");
|
|
2215
|
-
var
|
|
2522
|
+
var import_core6 = require("@7365admin1/core");
|
|
2216
2523
|
var parentChecklistSchema = import_joi6.default.object({
|
|
2217
2524
|
createdAt: import_joi6.default.alternatives().try(import_joi6.default.date(), import_joi6.default.string()).optional().allow("", null),
|
|
2218
2525
|
site: import_joi6.default.string().hex().required(),
|
|
2219
|
-
serviceType: import_joi6.default.string().valid(...Object.values(
|
|
2526
|
+
serviceType: import_joi6.default.string().valid(...Object.values(import_core6.AppServiceType)).required()
|
|
2220
2527
|
});
|
|
2221
2528
|
function MParentChecklist(value) {
|
|
2222
2529
|
const { error } = parentChecklistSchema.validate(value);
|
|
@@ -2242,8 +2549,9 @@ function MParentChecklist(value) {
|
|
|
2242
2549
|
|
|
2243
2550
|
// src/repositories/hygiene-parent-checklist.repository.ts
|
|
2244
2551
|
var import_mongodb7 = require("mongodb");
|
|
2552
|
+
var import_moment_timezone2 = __toESM(require("moment-timezone"));
|
|
2245
2553
|
var import_node_server_utils14 = require("@7365admin1/node-server-utils");
|
|
2246
|
-
var
|
|
2554
|
+
var import_core7 = require("@7365admin1/core");
|
|
2247
2555
|
function useParentChecklistRepo() {
|
|
2248
2556
|
const db = import_node_server_utils14.useAtlas.getDb();
|
|
2249
2557
|
if (!db) {
|
|
@@ -2271,11 +2579,9 @@ function useParentChecklistRepo() {
|
|
|
2271
2579
|
async function createParentChecklist(value, session) {
|
|
2272
2580
|
try {
|
|
2273
2581
|
const currentDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
2274
|
-
const startOfDay =
|
|
2275
|
-
|
|
2276
|
-
const
|
|
2277
|
-
endOfDay.setUTCHours(23, 59, 59, 999);
|
|
2278
|
-
const allServiceTypes = Object.values(import_core6.AppServiceType);
|
|
2582
|
+
const startOfDay = (0, import_moment_timezone2.default)(currentDate).tz("Asia/Singapore").startOf("day").toDate();
|
|
2583
|
+
const endOfDay = (0, import_moment_timezone2.default)(currentDate).tz("Asia/Singapore").endOf("day").toDate();
|
|
2584
|
+
const allServiceTypes = Object.values(import_core7.AppServiceType);
|
|
2279
2585
|
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2280
2586
|
if (value.site) {
|
|
2281
2587
|
let siteObjectId;
|
|
@@ -2625,11 +2931,8 @@ function useParentChecklistRepo() {
|
|
|
2625
2931
|
}
|
|
2626
2932
|
}
|
|
2627
2933
|
async function getTodayParentChecklists() {
|
|
2628
|
-
const
|
|
2629
|
-
const
|
|
2630
|
-
start.setUTCHours(0, 0, 0, 0);
|
|
2631
|
-
const end = new Date(now);
|
|
2632
|
-
end.setUTCHours(23, 59, 59, 999);
|
|
2934
|
+
const start = (0, import_moment_timezone2.default)().tz("Asia/Singapore").startOf("day").toDate();
|
|
2935
|
+
const end = (0, import_moment_timezone2.default)().tz("Asia/Singapore").endOf("day").toDate();
|
|
2633
2936
|
try {
|
|
2634
2937
|
const items = await collection.find(
|
|
2635
2938
|
{ createdAt: { $gte: start, $lte: end } },
|
|
@@ -2642,11 +2945,8 @@ function useParentChecklistRepo() {
|
|
|
2642
2945
|
}
|
|
2643
2946
|
}
|
|
2644
2947
|
async function getTodayParentChecklistsForAreaGen() {
|
|
2645
|
-
const
|
|
2646
|
-
const
|
|
2647
|
-
start.setUTCHours(0, 0, 0, 0);
|
|
2648
|
-
const end = new Date(now);
|
|
2649
|
-
end.setUTCHours(23, 59, 59, 999);
|
|
2948
|
+
const start = (0, import_moment_timezone2.default)().tz("Asia/Singapore").startOf("day").toDate();
|
|
2949
|
+
const end = (0, import_moment_timezone2.default)().tz("Asia/Singapore").endOf("day").toDate();
|
|
2650
2950
|
try {
|
|
2651
2951
|
const items = await collection.find(
|
|
2652
2952
|
{
|
|
@@ -2680,7 +2980,7 @@ function useParentChecklistRepo() {
|
|
|
2680
2980
|
// src/controllers/hygiene-parent-checklist.controller.ts
|
|
2681
2981
|
var import_joi7 = __toESM(require("joi"));
|
|
2682
2982
|
var import_node_server_utils15 = require("@7365admin1/node-server-utils");
|
|
2683
|
-
var
|
|
2983
|
+
var import_core8 = require("@7365admin1/core");
|
|
2684
2984
|
function useParentChecklistController() {
|
|
2685
2985
|
const {
|
|
2686
2986
|
createParentChecklist: _createParentChecklist,
|
|
@@ -2691,7 +2991,7 @@ function useParentChecklistController() {
|
|
|
2691
2991
|
const validation = import_joi7.default.object({
|
|
2692
2992
|
createdAt: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2693
2993
|
site: import_joi7.default.string().hex().required(),
|
|
2694
|
-
serviceType: import_joi7.default.string().valid(...Object.values(
|
|
2994
|
+
serviceType: import_joi7.default.string().valid(...Object.values(import_core8.AppServiceType)).optional().allow("", null)
|
|
2695
2995
|
});
|
|
2696
2996
|
const { error } = validation.validate(payload);
|
|
2697
2997
|
if (error) {
|
|
@@ -2716,7 +3016,7 @@ function useParentChecklistController() {
|
|
|
2716
3016
|
limit: import_joi7.default.number().min(1).optional().allow("", null),
|
|
2717
3017
|
search: import_joi7.default.string().optional().allow("", null),
|
|
2718
3018
|
site: import_joi7.default.string().hex().required(),
|
|
2719
|
-
serviceType: import_joi7.default.string().valid(...Object.values(
|
|
3019
|
+
serviceType: import_joi7.default.string().valid(...Object.values(import_core8.AppServiceType)).required(),
|
|
2720
3020
|
startDate: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2721
3021
|
endDate: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2722
3022
|
status: import_joi7.default.string().valid(...allowedStatus, "all").optional().allow("", null)
|
|
@@ -2764,11 +3064,11 @@ function useParentChecklistController() {
|
|
|
2764
3064
|
var import_joi8 = __toESM(require("joi"));
|
|
2765
3065
|
var import_mongodb8 = require("mongodb");
|
|
2766
3066
|
var import_node_server_utils16 = require("@7365admin1/node-server-utils");
|
|
2767
|
-
var
|
|
3067
|
+
var import_core9 = require("@7365admin1/core");
|
|
2768
3068
|
var allowedChecklistStatus = ["open", "completed", "closed"];
|
|
2769
3069
|
var areaChecklistSchema = import_joi8.default.object({
|
|
2770
3070
|
schedule: import_joi8.default.string().hex().required(),
|
|
2771
|
-
serviceType: import_joi8.default.string().valid(...Object.values(
|
|
3071
|
+
serviceType: import_joi8.default.string().valid(...Object.values(import_core9.AppServiceType)).required(),
|
|
2772
3072
|
area: import_joi8.default.string().hex().required(),
|
|
2773
3073
|
name: import_joi8.default.string().required(),
|
|
2774
3074
|
type: import_joi8.default.string().valid(...allowedTypes).required(),
|
|
@@ -2842,7 +3142,7 @@ function MAreaChecklist(value) {
|
|
|
2842
3142
|
// src/services/hygiene-area-checklist.service.ts
|
|
2843
3143
|
var import_mongodb10 = require("mongodb");
|
|
2844
3144
|
var import_node_server_utils18 = require("@7365admin1/node-server-utils");
|
|
2845
|
-
var
|
|
3145
|
+
var import_core10 = require("@7365admin1/core");
|
|
2846
3146
|
|
|
2847
3147
|
// src/repositories/hygiene-area-checklist.repository.ts
|
|
2848
3148
|
var import_mongodb9 = require("mongodb");
|
|
@@ -3978,7 +4278,7 @@ function useAreaChecklistService() {
|
|
|
3978
4278
|
insertAutoGenSets
|
|
3979
4279
|
} = useAreaChecklistRepo();
|
|
3980
4280
|
const { updateParentChecklistStatuses, getParentChecklistById } = useParentChecklistRepo();
|
|
3981
|
-
const { getUserById } = (0,
|
|
4281
|
+
const { getUserById } = (0, import_core10.useUserRepo)();
|
|
3982
4282
|
async function createAreaChecklist(value) {
|
|
3983
4283
|
const results = [];
|
|
3984
4284
|
let totalChecklistsCreated = 0;
|
|
@@ -4204,7 +4504,7 @@ function useAreaChecklistService() {
|
|
|
4204
4504
|
// src/controllers/hygiene-area-checklist.controller.ts
|
|
4205
4505
|
var import_joi9 = __toESM(require("joi"));
|
|
4206
4506
|
var import_node_server_utils20 = require("@7365admin1/node-server-utils");
|
|
4207
|
-
var
|
|
4507
|
+
var import_core11 = require("@7365admin1/core");
|
|
4208
4508
|
|
|
4209
4509
|
// src/services/hygiene-checklist-pdf.service.ts
|
|
4210
4510
|
var import_puppeteer = require("puppeteer");
|
|
@@ -4471,7 +4771,7 @@ function useAreaChecklistController() {
|
|
|
4471
4771
|
type: import_joi9.default.string().valid(...allowedTypes, "all").optional().allow("", null),
|
|
4472
4772
|
status: import_joi9.default.string().valid(...allowedStatus, "all").optional().allow("", null),
|
|
4473
4773
|
schedule: import_joi9.default.string().hex().required(),
|
|
4474
|
-
serviceType: import_joi9.default.string().valid(...Object.values(
|
|
4774
|
+
serviceType: import_joi9.default.string().valid(...Object.values(import_core11.AppServiceType)).required()
|
|
4475
4775
|
});
|
|
4476
4776
|
const { error } = validation.validate(query);
|
|
4477
4777
|
if (error) {
|
|
@@ -4571,7 +4871,7 @@ function useAreaChecklistController() {
|
|
|
4571
4871
|
page: import_joi9.default.number().min(1).optional().allow("", null),
|
|
4572
4872
|
limit: import_joi9.default.number().min(1).optional().allow("", null),
|
|
4573
4873
|
search: import_joi9.default.string().optional().allow("", null),
|
|
4574
|
-
serviceType: import_joi9.default.string().valid(...Object.values(
|
|
4874
|
+
serviceType: import_joi9.default.string().valid(...Object.values(import_core11.AppServiceType)).required(),
|
|
4575
4875
|
id: import_joi9.default.string().hex().required()
|
|
4576
4876
|
});
|
|
4577
4877
|
const { error } = validation.validate(query);
|
|
@@ -4700,12 +5000,13 @@ function useAreaChecklistController() {
|
|
|
4700
5000
|
var import_joi10 = __toESM(require("joi"));
|
|
4701
5001
|
var import_mongodb12 = require("mongodb");
|
|
4702
5002
|
var import_node_server_utils21 = require("@7365admin1/node-server-utils");
|
|
4703
|
-
var
|
|
5003
|
+
var import_core12 = require("@7365admin1/core");
|
|
4704
5004
|
var supplySchema = import_joi10.default.object({
|
|
4705
5005
|
site: import_joi10.default.string().hex().required(),
|
|
4706
|
-
serviceType: import_joi10.default.string().valid(...Object.values(
|
|
5006
|
+
serviceType: import_joi10.default.string().valid(...Object.values(import_core12.AppServiceType)).required(),
|
|
4707
5007
|
name: import_joi10.default.string().required(),
|
|
4708
|
-
unitOfMeasurement: import_joi10.default.string().required()
|
|
5008
|
+
unitOfMeasurement: import_joi10.default.string().required(),
|
|
5009
|
+
attachment: import_joi10.default.string().allow(null, "").optional()
|
|
4709
5010
|
});
|
|
4710
5011
|
function MSupply(value) {
|
|
4711
5012
|
const { error } = supplySchema.validate(value);
|
|
@@ -4726,6 +5027,7 @@ function MSupply(value) {
|
|
|
4726
5027
|
name: value.name,
|
|
4727
5028
|
unitOfMeasurement: value.unitOfMeasurement,
|
|
4728
5029
|
qty: 0,
|
|
5030
|
+
attachment: value.attachment,
|
|
4729
5031
|
status: "active",
|
|
4730
5032
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4731
5033
|
updatedAt: "",
|
|
@@ -4837,6 +5139,7 @@ function useSupplyRepository() {
|
|
|
4837
5139
|
{ $match: query },
|
|
4838
5140
|
{
|
|
4839
5141
|
$project: {
|
|
5142
|
+
attachment: 1,
|
|
4840
5143
|
name: 1,
|
|
4841
5144
|
qty: 1,
|
|
4842
5145
|
status: 1
|
|
@@ -4885,6 +5188,7 @@ function useSupplyRepository() {
|
|
|
4885
5188
|
{ $match: query },
|
|
4886
5189
|
{
|
|
4887
5190
|
$project: {
|
|
5191
|
+
attachment: 1,
|
|
4888
5192
|
name: 1,
|
|
4889
5193
|
unitOfMeasurement: 1,
|
|
4890
5194
|
qty: 1
|
|
@@ -4985,7 +5289,7 @@ function useSupplyRepository() {
|
|
|
4985
5289
|
// src/controllers/hygiene-supply.controller.ts
|
|
4986
5290
|
var import_joi11 = __toESM(require("joi"));
|
|
4987
5291
|
var import_node_server_utils23 = require("@7365admin1/node-server-utils");
|
|
4988
|
-
var
|
|
5292
|
+
var import_core13 = require("@7365admin1/core");
|
|
4989
5293
|
function useSupplyController() {
|
|
4990
5294
|
const {
|
|
4991
5295
|
createSupply: _createSupply,
|
|
@@ -5019,7 +5323,7 @@ function useSupplyController() {
|
|
|
5019
5323
|
limit: import_joi11.default.number().min(1).optional().allow("", null),
|
|
5020
5324
|
search: import_joi11.default.string().optional().allow("", null),
|
|
5021
5325
|
site: import_joi11.default.string().hex().required(),
|
|
5022
|
-
serviceType: import_joi11.default.string().valid(...Object.values(
|
|
5326
|
+
serviceType: import_joi11.default.string().valid(...Object.values(import_core13.AppServiceType)).required()
|
|
5023
5327
|
});
|
|
5024
5328
|
const { error } = validation.validate(query);
|
|
5025
5329
|
if (error) {
|
|
@@ -5073,7 +5377,8 @@ function useSupplyController() {
|
|
|
5073
5377
|
id: import_joi11.default.string().hex().required(),
|
|
5074
5378
|
name: import_joi11.default.string().optional().allow("", null),
|
|
5075
5379
|
unitOfMeasurement: import_joi11.default.string().optional().allow("", null),
|
|
5076
|
-
qty: import_joi11.default.number().min(0).optional().allow("", null)
|
|
5380
|
+
qty: import_joi11.default.number().min(0).optional().allow("", null),
|
|
5381
|
+
attachment: import_joi11.default.string().optional().allow("", null)
|
|
5077
5382
|
});
|
|
5078
5383
|
const { error } = validation.validate(payload);
|
|
5079
5384
|
if (error) {
|
|
@@ -5124,10 +5429,10 @@ function useSupplyController() {
|
|
|
5124
5429
|
var import_joi12 = __toESM(require("joi"));
|
|
5125
5430
|
var import_mongodb14 = require("mongodb");
|
|
5126
5431
|
var import_node_server_utils24 = require("@7365admin1/node-server-utils");
|
|
5127
|
-
var
|
|
5432
|
+
var import_core14 = require("@7365admin1/core");
|
|
5128
5433
|
var stockSchema = import_joi12.default.object({
|
|
5129
5434
|
site: import_joi12.default.string().hex().required(),
|
|
5130
|
-
serviceType: import_joi12.default.string().valid(...Object.values(
|
|
5435
|
+
serviceType: import_joi12.default.string().valid(...Object.values(import_core14.AppServiceType)).required(),
|
|
5131
5436
|
supply: import_joi12.default.string().hex().required(),
|
|
5132
5437
|
in: import_joi12.default.number().min(0).optional(),
|
|
5133
5438
|
out: import_joi12.default.number().min(0).optional(),
|
|
@@ -5349,7 +5654,7 @@ function useStockService() {
|
|
|
5349
5654
|
// src/controllers/hygiene-stock.controller.ts
|
|
5350
5655
|
var import_joi13 = __toESM(require("joi"));
|
|
5351
5656
|
var import_node_server_utils27 = require("@7365admin1/node-server-utils");
|
|
5352
|
-
var
|
|
5657
|
+
var import_core15 = require("@7365admin1/core");
|
|
5353
5658
|
function useStockController() {
|
|
5354
5659
|
const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
|
|
5355
5660
|
const { createStock: _createStock } = useStockService();
|
|
@@ -5357,7 +5662,7 @@ function useStockController() {
|
|
|
5357
5662
|
const payload = { ...req.body, ...req.params };
|
|
5358
5663
|
const validation = import_joi13.default.object({
|
|
5359
5664
|
site: import_joi13.default.string().hex().required(),
|
|
5360
|
-
serviceType: import_joi13.default.string().valid(...Object.values(
|
|
5665
|
+
serviceType: import_joi13.default.string().valid(...Object.values(import_core15.AppServiceType)).required(),
|
|
5361
5666
|
supply: import_joi13.default.string().hex().required(),
|
|
5362
5667
|
qty: import_joi13.default.number().min(0).required(),
|
|
5363
5668
|
remarks: import_joi13.default.string().optional().allow("", null)
|
|
@@ -5385,7 +5690,7 @@ function useStockController() {
|
|
|
5385
5690
|
limit: import_joi13.default.number().min(1).optional().allow("", null),
|
|
5386
5691
|
search: import_joi13.default.string().optional().allow("", null),
|
|
5387
5692
|
site: import_joi13.default.string().hex().required(),
|
|
5388
|
-
serviceType: import_joi13.default.string().valid(...Object.values(
|
|
5693
|
+
serviceType: import_joi13.default.string().valid(...Object.values(import_core15.AppServiceType)).required(),
|
|
5389
5694
|
supply: import_joi13.default.string().hex().required()
|
|
5390
5695
|
});
|
|
5391
5696
|
const { error } = validation.validate(query);
|
|
@@ -5427,11 +5732,11 @@ function useStockController() {
|
|
|
5427
5732
|
var import_joi14 = __toESM(require("joi"));
|
|
5428
5733
|
var import_mongodb16 = require("mongodb");
|
|
5429
5734
|
var import_node_server_utils28 = require("@7365admin1/node-server-utils");
|
|
5430
|
-
var
|
|
5735
|
+
var import_core16 = require("@7365admin1/core");
|
|
5431
5736
|
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
5432
5737
|
var checkOutItemSchema = import_joi14.default.object({
|
|
5433
5738
|
site: import_joi14.default.string().hex().required(),
|
|
5434
|
-
serviceType: import_joi14.default.string().valid(...Object.values(
|
|
5739
|
+
serviceType: import_joi14.default.string().valid(...Object.values(import_core16.AppServiceType)).required(),
|
|
5435
5740
|
supply: import_joi14.default.string().hex().required(),
|
|
5436
5741
|
supplyName: import_joi14.default.string().required(),
|
|
5437
5742
|
qty: import_joi14.default.number().min(0).required(),
|
|
@@ -5752,7 +6057,7 @@ function useCheckOutItemRepository() {
|
|
|
5752
6057
|
}
|
|
5753
6058
|
|
|
5754
6059
|
// src/services/hygiene-checkout-item.service.ts
|
|
5755
|
-
var
|
|
6060
|
+
var import_core17 = require("@7365admin1/core");
|
|
5756
6061
|
var import_node_server_utils30 = require("@7365admin1/node-server-utils");
|
|
5757
6062
|
function useCheckOutItemService() {
|
|
5758
6063
|
const {
|
|
@@ -5761,7 +6066,7 @@ function useCheckOutItemService() {
|
|
|
5761
6066
|
completeCheckOutItem
|
|
5762
6067
|
} = useCheckOutItemRepository();
|
|
5763
6068
|
const { getSupplyById } = useSupplyRepository();
|
|
5764
|
-
const { getUserById } = (0,
|
|
6069
|
+
const { getUserById } = (0, import_core17.useUserRepo)();
|
|
5765
6070
|
const { createStock } = useStockService();
|
|
5766
6071
|
async function createCheckOutItem(value) {
|
|
5767
6072
|
const session = import_node_server_utils30.useAtlas.getClient()?.startSession();
|
|
@@ -5856,7 +6161,7 @@ function useCheckOutItemService() {
|
|
|
5856
6161
|
// src/controllers/hygiene-checkout-item.controller.ts
|
|
5857
6162
|
var import_joi15 = __toESM(require("joi"));
|
|
5858
6163
|
var import_node_server_utils31 = require("@7365admin1/node-server-utils");
|
|
5859
|
-
var
|
|
6164
|
+
var import_core18 = require("@7365admin1/core");
|
|
5860
6165
|
function useCheckOutItemController() {
|
|
5861
6166
|
const {
|
|
5862
6167
|
getCheckOutItems: _getCheckOutItems,
|
|
@@ -5879,7 +6184,7 @@ function useCheckOutItemController() {
|
|
|
5879
6184
|
};
|
|
5880
6185
|
const validation = import_joi15.default.object({
|
|
5881
6186
|
site: import_joi15.default.string().hex().required(),
|
|
5882
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6187
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required(),
|
|
5883
6188
|
supply: import_joi15.default.string().hex().required(),
|
|
5884
6189
|
qty: import_joi15.default.number().min(0).required(),
|
|
5885
6190
|
attachment: import_joi15.default.array().items(import_joi15.default.string()).optional().allow(null),
|
|
@@ -5914,7 +6219,7 @@ function useCheckOutItemController() {
|
|
|
5914
6219
|
};
|
|
5915
6220
|
const validation = import_joi15.default.object({
|
|
5916
6221
|
site: import_joi15.default.string().hex().required(),
|
|
5917
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6222
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required(),
|
|
5918
6223
|
createdBy: import_joi15.default.string().hex().required(),
|
|
5919
6224
|
items: import_joi15.default.array().items(
|
|
5920
6225
|
import_joi15.default.object({
|
|
@@ -5947,7 +6252,7 @@ function useCheckOutItemController() {
|
|
|
5947
6252
|
limit: import_joi15.default.number().min(1).optional().allow("", null),
|
|
5948
6253
|
search: import_joi15.default.string().optional().allow("", null),
|
|
5949
6254
|
site: import_joi15.default.string().hex().required(),
|
|
5950
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6255
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required()
|
|
5951
6256
|
});
|
|
5952
6257
|
const { error } = validation.validate(query);
|
|
5953
6258
|
if (error) {
|
|
@@ -6005,12 +6310,12 @@ function useCheckOutItemController() {
|
|
|
6005
6310
|
|
|
6006
6311
|
// src/models/hygiene-schedule-task.model.ts
|
|
6007
6312
|
var import_node_server_utils32 = require("@7365admin1/node-server-utils");
|
|
6008
|
-
var
|
|
6313
|
+
var import_core19 = require("@7365admin1/core");
|
|
6009
6314
|
var import_joi16 = __toESM(require("joi"));
|
|
6010
6315
|
var import_mongodb18 = require("mongodb");
|
|
6011
6316
|
var scheduleTaskSchema = import_joi16.default.object({
|
|
6012
6317
|
site: import_joi16.default.string().hex().required(),
|
|
6013
|
-
serviceType: import_joi16.default.string().valid(...Object.values(
|
|
6318
|
+
serviceType: import_joi16.default.string().valid(...Object.values(import_core19.AppServiceType)).required(),
|
|
6014
6319
|
title: import_joi16.default.string().required(),
|
|
6015
6320
|
time: import_joi16.default.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
|
|
6016
6321
|
dates: import_joi16.default.array().min(1).items(
|
|
@@ -6616,7 +6921,7 @@ function useScheduleTaskService() {
|
|
|
6616
6921
|
// src/controllers/hygiene-schedule-task.controller.ts
|
|
6617
6922
|
var import_joi17 = __toESM(require("joi"));
|
|
6618
6923
|
var import_node_server_utils35 = require("@7365admin1/node-server-utils");
|
|
6619
|
-
var
|
|
6924
|
+
var import_core20 = require("@7365admin1/core");
|
|
6620
6925
|
function useScheduleTaskController() {
|
|
6621
6926
|
const {
|
|
6622
6927
|
createScheduleTask: _createScheduleTask,
|
|
@@ -6650,7 +6955,7 @@ function useScheduleTaskController() {
|
|
|
6650
6955
|
limit: import_joi17.default.number().min(1).optional().allow("", null),
|
|
6651
6956
|
search: import_joi17.default.string().optional().allow("", null),
|
|
6652
6957
|
site: import_joi17.default.string().hex().required(),
|
|
6653
|
-
serviceType: import_joi17.default.string().valid(...Object.values(
|
|
6958
|
+
serviceType: import_joi17.default.string().valid(...Object.values(import_core20.AppServiceType)).required()
|
|
6654
6959
|
});
|
|
6655
6960
|
const { error } = validation.validate(query);
|
|
6656
6961
|
if (error) {
|