fix(inkop): stabil ordning i inkopslistan (id som tie-breaker + sortOrder pa nya varor)
Varor som lades till via recept/manuellt fick alla sortOrder=0. GET-listan sorterade pa (sektion, sortOrder) utan stabil brytare, sa nar en rad bockades av (UPDATE) kastades ordningen om - varorna hoppade. Nu: id som sista sorteringsnyckel (total, deterministisk ordning) + nya varor far nasta sortOrder sa de laggs sist.
This commit is contained in:
@@ -77,7 +77,14 @@ export async function shoppingRoutes(app: FastifyInstance) {
|
|||||||
.select()
|
.select()
|
||||||
.from(schema.shoppingListItems)
|
.from(schema.shoppingListItems)
|
||||||
.where(eq(schema.shoppingListItems.shoppingListId, id))
|
.where(eq(schema.shoppingListItems.shoppingListId, id))
|
||||||
.orderBy(schema.shoppingListItems.storeSection, schema.shoppingListItems.sortOrder);
|
// Stabil ordning: sektion, sortOrder och SIST id som tie-breaker. Utan id
|
||||||
|
// hamnar rader med samma sortOrder (t.ex. alla 0) i odefinierad ordning som
|
||||||
|
// kastas om när en rad uppdateras (bockas av) – varorna "hoppade" då runt.
|
||||||
|
.orderBy(
|
||||||
|
schema.shoppingListItems.storeSection,
|
||||||
|
schema.shoppingListItems.sortOrder,
|
||||||
|
schema.shoppingListItems.id,
|
||||||
|
);
|
||||||
const estimatedTotal = items.reduce((sum, i) => sum + (i.estimatedPriceMinor ?? 0), 0);
|
const estimatedTotal = items.reduce((sum, i) => sum + (i.estimatedPriceMinor ?? 0), 0);
|
||||||
// Prisuppskattningar härleds ur katalogens baspriser (SEK) tills per-marknads-priser (M8).
|
// Prisuppskattningar härleds ur katalogens baspriser (SEK) tills per-marknads-priser (M8).
|
||||||
return { list, items, estimatedTotalMinor: Math.round(estimatedTotal), currency: "SEK" };
|
return { list, items, estimatedTotalMinor: Math.round(estimatedTotal), currency: "SEK" };
|
||||||
@@ -139,6 +146,12 @@ export async function shoppingRoutes(app: FastifyInstance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nästa sortOrder = sist i listan, så nya varor läggs till på slutet i stället
|
||||||
|
// för att dela sortOrder 0 med alla andra (vilket gav ostabil ordning).
|
||||||
|
const [{ maxOrder } = { maxOrder: null }] = await app.db
|
||||||
|
.select({ maxOrder: sql<number | null>`max(${schema.shoppingListItems.sortOrder})` })
|
||||||
|
.from(schema.shoppingListItems)
|
||||||
|
.where(eq(schema.shoppingListItems.shoppingListId, id));
|
||||||
const [item] = await app.db
|
const [item] = await app.db
|
||||||
.insert(schema.shoppingListItems)
|
.insert(schema.shoppingListItems)
|
||||||
.values({
|
.values({
|
||||||
@@ -151,6 +164,7 @@ export async function shoppingRoutes(app: FastifyInstance) {
|
|||||||
estimatedPriceMinor: estimatedPrice ?? null,
|
estimatedPriceMinor: estimatedPrice ?? null,
|
||||||
addedByUserId: req.userId,
|
addedByUserId: req.userId,
|
||||||
origin: "manual",
|
origin: "manual",
|
||||||
|
sortOrder: (maxOrder ?? -1) + 1,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
return reply.status(201).send({ item, merged: false });
|
return reply.status(201).send({ item, merged: false });
|
||||||
|
|||||||
Reference in New Issue
Block a user