Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import {LogChainDataSource} from '@logchain/datasources';
import {HttpErrors, ParameterObject} from '@loopback/rest';
export const SLA_LIMIT_HOURS = 72;
export const WARN_THRESHOLD_HOURS = 60;
export const AT_RISK_LOW_HOURS = 60;
export const AT_RISK_HIGH_HOURS = 71.99;
export const ARC_LENGTH = 180;
export function formatDateOnly(d: Date): string {
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
return `${yyyy}-${mm}-${dd}`;
}
export function dateStr(d: Date): string {
return formatDateOnly(d);
}
export function roundTo1Decimal(value: number): number {
const rounded = Math.round(value * 10) / 10;
return Object.is(rounded, -0) ? 0 : rounded;
}
export async function resolvePeriodFromCalendar(
dataSource: LogChainDataSource,
period: string = 'week',
from?: string,
to?: string,
): Promise<{start: Date; end: Date; label: string}> {
const now = new Date();
const todayStr = formatDateOnly(now);
if (period === 'day') {
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
return {start, end: now, label: 'Today'};
}
if (period === 'week') {
const rows = (await dataSource.execute(
`SELECT ap_code, ap_label, ap_start_date, ap_end_date
FROM ap_calendar
WHERE $1::date BETWEEN ap_start_date AND ap_end_date
LIMIT 1`,
[todayStr],
)) as any[];
if (rows.length) {
const row = rows[0];
const start = new Date(row.ap_start_date);
start.setHours(0, 0, 0, 0);
const end = new Date(row.ap_end_date);
end.setHours(23, 59, 59, 999);
const effectiveEnd = end > now ? now : end;
return {start, end: end, label: row.ap_label ?? row.ap_code};
}
const day = now.getDay();
const diffToMon = day === 0 ? -6 : 1 - day;
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate() + diffToMon, 0, 0, 0, 0);
return {start, end: now, label: 'This Week'};
}
if (period === 'month') {
const weekRows = (await dataSource.execute(
`SELECT ap_code
FROM ap_calendar
WHERE $1::date BETWEEN ap_start_date AND ap_end_date
LIMIT 1`,
[todayStr],
)) as any[];
if (weekRows.length) {
const apCode = weekRows[0].ap_code as string;
const rangeRows = (await dataSource.execute(
`SELECT MIN(ap_start_date) AS period_start, MAX(ap_end_date) AS period_end
FROM ap_calendar
WHERE ap_code = $1`,
[apCode],
)) as any[];
if (rangeRows.length && rangeRows[0].period_start) {
const start = new Date(rangeRows[0].period_start);
start.setHours(0, 0, 0, 0);
const end = new Date(rangeRows[0].period_end);
end.setHours(23, 59, 59, 999);
return {start, end, label: apCode};
}
}
const start = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); // ngày cuối cùng của tháng
return {
start,
end,
label: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`,
};
}
if (period === 'custom') {
if (!from || !to) throw new HttpErrors.BadRequest('from and to are required when period=custom');
const start = new Date(from);
const end = new Date(to);
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
throw new HttpErrors.BadRequest('from and to must be valid dates');
}
start.setHours(0, 0, 0, 0);
end.setHours(23, 59, 59, 999);
if (start > end) {
throw new HttpErrors.BadRequest('from must be before or equal to to');
}
return {start, end, label: `${from} ~ ${to}`};
}
throw new HttpErrors.BadRequest('period must be one of: day, week, month, custom');
}
export async function resolvePrevApCode(dataSource: LogChainDataSource, apCode: string): Promise<string | null> {
const rows = (await dataSource.execute(
`SELECT DISTINCT ap_code
FROM ap_calendar
WHERE fiscal_year * 100 + ap_number = (
SELECT fiscal_year * 100 + ap_number - 1
FROM ap_calendar
WHERE ap_code = $1
LIMIT 1
)
LIMIT 1`,
[apCode],
)) as any[];
return rows[0]?.ap_code ?? null;
}
|