diff --git a/frontend/src/services/seatingService.ts b/frontend/src/services/seatingService.ts index 413834a..a9b8824 100644 --- a/frontend/src/services/seatingService.ts +++ b/frontend/src/services/seatingService.ts @@ -425,6 +425,23 @@ export class SeatingService { return { total, byRow, byBlock }; } + /** + * Task E5: Exportiert eine Sitzplatzliste als CSV-String. + * Spalten: Typ, rowId, blockId, X, Y + * Zeilentrenner: \n (kompatibel mit Excel via „Daten importieren“). + */ + exportSeatListCSV(elements: CADElement[]): string { + const header = 'type,row_id,block_id,x,y'; + const rows: string[] = [header]; + for (const el of elements) { + if (el.type !== 'chair') continue; + const rowId = (el.properties.rowId as string | undefined) ?? ''; + const blockId = (el.properties.blockId as string | undefined) ?? ''; + rows.push(`chair,${rowId},${blockId},${el.x.toFixed(1)},${el.y.toFixed(1)}`); + } + return rows.join('\n'); + } + /** Get all chairs belonging to a specific row */ getRowElements(elements: CADElement[], rowId: string): CADElement[] { return elements.filter(el => el.type === 'chair' && el.properties.rowId === rowId); diff --git a/frontend/tests/seating.count.test.ts b/frontend/tests/seating.count.test.ts index 66c4373..e785484 100644 --- a/frontend/tests/seating.count.test.ts +++ b/frontend/tests/seating.count.test.ts @@ -82,3 +82,29 @@ describe('countSeats', () => { expect(Object.keys(result.byRow).length).toBe(1); }); }); + +describe('exportSeatListCSV', () => { + const svc = new SeatingService(); + + it('erzeugt CSV mit Header und Stuhl-Zeilen', () => { + const els = svc.createSeatingRow(0, 0, 'layer-1', { count: 3 }); + const csv = svc.exportSeatListCSV(els); + const lines = csv.split('\n'); + expect(lines[0]).toBe('type,row_id,block_id,x,y'); + expect(lines.length).toBe(4); // Header + 3 Stühle + expect(lines[1]).toContain('chair'); + }); + + it('ignoriert Nicht-Stuhl-Elemente', () => { + const chairs = svc.createSeatingRow(0, 0, 'layer-1', { count: 2 }); + const other: CADElement = { + id: 'x1', type: 'rect', layerId: 'l', x: 0, y: 0, width: 1, height: 1, properties: {}, + } as unknown as CADElement; + const csv = svc.exportSeatListCSV([...chairs, other]); + expect(csv.split('\n').length).toBe(3); // Header + 2 Stühle + }); + + it('leere Eingabe ergibt nur Header', () => { + expect(svc.exportSeatListCSV([])).toBe('type,row_id,block_id,x,y'); + }); +});