update kpi report to include summary for daily report and end cycle

This commit is contained in:
Alberto-Audrix committed 2026-09-07 10:08:07 +07:00
1 parent 6c21af745d
commit 4439e3b7b1
5 files changed
+454 -43

No files matched your search

+26 -19
View File
@@ -7,6 +7,7 @@ import {
feedUseTotals,
} from './reportTotals.ts';
import { formatDateId, formatDateRange, formatNumber, formatRatio } from './format.ts';
import { buildReportSummary, formatSummaryValue } from './reportSummary.ts';
const COLORS = {
headerFill: 'FFF8FAFC',
@@ -54,17 +55,6 @@ const harvestKg = (grams: number | null | undefined): CellValue => {
return `${formatNumber(grams / 1000, 1)} kg`;
};
const latestValidRatio = (
rows: Array<{ iotFcr?: number | null; iotEef?: number | null }>,
key: 'iotFcr' | 'iotEef'
): number | null => {
for (let i = rows.length - 1; i >= 0; i -= 1) {
const value = rows[i]?.[key];
if (isPresent(value)) return value;
}
return null;
};
function styleHeaderRow(row: ExcelJS.Row, colCount: number): void {
row.height = 22;
for (let c = 1; c <= colCount; c += 1) {
@@ -196,18 +186,35 @@ function addSummarySheet(workbook: ExcelJS.Workbook, payload: DashboardReportPay
addMeta('Lokasi', `${payload.area} — ${payload.kandangName}`);
addMeta(
'Periode',
`Hari ke-0 s/d ke-${payload.upToDay} (${formatDateId(payload.cycleStart)} – ${formatDateId(lastDate)})`
`Hari ke-0 s/d ke-${payload.upToDay} (${formatDateId(payload.cycleStart)} - ${formatDateId(lastDate)})`
);
addMeta('Siklus', formatDateRange(payload.cycleStart, payload.cycleEnd));
addMeta('Dicetak', printedDate);
if (isEndCycle) {
const finalFcr = latestValidRatio(payload.fcr, 'iotFcr');
const finalEef = latestValidRatio(payload.eef, 'iotEef');
sheet.addRow([]);
addMeta('FCR akhir', ratio(finalFcr), true);
addMeta('EEF akhir', ratio(finalEef), true);
}
sheet.addRow([]);
const kpiTitle = sheet.addRow(['Ringkasan KPI']);
kpiTitle.getCell(1).font = {
bold: true,
size: 12,
color: { argb: COLORS.accentFill },
};
sheet.getColumn(3).width = 12;
const kpiHeader = sheet.addRow(['Metrik', 'Nilai', 'Satuan']);
styleHeaderRow(kpiHeader, 3);
const summary = buildReportSummary(payload);
summary.metrics.forEach((metric, index) => {
const row = sheet.addRow([
metric.label,
formatSummaryValue(metric),
metric.unit || '—',
]);
styleDataRow(row, 3, index % 2 === 1);
row.getCell(1).alignment = { vertical: 'middle', horizontal: 'left' };
row.getCell(2).alignment = { vertical: 'middle', horizontal: 'right' };
row.getCell(3).alignment = { vertical: 'middle', horizontal: 'left' };
});
sheet.addRow([]);
const navHeader = sheet.addRow(['Sheet', 'Isi']);