feat(lager): dedup per forvaringsplats + tydlig Ta bort per rad
Skann-bekraftelse slar bara ihop dubbletter inom SAMMA plats (mjolk i kyl != mjolk i frys) + hoppar over tomma poster. Lagerlistan far en tydlig 'Ta bort' direkt pa varje rad (inte bara via markering).
This commit is contained in:
@@ -151,11 +151,13 @@ export async function scanRoutes(app: FastifyInstance) {
|
||||
id: schema.inventoryItems.id,
|
||||
canonicalIngredientId: schema.inventoryItems.canonicalIngredientId,
|
||||
displayName: schema.inventoryItems.displayName,
|
||||
storageLocationId: schema.inventoryItems.storageLocationId,
|
||||
})
|
||||
.from(schema.inventoryItems)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.inventoryItems.householdId, householdId),
|
||||
isNull(schema.inventoryItems.depletedAt),
|
||||
gt(schema.inventoryItems.quantity, 0),
|
||||
),
|
||||
);
|
||||
@@ -175,11 +177,14 @@ export async function scanRoutes(app: FastifyInstance) {
|
||||
// Matcha på katalog-id ELLER normaliserat namn — Vision skriver sällan
|
||||
// exakt samma namn två gånger ("Mjölk" vs "mjölk" vs "Mjölk 1L").
|
||||
const wantNorm = normalizeItemName(item.displayName);
|
||||
// Slå bara ihop inom SAMMA förvaringsplats – "Mjölk" i kylen och "Mjölk"
|
||||
// i frysen är olika varor och ska inte slås ihop till en rad.
|
||||
const dupe = activeItems.find(
|
||||
(r) =>
|
||||
(item.canonicalIngredientId != null &&
|
||||
r.storageLocationId === locationId &&
|
||||
((item.canonicalIngredientId != null &&
|
||||
r.canonicalIngredientId === item.canonicalIngredientId) ||
|
||||
r.norm === wantNorm,
|
||||
r.norm === wantNorm),
|
||||
);
|
||||
if (dupe) {
|
||||
await app.db
|
||||
@@ -230,6 +235,7 @@ export async function scanRoutes(app: FastifyInstance) {
|
||||
id: inv!.id,
|
||||
canonicalIngredientId: item.canonicalIngredientId ?? null,
|
||||
displayName: item.displayName,
|
||||
storageLocationId: locationId,
|
||||
norm: wantNorm,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { Alert, View } from "react-native";
|
||||
import { Alert, Pressable, View } from "react-native";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { api } from "@/lib/api";
|
||||
@@ -193,12 +193,22 @@ export default function KitchenScreen() {
|
||||
onPress={() => toggle(item.id)}
|
||||
style={isSel ? { borderColor: colors.primary, backgroundColor: colors.primarySoft } : undefined}
|
||||
>
|
||||
<Row style={{ justifyContent: "space-between" }}>
|
||||
<Row style={{ justifyContent: "space-between", alignItems: "center" }}>
|
||||
<Body>
|
||||
{isSel ? "☑ " : "☐ "}
|
||||
{item.displayName} · {formatQuantity(item.quantity, item.unit)}
|
||||
</Body>
|
||||
{item.expiry.pastBestBefore && <Small>⚠︎ bäst före</Small>}
|
||||
<Row style={{ alignItems: "center", gap: 12 }}>
|
||||
{item.expiry.pastBestBefore && <Small>⚠︎ bäst före</Small>}
|
||||
<Pressable
|
||||
onPress={() => confirmDelete([item.id], locLabel(item.locationType))}
|
||||
hitSlop={8}
|
||||
>
|
||||
<Small style={{ color: colors.danger, fontWeight: "600" }}>
|
||||
{t("common.remove")}
|
||||
</Small>
|
||||
</Pressable>
|
||||
</Row>
|
||||
</Row>
|
||||
</Card>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user