diff --git a/server/src/services/packingService.ts b/server/src/services/packingService.ts index bc4b38c5..de487b3e 100644 --- a/server/src/services/packingService.ts +++ b/server/src/services/packingService.ts @@ -76,13 +76,14 @@ interface ImportItem { category?: string; weight_grams?: string | number; bag?: string; + quantity?: number; } export function bulkImport(tripId: string | number, items: ImportItem[]) { const maxOrder = db.prepare('SELECT MAX(sort_order) as max FROM packing_items WHERE trip_id = ?').get(tripId) as { max: number | null }; let sortOrder = (maxOrder.max !== null ? maxOrder.max : -1) + 1; - const stmt = db.prepare('INSERT INTO packing_items (trip_id, name, checked, category, weight_grams, bag_id, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)'); + const stmt = db.prepare('INSERT INTO packing_items (trip_id, name, checked, category, weight_grams, bag_id, sort_order, quantity) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'); const created: any[] = []; const insertAll = db.transaction(() => { @@ -105,7 +106,8 @@ export function bulkImport(tripId: string | number, items: ImportItem[]) { } } - const result = stmt.run(tripId, item.name.trim(), checked, item.category?.trim() || 'Other', weight, bagId, sortOrder++); + const qty = Math.max(1, Math.min(999, Number(item.quantity) || 1)); + const result = stmt.run(tripId, item.name.trim(), checked, item.category?.trim() || 'Other', weight, bagId, sortOrder++, qty); created.push(db.prepare('SELECT * FROM packing_items WHERE id = ?').get(result.lastInsertRowid)); } }); diff --git a/server/tests/unit/services/packingService.test.ts b/server/tests/unit/services/packingService.test.ts index 672bb962..511f388d 100644 --- a/server/tests/unit/services/packingService.test.ts +++ b/server/tests/unit/services/packingService.test.ts @@ -275,3 +275,27 @@ describe('bulkImport with bag field', () => { expect(items[1].bag_id).toBe(bags[0].id); }); }); + +// ── bulkImport with quantity field ──────────────────────────────────────────── + +describe('bulkImport with quantity field', () => { + it('PACK-SVC-013: bulk import respects per-item quantity, defaults to 1, and clamps out-of-range', () => { + const { user } = createUser(testDb); + const trip = createTrip(testDb, user.id); + + bulkImport(trip.id, [ + { name: 'Socks', quantity: 5 }, + { name: 'Toothbrush' }, + { name: 'Batteries', quantity: 9999 }, + { name: 'Charger', quantity: 0 }, + ]); + + const byName = (n: string) => + testDb.prepare('SELECT * FROM packing_items WHERE trip_id = ? AND name = ?').get(trip.id, n) as any; + + expect(byName('Socks').quantity).toBe(5); + expect(byName('Toothbrush').quantity).toBe(1); + expect(byName('Batteries').quantity).toBe(999); + expect(byName('Charger').quantity).toBe(1); + }); +});