@7365admin1/module-hygiene 4.20.0 → 4.22.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 +30 -8
- package/dist/index.js +729 -393
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +744 -407
- 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
|
-
{ $
|
|
400
|
-
|
|
401
|
-
scheduleTaskCollection.aggregate([
|
|
402
|
-
{ $match: yesterDayQueries.scheduleTask },
|
|
403
|
-
{ $count: "count" }
|
|
511
|
+
{ $skip: page * limit },
|
|
512
|
+
{ $limit: limit }
|
|
404
513
|
]).toArray(),
|
|
405
|
-
|
|
406
|
-
|
|
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);
|
|
@@ -2243,7 +2550,7 @@ function MParentChecklist(value) {
|
|
|
2243
2550
|
// src/repositories/hygiene-parent-checklist.repository.ts
|
|
2244
2551
|
var import_mongodb7 = require("mongodb");
|
|
2245
2552
|
var import_node_server_utils14 = require("@7365admin1/node-server-utils");
|
|
2246
|
-
var
|
|
2553
|
+
var import_core7 = require("@7365admin1/core");
|
|
2247
2554
|
function useParentChecklistRepo() {
|
|
2248
2555
|
const db = import_node_server_utils14.useAtlas.getDb();
|
|
2249
2556
|
if (!db) {
|
|
@@ -2275,7 +2582,7 @@ function useParentChecklistRepo() {
|
|
|
2275
2582
|
startOfDay.setUTCHours(0, 0, 0, 0);
|
|
2276
2583
|
const endOfDay = new Date(currentDate);
|
|
2277
2584
|
endOfDay.setUTCHours(23, 59, 59, 999);
|
|
2278
|
-
const allServiceTypes = Object.values(
|
|
2585
|
+
const allServiceTypes = Object.values(import_core7.AppServiceType);
|
|
2279
2586
|
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2280
2587
|
if (value.site) {
|
|
2281
2588
|
let siteObjectId;
|
|
@@ -2680,7 +2987,7 @@ function useParentChecklistRepo() {
|
|
|
2680
2987
|
// src/controllers/hygiene-parent-checklist.controller.ts
|
|
2681
2988
|
var import_joi7 = __toESM(require("joi"));
|
|
2682
2989
|
var import_node_server_utils15 = require("@7365admin1/node-server-utils");
|
|
2683
|
-
var
|
|
2990
|
+
var import_core8 = require("@7365admin1/core");
|
|
2684
2991
|
function useParentChecklistController() {
|
|
2685
2992
|
const {
|
|
2686
2993
|
createParentChecklist: _createParentChecklist,
|
|
@@ -2691,7 +2998,7 @@ function useParentChecklistController() {
|
|
|
2691
2998
|
const validation = import_joi7.default.object({
|
|
2692
2999
|
createdAt: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2693
3000
|
site: import_joi7.default.string().hex().required(),
|
|
2694
|
-
serviceType: import_joi7.default.string().valid(...Object.values(
|
|
3001
|
+
serviceType: import_joi7.default.string().valid(...Object.values(import_core8.AppServiceType)).optional().allow("", null)
|
|
2695
3002
|
});
|
|
2696
3003
|
const { error } = validation.validate(payload);
|
|
2697
3004
|
if (error) {
|
|
@@ -2716,7 +3023,7 @@ function useParentChecklistController() {
|
|
|
2716
3023
|
limit: import_joi7.default.number().min(1).optional().allow("", null),
|
|
2717
3024
|
search: import_joi7.default.string().optional().allow("", null),
|
|
2718
3025
|
site: import_joi7.default.string().hex().required(),
|
|
2719
|
-
serviceType: import_joi7.default.string().valid(...Object.values(
|
|
3026
|
+
serviceType: import_joi7.default.string().valid(...Object.values(import_core8.AppServiceType)).required(),
|
|
2720
3027
|
startDate: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2721
3028
|
endDate: import_joi7.default.alternatives().try(import_joi7.default.date(), import_joi7.default.string()).optional().allow("", null),
|
|
2722
3029
|
status: import_joi7.default.string().valid(...allowedStatus, "all").optional().allow("", null)
|
|
@@ -2764,11 +3071,11 @@ function useParentChecklistController() {
|
|
|
2764
3071
|
var import_joi8 = __toESM(require("joi"));
|
|
2765
3072
|
var import_mongodb8 = require("mongodb");
|
|
2766
3073
|
var import_node_server_utils16 = require("@7365admin1/node-server-utils");
|
|
2767
|
-
var
|
|
3074
|
+
var import_core9 = require("@7365admin1/core");
|
|
2768
3075
|
var allowedChecklistStatus = ["open", "completed", "closed"];
|
|
2769
3076
|
var areaChecklistSchema = import_joi8.default.object({
|
|
2770
3077
|
schedule: import_joi8.default.string().hex().required(),
|
|
2771
|
-
serviceType: import_joi8.default.string().valid(...Object.values(
|
|
3078
|
+
serviceType: import_joi8.default.string().valid(...Object.values(import_core9.AppServiceType)).required(),
|
|
2772
3079
|
area: import_joi8.default.string().hex().required(),
|
|
2773
3080
|
name: import_joi8.default.string().required(),
|
|
2774
3081
|
type: import_joi8.default.string().valid(...allowedTypes).required(),
|
|
@@ -2842,7 +3149,7 @@ function MAreaChecklist(value) {
|
|
|
2842
3149
|
// src/services/hygiene-area-checklist.service.ts
|
|
2843
3150
|
var import_mongodb10 = require("mongodb");
|
|
2844
3151
|
var import_node_server_utils18 = require("@7365admin1/node-server-utils");
|
|
2845
|
-
var
|
|
3152
|
+
var import_core10 = require("@7365admin1/core");
|
|
2846
3153
|
|
|
2847
3154
|
// src/repositories/hygiene-area-checklist.repository.ts
|
|
2848
3155
|
var import_mongodb9 = require("mongodb");
|
|
@@ -3978,7 +4285,7 @@ function useAreaChecklistService() {
|
|
|
3978
4285
|
insertAutoGenSets
|
|
3979
4286
|
} = useAreaChecklistRepo();
|
|
3980
4287
|
const { updateParentChecklistStatuses, getParentChecklistById } = useParentChecklistRepo();
|
|
3981
|
-
const { getUserById } = (0,
|
|
4288
|
+
const { getUserById } = (0, import_core10.useUserRepo)();
|
|
3982
4289
|
async function createAreaChecklist(value) {
|
|
3983
4290
|
const results = [];
|
|
3984
4291
|
let totalChecklistsCreated = 0;
|
|
@@ -4204,7 +4511,7 @@ function useAreaChecklistService() {
|
|
|
4204
4511
|
// src/controllers/hygiene-area-checklist.controller.ts
|
|
4205
4512
|
var import_joi9 = __toESM(require("joi"));
|
|
4206
4513
|
var import_node_server_utils20 = require("@7365admin1/node-server-utils");
|
|
4207
|
-
var
|
|
4514
|
+
var import_core11 = require("@7365admin1/core");
|
|
4208
4515
|
|
|
4209
4516
|
// src/services/hygiene-checklist-pdf.service.ts
|
|
4210
4517
|
var import_puppeteer = require("puppeteer");
|
|
@@ -4471,7 +4778,7 @@ function useAreaChecklistController() {
|
|
|
4471
4778
|
type: import_joi9.default.string().valid(...allowedTypes, "all").optional().allow("", null),
|
|
4472
4779
|
status: import_joi9.default.string().valid(...allowedStatus, "all").optional().allow("", null),
|
|
4473
4780
|
schedule: import_joi9.default.string().hex().required(),
|
|
4474
|
-
serviceType: import_joi9.default.string().valid(...Object.values(
|
|
4781
|
+
serviceType: import_joi9.default.string().valid(...Object.values(import_core11.AppServiceType)).required()
|
|
4475
4782
|
});
|
|
4476
4783
|
const { error } = validation.validate(query);
|
|
4477
4784
|
if (error) {
|
|
@@ -4571,7 +4878,7 @@ function useAreaChecklistController() {
|
|
|
4571
4878
|
page: import_joi9.default.number().min(1).optional().allow("", null),
|
|
4572
4879
|
limit: import_joi9.default.number().min(1).optional().allow("", null),
|
|
4573
4880
|
search: import_joi9.default.string().optional().allow("", null),
|
|
4574
|
-
serviceType: import_joi9.default.string().valid(...Object.values(
|
|
4881
|
+
serviceType: import_joi9.default.string().valid(...Object.values(import_core11.AppServiceType)).required(),
|
|
4575
4882
|
id: import_joi9.default.string().hex().required()
|
|
4576
4883
|
});
|
|
4577
4884
|
const { error } = validation.validate(query);
|
|
@@ -4700,10 +5007,10 @@ function useAreaChecklistController() {
|
|
|
4700
5007
|
var import_joi10 = __toESM(require("joi"));
|
|
4701
5008
|
var import_mongodb12 = require("mongodb");
|
|
4702
5009
|
var import_node_server_utils21 = require("@7365admin1/node-server-utils");
|
|
4703
|
-
var
|
|
5010
|
+
var import_core12 = require("@7365admin1/core");
|
|
4704
5011
|
var supplySchema = import_joi10.default.object({
|
|
4705
5012
|
site: import_joi10.default.string().hex().required(),
|
|
4706
|
-
serviceType: import_joi10.default.string().valid(...Object.values(
|
|
5013
|
+
serviceType: import_joi10.default.string().valid(...Object.values(import_core12.AppServiceType)).required(),
|
|
4707
5014
|
name: import_joi10.default.string().required(),
|
|
4708
5015
|
unitOfMeasurement: import_joi10.default.string().required()
|
|
4709
5016
|
});
|
|
@@ -4985,7 +5292,7 @@ function useSupplyRepository() {
|
|
|
4985
5292
|
// src/controllers/hygiene-supply.controller.ts
|
|
4986
5293
|
var import_joi11 = __toESM(require("joi"));
|
|
4987
5294
|
var import_node_server_utils23 = require("@7365admin1/node-server-utils");
|
|
4988
|
-
var
|
|
5295
|
+
var import_core13 = require("@7365admin1/core");
|
|
4989
5296
|
function useSupplyController() {
|
|
4990
5297
|
const {
|
|
4991
5298
|
createSupply: _createSupply,
|
|
@@ -5019,7 +5326,7 @@ function useSupplyController() {
|
|
|
5019
5326
|
limit: import_joi11.default.number().min(1).optional().allow("", null),
|
|
5020
5327
|
search: import_joi11.default.string().optional().allow("", null),
|
|
5021
5328
|
site: import_joi11.default.string().hex().required(),
|
|
5022
|
-
serviceType: import_joi11.default.string().valid(...Object.values(
|
|
5329
|
+
serviceType: import_joi11.default.string().valid(...Object.values(import_core13.AppServiceType)).required()
|
|
5023
5330
|
});
|
|
5024
5331
|
const { error } = validation.validate(query);
|
|
5025
5332
|
if (error) {
|
|
@@ -5124,10 +5431,10 @@ function useSupplyController() {
|
|
|
5124
5431
|
var import_joi12 = __toESM(require("joi"));
|
|
5125
5432
|
var import_mongodb14 = require("mongodb");
|
|
5126
5433
|
var import_node_server_utils24 = require("@7365admin1/node-server-utils");
|
|
5127
|
-
var
|
|
5434
|
+
var import_core14 = require("@7365admin1/core");
|
|
5128
5435
|
var stockSchema = import_joi12.default.object({
|
|
5129
5436
|
site: import_joi12.default.string().hex().required(),
|
|
5130
|
-
serviceType: import_joi12.default.string().valid(...Object.values(
|
|
5437
|
+
serviceType: import_joi12.default.string().valid(...Object.values(import_core14.AppServiceType)).required(),
|
|
5131
5438
|
supply: import_joi12.default.string().hex().required(),
|
|
5132
5439
|
in: import_joi12.default.number().min(0).optional(),
|
|
5133
5440
|
out: import_joi12.default.number().min(0).optional(),
|
|
@@ -5349,7 +5656,7 @@ function useStockService() {
|
|
|
5349
5656
|
// src/controllers/hygiene-stock.controller.ts
|
|
5350
5657
|
var import_joi13 = __toESM(require("joi"));
|
|
5351
5658
|
var import_node_server_utils27 = require("@7365admin1/node-server-utils");
|
|
5352
|
-
var
|
|
5659
|
+
var import_core15 = require("@7365admin1/core");
|
|
5353
5660
|
function useStockController() {
|
|
5354
5661
|
const { getStocksBySupplyId: _getStocksBySupplyId } = useStockRepository();
|
|
5355
5662
|
const { createStock: _createStock } = useStockService();
|
|
@@ -5357,7 +5664,7 @@ function useStockController() {
|
|
|
5357
5664
|
const payload = { ...req.body, ...req.params };
|
|
5358
5665
|
const validation = import_joi13.default.object({
|
|
5359
5666
|
site: import_joi13.default.string().hex().required(),
|
|
5360
|
-
serviceType: import_joi13.default.string().valid(...Object.values(
|
|
5667
|
+
serviceType: import_joi13.default.string().valid(...Object.values(import_core15.AppServiceType)).required(),
|
|
5361
5668
|
supply: import_joi13.default.string().hex().required(),
|
|
5362
5669
|
qty: import_joi13.default.number().min(0).required(),
|
|
5363
5670
|
remarks: import_joi13.default.string().optional().allow("", null)
|
|
@@ -5385,7 +5692,7 @@ function useStockController() {
|
|
|
5385
5692
|
limit: import_joi13.default.number().min(1).optional().allow("", null),
|
|
5386
5693
|
search: import_joi13.default.string().optional().allow("", null),
|
|
5387
5694
|
site: import_joi13.default.string().hex().required(),
|
|
5388
|
-
serviceType: import_joi13.default.string().valid(...Object.values(
|
|
5695
|
+
serviceType: import_joi13.default.string().valid(...Object.values(import_core15.AppServiceType)).required(),
|
|
5389
5696
|
supply: import_joi13.default.string().hex().required()
|
|
5390
5697
|
});
|
|
5391
5698
|
const { error } = validation.validate(query);
|
|
@@ -5427,11 +5734,11 @@ function useStockController() {
|
|
|
5427
5734
|
var import_joi14 = __toESM(require("joi"));
|
|
5428
5735
|
var import_mongodb16 = require("mongodb");
|
|
5429
5736
|
var import_node_server_utils28 = require("@7365admin1/node-server-utils");
|
|
5430
|
-
var
|
|
5737
|
+
var import_core16 = require("@7365admin1/core");
|
|
5431
5738
|
var allowedCheckOutItemStatus = ["pending", "completed"];
|
|
5432
5739
|
var checkOutItemSchema = import_joi14.default.object({
|
|
5433
5740
|
site: import_joi14.default.string().hex().required(),
|
|
5434
|
-
serviceType: import_joi14.default.string().valid(...Object.values(
|
|
5741
|
+
serviceType: import_joi14.default.string().valid(...Object.values(import_core16.AppServiceType)).required(),
|
|
5435
5742
|
supply: import_joi14.default.string().hex().required(),
|
|
5436
5743
|
supplyName: import_joi14.default.string().required(),
|
|
5437
5744
|
qty: import_joi14.default.number().min(0).required(),
|
|
@@ -5492,6 +5799,7 @@ function useCheckOutItemRepository() {
|
|
|
5492
5799
|
{ key: { site: 1 } },
|
|
5493
5800
|
{ key: { serviceType: 1 } },
|
|
5494
5801
|
{ key: { supply: 1 } },
|
|
5802
|
+
{ key: { createdBy: 1 } },
|
|
5495
5803
|
{ key: { status: 1 } }
|
|
5496
5804
|
]);
|
|
5497
5805
|
} catch (error) {
|
|
@@ -5523,7 +5831,11 @@ function useCheckOutItemRepository() {
|
|
|
5523
5831
|
});
|
|
5524
5832
|
return res.insertedId;
|
|
5525
5833
|
} catch (error) {
|
|
5526
|
-
|
|
5834
|
+
if (error.code === 11e3) {
|
|
5835
|
+
throw "The Item is already exisits";
|
|
5836
|
+
} else {
|
|
5837
|
+
throw error;
|
|
5838
|
+
}
|
|
5527
5839
|
}
|
|
5528
5840
|
}
|
|
5529
5841
|
async function getCheckOutItems({
|
|
@@ -5589,11 +5901,35 @@ function useCheckOutItemRepository() {
|
|
|
5589
5901
|
preserveNullAndEmptyArrays: true
|
|
5590
5902
|
}
|
|
5591
5903
|
},
|
|
5904
|
+
{
|
|
5905
|
+
$lookup: {
|
|
5906
|
+
from: "users",
|
|
5907
|
+
let: { createdByStr: "$createdBy" },
|
|
5908
|
+
pipeline: [
|
|
5909
|
+
{
|
|
5910
|
+
$match: {
|
|
5911
|
+
$expr: {
|
|
5912
|
+
$eq: [{ $toString: "$_id" }, "$$createdByStr"]
|
|
5913
|
+
}
|
|
5914
|
+
}
|
|
5915
|
+
},
|
|
5916
|
+
{ $project: { profile: 1 } }
|
|
5917
|
+
],
|
|
5918
|
+
as: "createdByDoc"
|
|
5919
|
+
}
|
|
5920
|
+
},
|
|
5921
|
+
{
|
|
5922
|
+
$unwind: {
|
|
5923
|
+
path: "$createdByDoc",
|
|
5924
|
+
preserveNullAndEmptyArrays: true
|
|
5925
|
+
}
|
|
5926
|
+
},
|
|
5592
5927
|
{
|
|
5593
5928
|
$project: {
|
|
5594
5929
|
supplyName: 1,
|
|
5595
5930
|
supplyQty: "$supplyDoc.qty",
|
|
5596
5931
|
checkOutByName: "$createdByName",
|
|
5932
|
+
profile: "$createdByDoc.profile",
|
|
5597
5933
|
checkOutQty: "$qty",
|
|
5598
5934
|
createdAt: 1,
|
|
5599
5935
|
status: 1
|
|
@@ -5723,7 +6059,7 @@ function useCheckOutItemRepository() {
|
|
|
5723
6059
|
}
|
|
5724
6060
|
|
|
5725
6061
|
// src/services/hygiene-checkout-item.service.ts
|
|
5726
|
-
var
|
|
6062
|
+
var import_core17 = require("@7365admin1/core");
|
|
5727
6063
|
var import_node_server_utils30 = require("@7365admin1/node-server-utils");
|
|
5728
6064
|
function useCheckOutItemService() {
|
|
5729
6065
|
const {
|
|
@@ -5732,7 +6068,7 @@ function useCheckOutItemService() {
|
|
|
5732
6068
|
completeCheckOutItem
|
|
5733
6069
|
} = useCheckOutItemRepository();
|
|
5734
6070
|
const { getSupplyById } = useSupplyRepository();
|
|
5735
|
-
const { getUserById } = (0,
|
|
6071
|
+
const { getUserById } = (0, import_core17.useUserRepo)();
|
|
5736
6072
|
const { createStock } = useStockService();
|
|
5737
6073
|
async function createCheckOutItem(value) {
|
|
5738
6074
|
const session = import_node_server_utils30.useAtlas.getClient()?.startSession();
|
|
@@ -5827,7 +6163,7 @@ function useCheckOutItemService() {
|
|
|
5827
6163
|
// src/controllers/hygiene-checkout-item.controller.ts
|
|
5828
6164
|
var import_joi15 = __toESM(require("joi"));
|
|
5829
6165
|
var import_node_server_utils31 = require("@7365admin1/node-server-utils");
|
|
5830
|
-
var
|
|
6166
|
+
var import_core18 = require("@7365admin1/core");
|
|
5831
6167
|
function useCheckOutItemController() {
|
|
5832
6168
|
const {
|
|
5833
6169
|
getCheckOutItems: _getCheckOutItems,
|
|
@@ -5850,7 +6186,7 @@ function useCheckOutItemController() {
|
|
|
5850
6186
|
};
|
|
5851
6187
|
const validation = import_joi15.default.object({
|
|
5852
6188
|
site: import_joi15.default.string().hex().required(),
|
|
5853
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6189
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required(),
|
|
5854
6190
|
supply: import_joi15.default.string().hex().required(),
|
|
5855
6191
|
qty: import_joi15.default.number().min(0).required(),
|
|
5856
6192
|
attachment: import_joi15.default.array().items(import_joi15.default.string()).optional().allow(null),
|
|
@@ -5885,7 +6221,7 @@ function useCheckOutItemController() {
|
|
|
5885
6221
|
};
|
|
5886
6222
|
const validation = import_joi15.default.object({
|
|
5887
6223
|
site: import_joi15.default.string().hex().required(),
|
|
5888
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6224
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required(),
|
|
5889
6225
|
createdBy: import_joi15.default.string().hex().required(),
|
|
5890
6226
|
items: import_joi15.default.array().items(
|
|
5891
6227
|
import_joi15.default.object({
|
|
@@ -5918,7 +6254,7 @@ function useCheckOutItemController() {
|
|
|
5918
6254
|
limit: import_joi15.default.number().min(1).optional().allow("", null),
|
|
5919
6255
|
search: import_joi15.default.string().optional().allow("", null),
|
|
5920
6256
|
site: import_joi15.default.string().hex().required(),
|
|
5921
|
-
serviceType: import_joi15.default.string().valid(...Object.values(
|
|
6257
|
+
serviceType: import_joi15.default.string().valid(...Object.values(import_core18.AppServiceType)).required()
|
|
5922
6258
|
});
|
|
5923
6259
|
const { error } = validation.validate(query);
|
|
5924
6260
|
if (error) {
|
|
@@ -5976,12 +6312,12 @@ function useCheckOutItemController() {
|
|
|
5976
6312
|
|
|
5977
6313
|
// src/models/hygiene-schedule-task.model.ts
|
|
5978
6314
|
var import_node_server_utils32 = require("@7365admin1/node-server-utils");
|
|
5979
|
-
var
|
|
6315
|
+
var import_core19 = require("@7365admin1/core");
|
|
5980
6316
|
var import_joi16 = __toESM(require("joi"));
|
|
5981
6317
|
var import_mongodb18 = require("mongodb");
|
|
5982
6318
|
var scheduleTaskSchema = import_joi16.default.object({
|
|
5983
6319
|
site: import_joi16.default.string().hex().required(),
|
|
5984
|
-
serviceType: import_joi16.default.string().valid(...Object.values(
|
|
6320
|
+
serviceType: import_joi16.default.string().valid(...Object.values(import_core19.AppServiceType)).required(),
|
|
5985
6321
|
title: import_joi16.default.string().required(),
|
|
5986
6322
|
time: import_joi16.default.string().pattern(/^([0-1]\d|2[0-3]):([0-5]\d)$/).required(),
|
|
5987
6323
|
dates: import_joi16.default.array().min(1).items(
|
|
@@ -6587,7 +6923,7 @@ function useScheduleTaskService() {
|
|
|
6587
6923
|
// src/controllers/hygiene-schedule-task.controller.ts
|
|
6588
6924
|
var import_joi17 = __toESM(require("joi"));
|
|
6589
6925
|
var import_node_server_utils35 = require("@7365admin1/node-server-utils");
|
|
6590
|
-
var
|
|
6926
|
+
var import_core20 = require("@7365admin1/core");
|
|
6591
6927
|
function useScheduleTaskController() {
|
|
6592
6928
|
const {
|
|
6593
6929
|
createScheduleTask: _createScheduleTask,
|
|
@@ -6621,7 +6957,7 @@ function useScheduleTaskController() {
|
|
|
6621
6957
|
limit: import_joi17.default.number().min(1).optional().allow("", null),
|
|
6622
6958
|
search: import_joi17.default.string().optional().allow("", null),
|
|
6623
6959
|
site: import_joi17.default.string().hex().required(),
|
|
6624
|
-
serviceType: import_joi17.default.string().valid(...Object.values(
|
|
6960
|
+
serviceType: import_joi17.default.string().valid(...Object.values(import_core20.AppServiceType)).required()
|
|
6625
6961
|
});
|
|
6626
6962
|
const { error } = validation.validate(query);
|
|
6627
6963
|
if (error) {
|