diff --git a/src/lib/server/shopping/repository.ts b/src/lib/server/shopping/repository.ts index 81f91dc..5463f6c 100644 --- a/src/lib/server/shopping/repository.ts +++ b/src/lib/server/shopping/repository.ts @@ -87,7 +87,7 @@ export function listShoppingList( LOWER(TRIM(COALESCE(i.unit, ''))) AS unit_key, MIN(i.name) AS display_name, MIN(i.unit) AS display_unit, - SUM(i.quantity * cr.servings * 1.0 / COALESCE(r.servings_default, cr.servings)) AS total_quantity, + SUM(i.quantity * cr.servings * 1.0 / NULLIF(COALESCE(r.servings_default, cr.servings), 0)) AS total_quantity, GROUP_CONCAT(DISTINCT r.title) AS from_recipes, EXISTS( SELECT 1 FROM shopping_cart_check c diff --git a/tests/integration/shopping-repository.test.ts b/tests/integration/shopping-repository.test.ts index 0c33f1a..437b087 100644 --- a/tests/integration/shopping-repository.test.ts +++ b/tests/integration/shopping-repository.test.ts @@ -172,4 +172,16 @@ describe('listShoppingList aggregation', () => { addRecipeToCart(db, id, null); expect(listShoppingList(db).uncheckedCount).toBe(2); }); + + it('does not blow up when servings_default is zero (silent NULL total_quantity)', () => { + const db = openInMemoryForTest(); + const id = insertRecipe(db, recipe({ + servings_default: 0, + ingredients: [{ position: 1, quantity: 100, unit: 'g', name: 'Mehl', note: null, raw_text: '', section_heading: null }] + })); + addRecipeToCart(db, id, null, 4); + const rows = listShoppingList(db).rows; + expect(rows).toHaveLength(1); + expect(rows[0].total_quantity).toBeNull(); + }); });