feat: add quantity support to totals, UI, and thread resolution
- totals.service: multiply weight/cost sums by quantity in category and global totals - setup.service: multiply by quantity in getAllSetups SQL subqueries; expose quantity in getSetupWithItems item list - thread.service: explicitly pass quantity: 1 when inserting resolved item - ItemForm: add Quantity number input (min=1, default=1) after price field - ItemCard: show ×N badge next to item name when quantity > 1 - CollectionView: pass quantity prop to ItemCard in both filtered and grouped views - $setupId.tsx: pass quantity to ItemCard; multiply by quantity in client-side per-setup totals - WeightSummaryCard: multiply by quantity in all chart and legend weight calculations - useItems / useSetups: add quantity to ItemWithCategory / SetupItemWithCategory interfaces Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,12 +21,12 @@ export function getAllSetups(db: Db = prodDb) {
|
||||
WHERE setup_items.setup_id = setups.id
|
||||
), 0)`.as("item_count"),
|
||||
totalWeight: sql<number>`COALESCE((
|
||||
SELECT SUM(items.weight_grams) FROM setup_items
|
||||
SELECT SUM(items.weight_grams * items.quantity) FROM setup_items
|
||||
JOIN items ON items.id = setup_items.item_id
|
||||
WHERE setup_items.setup_id = setups.id
|
||||
), 0)`.as("total_weight"),
|
||||
totalCost: sql<number>`COALESCE((
|
||||
SELECT SUM(items.price_cents) FROM setup_items
|
||||
SELECT SUM(items.price_cents * items.quantity) FROM setup_items
|
||||
JOIN items ON items.id = setup_items.item_id
|
||||
WHERE setup_items.setup_id = setups.id
|
||||
), 0)`.as("total_cost"),
|
||||
@@ -45,6 +45,7 @@ export function getSetupWithItems(db: Db = prodDb, setupId: number) {
|
||||
name: items.name,
|
||||
weightGrams: items.weightGrams,
|
||||
priceCents: items.priceCents,
|
||||
quantity: items.quantity,
|
||||
categoryId: items.categoryId,
|
||||
notes: items.notes,
|
||||
productUrl: items.productUrl,
|
||||
|
||||
@@ -299,6 +299,7 @@ export function resolveThread(
|
||||
productUrl: candidate.productUrl,
|
||||
imageFilename: candidate.imageFilename,
|
||||
imageSourceUrl: candidate.imageSourceUrl,
|
||||
quantity: 1,
|
||||
})
|
||||
.returning()
|
||||
.get();
|
||||
|
||||
@@ -10,8 +10,8 @@ export function getCategoryTotals(db: Db = prodDb) {
|
||||
categoryId: items.categoryId,
|
||||
categoryName: categories.name,
|
||||
categoryIcon: categories.icon,
|
||||
totalWeight: sql<number>`COALESCE(SUM(${items.weightGrams}), 0)`,
|
||||
totalCost: sql<number>`COALESCE(SUM(${items.priceCents}), 0)`,
|
||||
totalWeight: sql<number>`COALESCE(SUM(${items.weightGrams} * ${items.quantity}), 0)`,
|
||||
totalCost: sql<number>`COALESCE(SUM(${items.priceCents} * ${items.quantity}), 0)`,
|
||||
itemCount: sql<number>`COUNT(*)`,
|
||||
})
|
||||
.from(items)
|
||||
@@ -23,8 +23,8 @@ export function getCategoryTotals(db: Db = prodDb) {
|
||||
export function getGlobalTotals(db: Db = prodDb) {
|
||||
return db
|
||||
.select({
|
||||
totalWeight: sql<number>`COALESCE(SUM(${items.weightGrams}), 0)`,
|
||||
totalCost: sql<number>`COALESCE(SUM(${items.priceCents}), 0)`,
|
||||
totalWeight: sql<number>`COALESCE(SUM(${items.weightGrams} * ${items.quantity}), 0)`,
|
||||
totalCost: sql<number>`COALESCE(SUM(${items.priceCents} * ${items.quantity}), 0)`,
|
||||
itemCount: sql<number>`COUNT(*)`,
|
||||
})
|
||||
.from(items)
|
||||
|
||||
Reference in New Issue
Block a user