Add dashboard report snapshots feature with CRUD operations. Implemented new database migrations for dashboard_report_snapshots, including report type handling. Updated backend routes and models to support snapshot retrieval and upsert functionality. Enhanced frontend components to integrate report snapshot management, including UI for daily and end-cycle reports. Added tests for new functionality to ensure reliability.
CI / lint-and-test (push) Canceled after 0s
CI / lint-and-test (push) Canceled after 0s
This commit is contained in:
1 parent
059087be1d
commit
34336b9bd1
41 files changed
+4824
-178
No files matched your search
@@ -0,0 +1,125 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { latestValidRatio, mapKpiToEefRows, mapKpiToFcrRows } from '../reportFcrEef.ts';
|
||||
|
||||
const kpi = {
|
||||
'0': {
|
||||
food_total: 10,
|
||||
iot_weight: 45.5,
|
||||
chicken_life: 10000,
|
||||
harvest_weight_total: 12000,
|
||||
iot_fcr: 1.234,
|
||||
chicken_life_percentage: 99.5,
|
||||
iot_average_harvest_bw: 45.5,
|
||||
iot_average_day_weight: 0.2,
|
||||
iot_eef: 310.456,
|
||||
},
|
||||
'2': {
|
||||
food_total: 20,
|
||||
iot_weight: 80,
|
||||
chicken_life: 9900,
|
||||
harvest_weight_total: 50000,
|
||||
iot_fcr: 0,
|
||||
chicken_life_percentage: 98.1,
|
||||
iot_average_harvest_bw: 80,
|
||||
iot_average_day_weight: 2,
|
||||
iot_eef: 0,
|
||||
},
|
||||
'8': {
|
||||
food_total: 40,
|
||||
iot_weight: 400,
|
||||
chicken_life: 9700,
|
||||
harvest_weight_total: 200000,
|
||||
iot_fcr: 1.7,
|
||||
chicken_life_percentage: 96.2,
|
||||
iot_average_harvest_bw: 400,
|
||||
iot_average_day_weight: 8,
|
||||
iot_eef: 280.9,
|
||||
},
|
||||
};
|
||||
|
||||
describe('mapKpiToFcrRows', () => {
|
||||
it('maps page FCR fields and keeps only days 0..upToDay', () => {
|
||||
expect(mapKpiToFcrRows(kpi, 2)).toEqual([
|
||||
{
|
||||
day: 0,
|
||||
feedTotal: 10,
|
||||
iotWeight: 45.5,
|
||||
chickenLife: 10000,
|
||||
harvestWeightTotal: 12000,
|
||||
iotFcr: 1.234,
|
||||
},
|
||||
{
|
||||
day: 2,
|
||||
feedTotal: 20,
|
||||
iotWeight: 80,
|
||||
chickenLife: 9900,
|
||||
harvestWeightTotal: 50000,
|
||||
iotFcr: null,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns an empty array for invalid KPI without throwing', () => {
|
||||
expect(mapKpiToFcrRows(null, 8)).toEqual([]);
|
||||
expect(mapKpiToFcrRows(undefined, 8)).toEqual([]);
|
||||
expect(mapKpiToFcrRows('nope', 8)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapKpiToEefRows', () => {
|
||||
it('maps page EEF fields and keeps only days 0..upToDay', () => {
|
||||
expect(mapKpiToEefRows(kpi, 2)).toEqual([
|
||||
{
|
||||
day: 0,
|
||||
chickenLifePercentage: 99.5,
|
||||
iotAverageHarvestBw: 45.5,
|
||||
iotAverageDayWeight: 0.2,
|
||||
iotFcr: 1.234,
|
||||
iotEef: 310.456,
|
||||
},
|
||||
{
|
||||
day: 2,
|
||||
chickenLifePercentage: 98.1,
|
||||
iotAverageHarvestBw: 80,
|
||||
iotAverageDayWeight: 2,
|
||||
iotFcr: null,
|
||||
iotEef: null,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns an empty array for invalid KPI without throwing', () => {
|
||||
expect(mapKpiToEefRows(null, 8)).toEqual([]);
|
||||
expect(mapKpiToEefRows(undefined, 8)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('latestValidRatio', () => {
|
||||
it('returns the last non-null ratio, skipping empty later days', () => {
|
||||
expect(
|
||||
latestValidRatio(
|
||||
[
|
||||
{ day: 0, iotFcr: 1.234 },
|
||||
{ day: 2, iotFcr: null },
|
||||
{ day: 8, iotFcr: 1.7 },
|
||||
],
|
||||
'iotFcr'
|
||||
)
|
||||
).toBe(1.7);
|
||||
expect(
|
||||
latestValidRatio(
|
||||
[
|
||||
{ day: 0, iotEef: 310.456 },
|
||||
{ day: 2, iotEef: null },
|
||||
],
|
||||
'iotEef'
|
||||
)
|
||||
).toBe(310.456);
|
||||
});
|
||||
|
||||
it('returns null when every value is missing', () => {
|
||||
expect(latestValidRatio([{ iotFcr: null }, { iotFcr: 0 }], 'iotFcr')).toBeNull();
|
||||
expect(latestValidRatio([], 'iotFcr')).toBeNull();
|
||||
expect(latestValidRatio(undefined, 'iotFcr')).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user