feat: Etikettendruck prueft auch gedrehte Anordnung fuer bessere Blattausnutzung
Im automatischen Modus (Spalten/Zeilen leer) wird jetzt zusaetzlich berechnet, wie viele Etiketten pro Blatt passen, wenn man sie um 90 Grad dreht (Breite/Hoehe vertauscht). Passt die gedrehte Anordnung mehr drauf, wird sie verwendet - die Etiketten selbst bleiben inhaltlich unveraendert (nur auf dem Blatt gedreht), jedes einzelne Etikett bleibt beim Abziehen normal lesbar. Bei explizit gesetzten Spalten/Zeilen (z.B. fuer ein vorgedrucktes Avery-Raster) greift die Drehung nicht - ein reales Blatt hat feste, nicht drehbare Felder. Rotation erfolgt via pdfkit-Rotation um die Mitte des Feldes: ein Etikett, exakt 90 Grad um seinen eigenen Mittelpunkt gedreht, ergibt immer eine vertauschte Bounding-Box an derselben Stelle - unabhaengig von der Drehrichtungskonvention. 2 neue Tests belegen ueber die Seitenzahl, dass die Drehung greift, wenn sie mehr Etiketten unterbringt, und dass ein explizites Raster unangetastet bleibt. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
1e53758753
commit
390ec32f50
2 files changed
+169
-21
No files matched your search
@@ -343,6 +343,54 @@ describe('LabelTemplatesService', () => {
|
||||
expect(countPages(pdf)).toBe(2);
|
||||
});
|
||||
|
||||
it('rotates labels 90 degrees when that fits more per sheet than the upright orientation', async () => {
|
||||
// widthMm:90, heightMm:35, marginTopMm/Left:5, gapX/Y:2 (the default
|
||||
// fixture): upright fits 2 columns x 7 rows = 14 per page, but rotated
|
||||
// (35mm-wide x 90mm-tall slots) fits 5 columns x 3 rows = 15 per page.
|
||||
prisma.labelTemplate.findUnique.mockResolvedValue(template);
|
||||
prisma.bottlingBatch.findUnique.mockResolvedValue({
|
||||
id: 'batch-1',
|
||||
jarSize: 500,
|
||||
jarCount: 15,
|
||||
lotNumber: 'L-001',
|
||||
date: new Date('2026-06-01T00:00:00.000Z'),
|
||||
bestBeforeDate: new Date('2028-06-01T00:00:00.000Z'),
|
||||
honeyBatch: { batchNumber: 'HB-001', honeyType: 'Bluetenhonig' },
|
||||
product: { name: 'Glas 500g' },
|
||||
});
|
||||
|
||||
const pdf = await service.renderLabelsPdf('template-1', 'batch-1');
|
||||
|
||||
// Only fits on a single page if the rotated 15-per-page layout was
|
||||
// actually used - upright would need a second page for the 15th copy.
|
||||
expect(countPages(pdf)).toBe(1);
|
||||
});
|
||||
|
||||
it('does not rotate when columns/rows are explicitly set, even if rotating would fit more', async () => {
|
||||
prisma.labelTemplate.findUnique.mockResolvedValue({
|
||||
...template,
|
||||
columns: 2,
|
||||
rows: 7,
|
||||
});
|
||||
prisma.bottlingBatch.findUnique.mockResolvedValue({
|
||||
id: 'batch-1',
|
||||
jarSize: 500,
|
||||
jarCount: 15,
|
||||
lotNumber: 'L-001',
|
||||
date: new Date('2026-06-01T00:00:00.000Z'),
|
||||
bestBeforeDate: new Date('2028-06-01T00:00:00.000Z'),
|
||||
honeyBatch: { batchNumber: 'HB-001', honeyType: 'Bluetenhonig' },
|
||||
product: { name: 'Glas 500g' },
|
||||
});
|
||||
|
||||
const pdf = await service.renderLabelsPdf('template-1', 'batch-1');
|
||||
|
||||
// An explicit grid describes a real pre-printed sheet - it must be
|
||||
// honoured as-is (14 per page), needing 2 pages for 15 copies, even
|
||||
// though the auto-fit rotation logic would otherwise fit all 15 on one.
|
||||
expect(countPages(pdf)).toBe(2);
|
||||
});
|
||||
|
||||
it('skips already-used slots on the first sheet via startPosition, but not later sheets', async () => {
|
||||
prisma.labelTemplate.findUnique.mockResolvedValue({
|
||||
...template,
|
||||
|
||||
Reference in new issue
Block a user