first commit
This commit is contained in:
commit
b54624be96
226 files changed
+108840
No files matched your search
@@ -0,0 +1,180 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildInMemoryReport } from '../buildInMemoryReport.ts';
|
||||
import type { ChickenCounting, Cycle, Karung, KPI } from '../../types/api.ts';
|
||||
|
||||
const cycle: Cycle = {
|
||||
id: 1,
|
||||
kandang: 9,
|
||||
kandang_name: 'Kandang 1',
|
||||
total_days: 35,
|
||||
current_day: 1,
|
||||
visible_through_date: '2026-05-02',
|
||||
start_date: '2026-05-01',
|
||||
end_date: '2026-06-04',
|
||||
chick_in_weight: 45,
|
||||
doc_in_count: 20000,
|
||||
feed_initial_balance: 0,
|
||||
status: 'gm',
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
};
|
||||
|
||||
describe('buildInMemoryReport', () => {
|
||||
it('maps IoT counting and karung onto daily rows up to current_day', () => {
|
||||
const countings: ChickenCounting[] = [
|
||||
{
|
||||
id: 1,
|
||||
cycle: 1,
|
||||
kandang: 9,
|
||||
flock_id: 1,
|
||||
date: '2026-05-02',
|
||||
total_count: 19800,
|
||||
mortality_count: 12,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
const karungs: Karung[] = [
|
||||
{
|
||||
id: 1,
|
||||
cycle: 1,
|
||||
kandang: 9,
|
||||
flock_id: 1,
|
||||
date: '2026-05-02',
|
||||
in_today: 10,
|
||||
out_today: 8,
|
||||
in_total: 10,
|
||||
out_total: 8,
|
||||
feed_use_today: 8,
|
||||
feed_use_total: 8,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
const kpis: KPI[] = [
|
||||
{
|
||||
id: 1,
|
||||
cycle: 1,
|
||||
kandang: 9,
|
||||
flock_id: 1,
|
||||
date: '2026-05-02',
|
||||
age: 1,
|
||||
mortality: 12,
|
||||
mortality_total: 12,
|
||||
feed: 8,
|
||||
feed_total: 8,
|
||||
harvest: 0,
|
||||
harvest_total: 0,
|
||||
harvest_weight: 0,
|
||||
harvest_weight_total: 0,
|
||||
chicken_life: 19800,
|
||||
chicken_life_percentage: 99,
|
||||
iot_weight: 0,
|
||||
average_harvest_day: 0,
|
||||
average_harvest_weight: 0,
|
||||
fcr: 1.2,
|
||||
eef: 250,
|
||||
cc: 1,
|
||||
cw: 1,
|
||||
fs: 1,
|
||||
manual: 1,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
|
||||
const payload = buildInMemoryReport({
|
||||
cycle,
|
||||
kandangId: 9,
|
||||
kandangName: 'Kandang 1',
|
||||
area: 'Sukawarna',
|
||||
reportType: 'daily',
|
||||
countings,
|
||||
manuals: [],
|
||||
weights: [],
|
||||
karungs,
|
||||
kpis,
|
||||
});
|
||||
|
||||
expect(payload.upToDay).toBe(1);
|
||||
expect(payload.docWeight).toBe(45);
|
||||
expect(payload.counting).toHaveLength(2);
|
||||
const day0 = payload.counting.find((row) => row.day === 0);
|
||||
expect(day0?.countBefore).toBe(20000);
|
||||
expect(day0?.countAfter).toBe(20000);
|
||||
const day1 = payload.counting.find((row) => row.day === 1);
|
||||
expect(day1?.countBefore).toBe(20000);
|
||||
expect(day1?.iotCount).toBe(19800);
|
||||
expect(day1?.mortality).toBe(12);
|
||||
const feed1 = payload.feedUse.find((row) => row.day === 1);
|
||||
expect(feed1?.iotUse).toBe(8);
|
||||
expect(payload.fcr.find((row) => row.day === 1)?.iotFcr).toBe(1.2);
|
||||
});
|
||||
|
||||
it('uses doc_in_count for day-0 stok awal instead of reverse-calculating from stok akhir', () => {
|
||||
const countings: ChickenCounting[] = [
|
||||
{
|
||||
id: 1,
|
||||
cycle: 1,
|
||||
kandang: 9,
|
||||
flock_id: 1,
|
||||
date: '2026-05-01',
|
||||
total_count: 36900,
|
||||
mortality_count: 42,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
const kpis: KPI[] = [
|
||||
{
|
||||
id: 1,
|
||||
cycle: 1,
|
||||
kandang: 9,
|
||||
flock_id: 1,
|
||||
date: '2026-05-01',
|
||||
age: 0,
|
||||
mortality: 42,
|
||||
mortality_total: 42,
|
||||
feed: 0,
|
||||
feed_total: 0,
|
||||
harvest: 0,
|
||||
harvest_total: 0,
|
||||
harvest_weight: 0,
|
||||
harvest_weight_total: 0,
|
||||
chicken_life: 45000,
|
||||
chicken_life_percentage: 100,
|
||||
iot_weight: 0,
|
||||
average_harvest_day: 0,
|
||||
average_harvest_weight: 0,
|
||||
fcr: 0,
|
||||
eef: 0,
|
||||
cc: 1,
|
||||
cw: 1,
|
||||
fs: 1,
|
||||
manual: 1,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
|
||||
const payload = buildInMemoryReport({
|
||||
cycle: { ...cycle, doc_in_count: 45000, current_day: 0, start_date: '2026-05-01' },
|
||||
kandangId: 9,
|
||||
kandangName: 'Kandang 1',
|
||||
area: 'Sukawarna',
|
||||
reportType: 'daily',
|
||||
countings,
|
||||
manuals: [],
|
||||
weights: [],
|
||||
karungs: [],
|
||||
kpis,
|
||||
});
|
||||
|
||||
const day0 = payload.counting.find((row) => row.day === 0);
|
||||
expect(day0?.countBefore).toBe(45000);
|
||||
expect(day0?.mortality).toBe(42);
|
||||
expect(day0?.countAfter).toBe(45000);
|
||||
expect(day0?.iotCount).toBe(36900);
|
||||
expect(day0?.accuracy).toBe(82);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user