first commit
This commit is contained in:
commit
b54624be96
226 files changed
+108840
No files matched your search
@@ -0,0 +1,112 @@
|
||||
import type {
|
||||
DashboardReportCountingRow,
|
||||
DashboardReportFeedInRow,
|
||||
DashboardReportFeedOutRow,
|
||||
DashboardReportFeedUseRow,
|
||||
} from '../types/dashboardReport.ts';
|
||||
|
||||
export const REPORT_TOTAL_LABEL = 'Total';
|
||||
|
||||
const isPresentNumber = (value: number | null | undefined): value is number =>
|
||||
typeof value === 'number' && Number.isFinite(value);
|
||||
|
||||
function sumPresent(values: Array<number | null | undefined>): number | null {
|
||||
let total = 0;
|
||||
let any = false;
|
||||
for (const value of values) {
|
||||
if (!isPresentNumber(value)) continue;
|
||||
total += value;
|
||||
any = true;
|
||||
}
|
||||
return any ? total : null;
|
||||
}
|
||||
|
||||
const sackAccuracy = (manual: number | null, iot: number | null): number | null => {
|
||||
if (manual != null && iot != null && manual > 0 && iot > 0) {
|
||||
return Math.round((Math.min(manual, iot) / Math.max(manual, iot)) * 1000) / 10;
|
||||
}
|
||||
if (manual === 0 && iot === 0) return 100;
|
||||
return null;
|
||||
};
|
||||
|
||||
export interface CountingTotalsRow {
|
||||
label: string;
|
||||
countBefore: number | null;
|
||||
mortality: number | null;
|
||||
harvest: number | null;
|
||||
harvestWeight: number | null;
|
||||
countAfter: number | null;
|
||||
iotCount: number | null;
|
||||
accuracy: number | null;
|
||||
}
|
||||
|
||||
export interface FeedInTotalsRow {
|
||||
label: string;
|
||||
manualIn: number | null;
|
||||
iotIn: number | null;
|
||||
accuracy: number | null;
|
||||
}
|
||||
|
||||
export interface FeedUseTotalsRow {
|
||||
label: string;
|
||||
manualUse: number | null;
|
||||
iotUse: number | null;
|
||||
accuracy: number | null;
|
||||
}
|
||||
|
||||
export interface FeedOutTotalsRow {
|
||||
label: string;
|
||||
manualOut: number | null;
|
||||
iotOut: number | null;
|
||||
accuracy: number | null;
|
||||
}
|
||||
|
||||
export function countingTotals(rows: DashboardReportCountingRow[]): CountingTotalsRow | null {
|
||||
if (!rows.length) return null;
|
||||
return {
|
||||
label: REPORT_TOTAL_LABEL,
|
||||
countBefore: null,
|
||||
mortality: sumPresent(rows.map((row) => row.mortality)),
|
||||
harvest: sumPresent(rows.map((row) => row.harvest)),
|
||||
harvestWeight: sumPresent(rows.map((row) => row.harvestWeight)),
|
||||
countAfter: null,
|
||||
iotCount: null,
|
||||
accuracy: null,
|
||||
};
|
||||
}
|
||||
|
||||
export function feedInTotals(rows: DashboardReportFeedInRow[]): FeedInTotalsRow | null {
|
||||
if (!rows.length) return null;
|
||||
const manualIn = sumPresent(rows.map((row) => row.manualIn));
|
||||
const iotIn = sumPresent(rows.map((row) => row.iotIn));
|
||||
return {
|
||||
label: REPORT_TOTAL_LABEL,
|
||||
manualIn,
|
||||
iotIn,
|
||||
accuracy: sackAccuracy(manualIn, iotIn),
|
||||
};
|
||||
}
|
||||
|
||||
export function feedUseTotals(rows: DashboardReportFeedUseRow[]): FeedUseTotalsRow | null {
|
||||
if (!rows.length) return null;
|
||||
const manualUse = sumPresent(rows.map((row) => row.manualUse));
|
||||
const iotUse = sumPresent(rows.map((row) => row.iotUse));
|
||||
return {
|
||||
label: REPORT_TOTAL_LABEL,
|
||||
manualUse,
|
||||
iotUse,
|
||||
accuracy: sackAccuracy(manualUse, iotUse),
|
||||
};
|
||||
}
|
||||
|
||||
export function feedOutTotals(rows: DashboardReportFeedOutRow[]): FeedOutTotalsRow | null {
|
||||
if (!rows.length) return null;
|
||||
const manualOut = sumPresent(rows.map((row) => row.manualOut));
|
||||
const iotOut = sumPresent(rows.map((row) => row.iotOut));
|
||||
return {
|
||||
label: REPORT_TOTAL_LABEL,
|
||||
manualOut,
|
||||
iotOut,
|
||||
accuracy: sackAccuracy(manualOut, iotOut),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user