fix: include Wirkstoff, Charge, and Wartezeit in the annual treatment report

The colony annual PDF report's treatment section only ever printed
date/product/amount - activeIngredient, batchNumber, and
withdrawalPeriodDays (added earlier this session specifically for
Wartezeit compliance) existed on the Treatment record but never made
it into the one document a beekeeper would actually hand to a
Veterinäramt inspector or keep as their Bestandsbuch-style compliance
record. Silently missing the withdrawal period from the printed
record undermines the whole point of tracking it.

Also adds the first tests for annual-reports.ts (previously untested).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Sonnet 5 committed 2026-09-09 10:50:46 +02:00
1 parent fb4713e320
commit 2e6846285d
2 files changed
+93 -2

No files matched your search

@@ -0,0 +1,74 @@
import { NotFoundException } from '@nestjs/common';
import { buildColonyAnnualReport } from './annual-reports';
import { PrismaService } from '../prisma/prisma.service';
describe('buildColonyAnnualReport', () => {
let prisma: {
colony: { findUnique: jest.Mock };
inspection: { findMany: jest.Mock };
treatment: { findMany: jest.Mock };
varroaMeasurement: { findMany: jest.Mock };
swarmControlCheck: { findMany: jest.Mock };
harvestColony: { findMany: jest.Mock };
};
const colony = {
id: 'colony-1',
code: 'V-001',
colonyType: 'PRODUCTION_COLONY',
status: 'ACTIVE',
apiary: { id: 'apiary-1', name: 'Heimstand' },
};
beforeEach(() => {
prisma = {
colony: { findUnique: jest.fn().mockResolvedValue(colony) },
inspection: { findMany: jest.fn().mockResolvedValue([]) },
treatment: { findMany: jest.fn().mockResolvedValue([]) },
varroaMeasurement: { findMany: jest.fn().mockResolvedValue([]) },
swarmControlCheck: { findMany: jest.fn().mockResolvedValue([]) },
harvestColony: { findMany: jest.fn().mockResolvedValue([]) },
};
});
it('throws NotFoundException for an unknown colony', async () => {
prisma.colony.findUnique.mockResolvedValue(null);
await expect(
buildColonyAnnualReport(
prisma as unknown as PrismaService,
'missing',
2026,
),
).rejects.toBeInstanceOf(NotFoundException);
});
it('carries activeIngredient, batchNumber and withdrawalPeriodDays through for each treatment', async () => {
prisma.treatment.findMany.mockResolvedValue([
{
date: new Date('2026-05-01'),
product: 'Ameisensäure 60%',
amount: '15 ml',
activeIngredient: 'Ameisensäure',
batchNumber: 'CH-2026-01',
withdrawalPeriodDays: 0,
},
]);
const report = await buildColonyAnnualReport(
prisma as unknown as PrismaService,
'colony-1',
2026,
);
expect(report.treatments).toEqual([
{
date: new Date('2026-05-01'),
product: 'Ameisensäure 60%',
amount: '15 ml',
activeIngredient: 'Ameisensäure',
batchNumber: 'CH-2026-01',
withdrawalPeriodDays: 0,
},
]);
});
});
+19 -2
View File
@@ -37,7 +37,14 @@ export interface ColonyAnnualReport {
queenSeen: boolean | null; queenSeen: boolean | null;
broodAmount: string | null; broodAmount: string | null;
}[]; }[];
treatments: { date: Date; product: string; amount: string | null }[]; treatments: {
date: Date;
product: string;
amount: string | null;
activeIngredient: string | null;
batchNumber: string | null;
withdrawalPeriodDays: number | null;
}[];
varroaMeasurements: { varroaMeasurements: {
date: Date; date: Date;
method: string; method: string;
@@ -141,6 +148,9 @@ export async function buildColonyAnnualReport(
date: entry.date, date: entry.date,
product: entry.product, product: entry.product,
amount: entry.amount, amount: entry.amount,
activeIngredient: entry.activeIngredient,
batchNumber: entry.batchNumber,
withdrawalPeriodDays: entry.withdrawalPeriodDays,
})), })),
varroaMeasurements: varroaMeasurements.map((entry) => ({ varroaMeasurements: varroaMeasurements.map((entry) => ({
date: entry.date, date: entry.date,
@@ -262,7 +272,14 @@ export function renderColonyAnnualReportPdf(
} }
for (const entry of report.treatments) { for (const entry of report.treatments) {
doc.text( doc.text(
`- ${formatDate(entry.date)}: ${entry.product} (${entry.amount ?? '-'})`, `- ${formatDate(entry.date)}: ${entry.product} (${entry.amount ?? '-'})` +
(entry.activeIngredient
? `, Wirkstoff: ${entry.activeIngredient}`
: '') +
(entry.batchNumber ? `, Charge: ${entry.batchNumber}` : '') +
(entry.withdrawalPeriodDays !== null
? `, Wartezeit: ${entry.withdrawalPeriodDays} Tage`
: ''),
); );
} }
doc.moveDown(); doc.moveDown();