@7365admin1/module-hygiene 4.28.1-staging.6 → 4.28.1-staging.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +144 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +144 -128
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
- package/test/hygiene-dashboard-metrics.util.test.mjs +146 -0
package/dist/index.js
CHANGED
|
@@ -93,9 +93,57 @@ var allowedStatus = [
|
|
|
93
93
|
var allowedPeriods = ["today", "thisWeek", "thisMonth"];
|
|
94
94
|
|
|
95
95
|
// src/repositories/hygiene-dashboard.repository.ts
|
|
96
|
-
var
|
|
96
|
+
var import_moment_timezone2 = __toESM(require("moment-timezone"));
|
|
97
97
|
var import_mongodb = require("mongodb");
|
|
98
98
|
var import_node_server_utils = require("@7365admin1/node-server-utils");
|
|
99
|
+
|
|
100
|
+
// src/utils/hygiene-dashboard-metrics.util.ts
|
|
101
|
+
var import_moment_timezone = __toESM(require("moment-timezone"));
|
|
102
|
+
var DASHBOARD_TIMEZONE = "Asia/Singapore";
|
|
103
|
+
var PERIOD_UNITS = {
|
|
104
|
+
thisWeek: { boundary: "isoWeek", step: "week" },
|
|
105
|
+
thisMonth: { boundary: "month", step: "month" }
|
|
106
|
+
};
|
|
107
|
+
var DAY_UNIT = {
|
|
108
|
+
boundary: "day",
|
|
109
|
+
step: "day"
|
|
110
|
+
};
|
|
111
|
+
function unitsOf(period) {
|
|
112
|
+
return PERIOD_UNITS[period] ?? DAY_UNIT;
|
|
113
|
+
}
|
|
114
|
+
function at(now) {
|
|
115
|
+
return now === void 0 || now === null ? import_moment_timezone.default.tz(DASHBOARD_TIMEZONE) : import_moment_timezone.default.tz(now, DASHBOARD_TIMEZONE);
|
|
116
|
+
}
|
|
117
|
+
function getPeriodRange(period, now) {
|
|
118
|
+
const { boundary } = unitsOf(period);
|
|
119
|
+
const point = at(now);
|
|
120
|
+
return {
|
|
121
|
+
$gte: point.clone().startOf(boundary).toDate(),
|
|
122
|
+
$lte: point.clone().endOf(boundary).toDate()
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function getPreviousPeriodRange(period, now) {
|
|
126
|
+
const { boundary, step } = unitsOf(period);
|
|
127
|
+
const point = at(now).subtract(1, step);
|
|
128
|
+
return {
|
|
129
|
+
$gte: point.clone().startOf(boundary).toDate(),
|
|
130
|
+
$lte: point.clone().endOf(boundary).toDate()
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function calculatePercentageChange(currentCount, previousCount) {
|
|
134
|
+
if (typeof currentCount !== "number" || !Number.isFinite(currentCount)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if (typeof previousCount !== "number" || !Number.isFinite(previousCount)) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
if (previousCount === 0)
|
|
141
|
+
return null;
|
|
142
|
+
return Math.round((currentCount - previousCount) / previousCount * 100 * 100) / 100;
|
|
143
|
+
}
|
|
144
|
+
var SUPPLY_ALERT_HAS_NO_PRIOR_PERIOD = "Supply alerts count what is out of stock right now, and the supply record keeps no history, so there is no earlier period to compare against.";
|
|
145
|
+
|
|
146
|
+
// src/repositories/hygiene-dashboard.repository.ts
|
|
99
147
|
function useHygieneDashboardRepository() {
|
|
100
148
|
const db = import_node_server_utils.useAtlas.getDb();
|
|
101
149
|
if (!db) {
|
|
@@ -166,59 +214,16 @@ function useHygieneDashboardRepository() {
|
|
|
166
214
|
import_node_server_utils.logger.info(`Cache hit for dashboard: ${dashboardCacheKey}`);
|
|
167
215
|
return cachedDashboard;
|
|
168
216
|
}
|
|
169
|
-
function formatEndDate(date) {
|
|
170
|
-
if (typeof date === "string") {
|
|
171
|
-
const dateWithoutTimezone = date.replace(/\s*\+\d{2}:\d{2}$/, "");
|
|
172
|
-
date = new Date(dateWithoutTimezone);
|
|
173
|
-
}
|
|
174
|
-
const singaporeMoment = import_moment_timezone.default.tz(date, "Asia/Singapore");
|
|
175
|
-
singaporeMoment.set({
|
|
176
|
-
hour: 23,
|
|
177
|
-
minute: 59,
|
|
178
|
-
second: 59,
|
|
179
|
-
millisecond: 999
|
|
180
|
-
});
|
|
181
|
-
return singaporeMoment.toDate();
|
|
182
|
-
}
|
|
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) };
|
|
188
|
-
}
|
|
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
217
|
const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
|
|
204
218
|
try {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
const yesterday = /* @__PURE__ */ new Date();
|
|
208
|
-
yesterday.setDate(today.getDate() - 1);
|
|
209
|
-
yesterday.setHours(0, 0, 0, 0);
|
|
210
|
-
const yesterdayEnd = new Date(yesterday);
|
|
211
|
-
yesterdayEnd.setHours(23, 59, 59, 999);
|
|
212
|
-
const todayEnd = formatEndDate(/* @__PURE__ */ new Date());
|
|
213
|
-
const periodRange = getDateRange(period);
|
|
219
|
+
const periodRange = getPeriodRange(period);
|
|
220
|
+
const priorPeriodRange = getPreviousPeriodRange(period);
|
|
214
221
|
const [
|
|
215
222
|
workOrderReport,
|
|
216
223
|
supplyAlertReport,
|
|
217
224
|
taskCompletedReport,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
yesterdayTaskCompletedReport,
|
|
221
|
-
todayTaskCompletedReport
|
|
225
|
+
priorWorkOrderReport,
|
|
226
|
+
priorTaskCompletedReport
|
|
222
227
|
] = await Promise.all([
|
|
223
228
|
// 1. Open work orders (period-filtered) with inProgress breakdown
|
|
224
229
|
workOrderCollection.aggregate([
|
|
@@ -262,45 +267,28 @@ function useHygieneDashboardRepository() {
|
|
|
262
267
|
}
|
|
263
268
|
}
|
|
264
269
|
]).toArray(),
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
{ $count: "count" }
|
|
276
|
-
]).toArray(),
|
|
277
|
-
// 5. Today open work orders (for % change)
|
|
270
|
+
/*
|
|
271
|
+
4. Open work orders in the PREVIOUS period (for % change).
|
|
272
|
+
|
|
273
|
+
The current side of the comparison is no longer queried separately:
|
|
274
|
+
it is now the same range as tile 1, so `wFacet.total` below IS the
|
|
275
|
+
current count. Two aggregations dropped, not by cutting a measure but
|
|
276
|
+
because the fix made them duplicates.
|
|
277
|
+
*/
|
|
278
278
|
workOrderCollection.aggregate([
|
|
279
279
|
{
|
|
280
280
|
$match: {
|
|
281
281
|
site,
|
|
282
282
|
service: workOrderService,
|
|
283
|
-
createdAt:
|
|
283
|
+
createdAt: priorPeriodRange,
|
|
284
284
|
status: { $nin: ["completed"] }
|
|
285
285
|
}
|
|
286
286
|
},
|
|
287
287
|
{ $count: "count" }
|
|
288
288
|
]).toArray(),
|
|
289
|
-
//
|
|
289
|
+
// 5. Task completed in the PREVIOUS period — area checklists (for % change)
|
|
290
290
|
areaChecklistCollection.aggregate([
|
|
291
|
-
...areaChecklistScheduleLookup(site, serviceType,
|
|
292
|
-
$gte: yesterday,
|
|
293
|
-
$lte: yesterdayEnd
|
|
294
|
-
}),
|
|
295
|
-
{ $match: { status: "completed" } },
|
|
296
|
-
{ $count: "count" }
|
|
297
|
-
]).toArray(),
|
|
298
|
-
// 7. Today task completed — area checklists (for % change)
|
|
299
|
-
areaChecklistCollection.aggregate([
|
|
300
|
-
...areaChecklistScheduleLookup(site, serviceType, {
|
|
301
|
-
$gte: today,
|
|
302
|
-
$lte: todayEnd
|
|
303
|
-
}),
|
|
291
|
+
...areaChecklistScheduleLookup(site, serviceType, priorPeriodRange),
|
|
304
292
|
{ $match: { status: "completed" } },
|
|
305
293
|
{ $count: "count" }
|
|
306
294
|
]).toArray()
|
|
@@ -316,21 +304,26 @@ function useHygieneDashboardRepository() {
|
|
|
316
304
|
count: wFacet.total[0]?.count ?? 0,
|
|
317
305
|
inProgress: wFacet.inProgress[0]?.count ?? 0,
|
|
318
306
|
percentage: calculatePercentageChange(
|
|
319
|
-
|
|
320
|
-
|
|
307
|
+
wFacet.total[0]?.count ?? 0,
|
|
308
|
+
priorWorkOrderReport[0]?.count ?? 0
|
|
321
309
|
)
|
|
322
310
|
},
|
|
323
311
|
supplyAlert: {
|
|
312
|
+
// The count is real: active supplies at qty 0 for this site and
|
|
313
|
+
// service. The percentage beside it was the literal 0 and had never
|
|
314
|
+
// been computed from anything — see the util for why there is no
|
|
315
|
+
// prior period to compute one from.
|
|
324
316
|
count: supplyAlertReport[0]?.count ?? 0,
|
|
325
|
-
percentage:
|
|
317
|
+
percentage: null,
|
|
318
|
+
percentageUnavailableReason: SUPPLY_ALERT_HAS_NO_PRIOR_PERIOD
|
|
326
319
|
},
|
|
327
320
|
taskCompleted: {
|
|
328
321
|
completed: tFacet.completed[0]?.count ?? 0,
|
|
329
322
|
total: tFacet.total[0]?.count ?? 0,
|
|
330
323
|
inProgress: tFacet.inProgress[0]?.count ?? 0,
|
|
331
324
|
percentage: calculatePercentageChange(
|
|
332
|
-
|
|
333
|
-
|
|
325
|
+
tFacet.completed[0]?.count ?? 0,
|
|
326
|
+
priorTaskCompletedReport[0]?.count ?? 0
|
|
334
327
|
)
|
|
335
328
|
}
|
|
336
329
|
};
|
|
@@ -368,8 +361,8 @@ function useHygieneDashboardRepository() {
|
|
|
368
361
|
return cachedData;
|
|
369
362
|
}
|
|
370
363
|
const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
|
|
371
|
-
const weekStart =
|
|
372
|
-
const weekEnd =
|
|
364
|
+
const weekStart = import_moment_timezone2.default.tz("Asia/Singapore").startOf("isoWeek").toDate();
|
|
365
|
+
const weekEnd = import_moment_timezone2.default.tz("Asia/Singapore").endOf("isoWeek").toDate();
|
|
373
366
|
const weekRange = { $gte: weekStart, $lte: weekEnd };
|
|
374
367
|
const dayLabels = {
|
|
375
368
|
1: "Sun",
|
|
@@ -449,8 +442,8 @@ function useHygieneDashboardRepository() {
|
|
|
449
442
|
import_node_server_utils.logger.info(`Cache hit for todayTaskSchedule: ${cacheKey}`);
|
|
450
443
|
return cachedData;
|
|
451
444
|
}
|
|
452
|
-
const todayStart =
|
|
453
|
-
const todayEnd =
|
|
445
|
+
const todayStart = import_moment_timezone2.default.tz("Asia/Singapore").startOf("day").toDate();
|
|
446
|
+
const todayEnd = import_moment_timezone2.default.tz("Asia/Singapore").endOf("day").toDate();
|
|
454
447
|
const todayRange = { $gte: todayStart, $lte: todayEnd };
|
|
455
448
|
try {
|
|
456
449
|
const [items, countResult] = await Promise.all([
|
|
@@ -554,8 +547,8 @@ function useHygieneDashboardRepository() {
|
|
|
554
547
|
import_node_server_utils.logger.info(`Cache hit for staffAttendance: ${cacheKey}`);
|
|
555
548
|
return cachedData;
|
|
556
549
|
}
|
|
557
|
-
const todayStart =
|
|
558
|
-
const todayEnd =
|
|
550
|
+
const todayStart = import_moment_timezone2.default.tz("Asia/Singapore").startOf("day").toDate();
|
|
551
|
+
const todayEnd = import_moment_timezone2.default.tz("Asia/Singapore").endOf("day").toDate();
|
|
559
552
|
const todayStartStr = todayStart.toISOString();
|
|
560
553
|
const todayEndStr = todayEnd.toISOString();
|
|
561
554
|
try {
|
|
@@ -1663,7 +1656,7 @@ function useUnitRepository() {
|
|
|
1663
1656
|
function useAreaService() {
|
|
1664
1657
|
const { createArea: _createArea, getAreasForChecklist } = useAreaRepo();
|
|
1665
1658
|
const { generateAreaExcel } = useAreaExportService();
|
|
1666
|
-
const { getUnits: _getUnits } = useUnitRepository();
|
|
1659
|
+
const { createUnit: _createUnit, getUnits: _getUnits } = useUnitRepository();
|
|
1667
1660
|
async function importArea({
|
|
1668
1661
|
dataJson,
|
|
1669
1662
|
site,
|
|
@@ -1745,23 +1738,40 @@ function useAreaService() {
|
|
|
1745
1738
|
areaData.set = setNumber;
|
|
1746
1739
|
}
|
|
1747
1740
|
}
|
|
1748
|
-
if (row.UNITS
|
|
1741
|
+
if (row.UNITS) {
|
|
1749
1742
|
const unitNames = String(row.UNITS).split(",").map((u) => u.trim()).filter((u) => u);
|
|
1750
1743
|
if (unitNames.length > 0) {
|
|
1751
1744
|
const areaUnits = [];
|
|
1752
1745
|
for (const unitName of unitNames) {
|
|
1753
|
-
|
|
1746
|
+
let foundUnit = availableUnits.find(
|
|
1754
1747
|
(u) => u.name.toLowerCase() === unitName.toLowerCase()
|
|
1755
1748
|
);
|
|
1749
|
+
if (!foundUnit) {
|
|
1750
|
+
try {
|
|
1751
|
+
const insertedUnitId = await _createUnit({
|
|
1752
|
+
name: unitName,
|
|
1753
|
+
site,
|
|
1754
|
+
serviceType
|
|
1755
|
+
});
|
|
1756
|
+
foundUnit = {
|
|
1757
|
+
_id: insertedUnitId,
|
|
1758
|
+
name: unitName
|
|
1759
|
+
};
|
|
1760
|
+
availableUnits.push(foundUnit);
|
|
1761
|
+
import_node_server_utils8.logger.info(
|
|
1762
|
+
`Successfully created missing unit "${unitName}" for area "${areaName}"`
|
|
1763
|
+
);
|
|
1764
|
+
} catch (error) {
|
|
1765
|
+
import_node_server_utils8.logger.warn(
|
|
1766
|
+
`Unit "${unitName}" could not be created for area "${areaName}": ${error.message}`
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1756
1770
|
if (foundUnit) {
|
|
1757
1771
|
areaUnits.push({
|
|
1758
1772
|
unit: foundUnit._id,
|
|
1759
1773
|
name: foundUnit.name
|
|
1760
1774
|
});
|
|
1761
|
-
} else {
|
|
1762
|
-
import_node_server_utils8.logger.warn(
|
|
1763
|
-
`Unit "${unitName}" not found in site for area "${areaName}"`
|
|
1764
|
-
);
|
|
1765
1775
|
}
|
|
1766
1776
|
}
|
|
1767
1777
|
if (areaUnits.length > 0) {
|
|
@@ -2148,6 +2158,13 @@ function useUnitService() {
|
|
|
2148
2158
|
updateUnit: _updateUnit,
|
|
2149
2159
|
deleteUnit: _deleteUnit
|
|
2150
2160
|
} = useUnitRepository();
|
|
2161
|
+
function getUnitNamesFromRow(row) {
|
|
2162
|
+
const unitValue = row?.UNIT ?? row?.UNITS;
|
|
2163
|
+
if (!unitValue) {
|
|
2164
|
+
return [];
|
|
2165
|
+
}
|
|
2166
|
+
return String(unitValue).split(",").map((unit) => unit.trim()).filter((unit) => unit && !unit.startsWith("Sample:"));
|
|
2167
|
+
}
|
|
2151
2168
|
async function importUnit({
|
|
2152
2169
|
dataJson,
|
|
2153
2170
|
site,
|
|
@@ -2173,36 +2190,35 @@ function useUnitService() {
|
|
|
2173
2190
|
try {
|
|
2174
2191
|
for (let i = 0; i < dataArray.length; i++) {
|
|
2175
2192
|
const row = dataArray[i];
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
continue;
|
|
2180
|
-
}
|
|
2181
|
-
const unitName = String(row.UNIT).trim();
|
|
2182
|
-
if (!unitName) {
|
|
2183
|
-
import_node_server_utils11.logger.warn(`Skipping row ${i + 1} with empty unit name`);
|
|
2193
|
+
const unitNames = getUnitNamesFromRow(row);
|
|
2194
|
+
if (unitNames.length === 0) {
|
|
2195
|
+
import_node_server_utils11.logger.warn(`Skipping row ${i + 1} with missing UNIT/UNITS:`, row);
|
|
2184
2196
|
skippedRows.push(i + 1);
|
|
2185
2197
|
continue;
|
|
2186
2198
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2199
|
+
const uniqueUnitNames = Array.from(
|
|
2200
|
+
new Set(unitNames.map((unitName) => unitName.toLowerCase()))
|
|
2201
|
+
).map(
|
|
2202
|
+
(lowerUnitName) => unitNames.find(
|
|
2203
|
+
(unitName) => unitName.toLowerCase() === lowerUnitName
|
|
2204
|
+
)
|
|
2205
|
+
);
|
|
2206
|
+
for (const unitName of uniqueUnitNames) {
|
|
2207
|
+
try {
|
|
2208
|
+
const insertedId = await _createUnit({
|
|
2209
|
+
name: unitName,
|
|
2210
|
+
site,
|
|
2211
|
+
serviceType
|
|
2212
|
+
});
|
|
2213
|
+
insertedUnitIds.push(insertedId);
|
|
2214
|
+
import_node_server_utils11.logger.info(`Successfully created unit: ${unitName}`);
|
|
2215
|
+
} catch (error) {
|
|
2216
|
+
import_node_server_utils11.logger.error(`Error creating unit "${unitName}": ${error.message}`);
|
|
2217
|
+
if (error.message.includes("Unit already exists")) {
|
|
2218
|
+
duplicateUnits.push(unitName);
|
|
2219
|
+
} else {
|
|
2220
|
+
failedUnits.push(unitName);
|
|
2221
|
+
}
|
|
2206
2222
|
}
|
|
2207
2223
|
}
|
|
2208
2224
|
}
|
|
@@ -2555,7 +2571,7 @@ function MParentChecklist(value) {
|
|
|
2555
2571
|
|
|
2556
2572
|
// src/repositories/hygiene-parent-checklist.repository.ts
|
|
2557
2573
|
var import_mongodb7 = require("mongodb");
|
|
2558
|
-
var
|
|
2574
|
+
var import_moment_timezone3 = __toESM(require("moment-timezone"));
|
|
2559
2575
|
var import_node_server_utils14 = require("@7365admin1/node-server-utils");
|
|
2560
2576
|
var import_core7 = require("@7365admin1/core");
|
|
2561
2577
|
function useParentChecklistRepo() {
|
|
@@ -2851,11 +2867,11 @@ function useParentChecklistRepo() {
|
|
|
2851
2867
|
cacheOptions.search = search;
|
|
2852
2868
|
}
|
|
2853
2869
|
const singaporeTz = "Asia/Singapore";
|
|
2854
|
-
const normalizedStartDate = typeof startDate === "string" ? startDate : (0,
|
|
2855
|
-
const normalizedEndDate = typeof endDate === "string" ? endDate : (0,
|
|
2870
|
+
const normalizedStartDate = typeof startDate === "string" ? startDate : (0, import_moment_timezone3.default)(startDate).tz(singaporeTz).format("YYYY-MM-DD");
|
|
2871
|
+
const normalizedEndDate = typeof endDate === "string" ? endDate : (0, import_moment_timezone3.default)(endDate).tz(singaporeTz).format("YYYY-MM-DD");
|
|
2856
2872
|
if (startDate && endDate) {
|
|
2857
|
-
const startOfDay =
|
|
2858
|
-
const endOfDay =
|
|
2873
|
+
const startOfDay = import_moment_timezone3.default.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate();
|
|
2874
|
+
const endOfDay = import_moment_timezone3.default.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate();
|
|
2859
2875
|
query.createdAt = {
|
|
2860
2876
|
$gte: startOfDay,
|
|
2861
2877
|
$lte: endOfDay
|
|
@@ -2864,12 +2880,12 @@ function useParentChecklistRepo() {
|
|
|
2864
2880
|
cacheOptions.endDate = normalizedEndDate;
|
|
2865
2881
|
} else if (startDate) {
|
|
2866
2882
|
query.createdAt = {
|
|
2867
|
-
$gte:
|
|
2883
|
+
$gte: import_moment_timezone3.default.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate()
|
|
2868
2884
|
};
|
|
2869
2885
|
cacheOptions.startDate = normalizedStartDate;
|
|
2870
2886
|
} else if (endDate) {
|
|
2871
2887
|
query.createdAt = {
|
|
2872
|
-
$lte:
|
|
2888
|
+
$lte: import_moment_timezone3.default.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate()
|
|
2873
2889
|
};
|
|
2874
2890
|
cacheOptions.endDate = normalizedEndDate;
|
|
2875
2891
|
}
|