feat: opakovaný výběr jídla zvýší počet kusů (2x)
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Successful in 25s
CI / Build server (push) Successful in 27s
CI / Build client (push) Successful in 40s
CI / Playwright E2E tests (push) Successful in 1m50s
CI / Build and push Docker image (push) Successful in 44s
CI / Notify (push) Successful in 1s

This commit is contained in:
batmanisko committed 2026-09-23 16:37:01 +02:00
1 parent f9a7b791a0
commit 076b8db179
3 files changed
+41 -19

No files matched your search

+35 -14
View File
@@ -52,13 +52,12 @@ function findDish(text: string, dishes: { dish: StoreMenuDish, norm: string }[])
export function matchNoteToMenu(note: string | undefined, menu: StoreMenuDish[]): NoteMatch | undefined {
if (!note?.trim() || menu.length === 0) return undefined;
const dishes = menu.map(dish => ({ dish, norm: normalizeDishName(dish.name) }));
const whole = dishes.find(d => d.norm === normalizeDishName(note));
const parts: MatchedPart[] = whole
? [{ text: note.trim(), quantity: 1, dish: whole.dish }]
: note.split('+').map(p => p.trim()).filter(Boolean).map(text => {
const { quantity, rest } = parseQuantity(text);
return { text, quantity, dish: findDish(rest, dishes) };
});
const parts: MatchedPart[] = splitNoteItems(note, menu).map(text => {
const exact = dishes.find(d => d.norm === normalizeDishName(text));
if (exact) return { text, quantity: 1, dish: exact.dish };
const { quantity, rest } = parseQuantity(text);
return { text, quantity, dish: findDish(rest, dishes) };
});
if (!parts.some(p => p.dish)) return undefined;
const complete = parts.every(p => p.dish?.price != null);
return {
@@ -68,10 +67,8 @@ export function matchNoteToMenu(note: string | undefined, menu: StoreMenuDish[])
}
/** Počet položek v poznámce objednávky — části oddělené „+", včetně množství („2x Hranolky" = 2). */
export function countNoteItems(note: string | undefined): number {
if (!note?.trim()) return 0;
return note.split('+').map(p => p.trim()).filter(Boolean)
.reduce((sum, part) => sum + parseQuantity(part).quantity, 0);
export function countNoteItems(note: string | undefined, menu: StoreMenuDish[] = []): number {
return splitNoteItems(note, menu).reduce((sum, part) => sum + parseQuantity(part).quantity, 0);
}
/**
@@ -79,9 +76,19 @@ export function countNoteItems(note: string | undefined): number {
* odpovídá jednomu jídlu z nabídky (název může obsahovat „+"), je to jediná položka.
*/
export function splitNoteItems(note: string | undefined, menu: StoreMenuDish[] = []): string[] {
const trimmed = (note ?? '').trim();
if (trimmed && menu.some(d => normalizeDishName(d.name) === normalizeDishName(trimmed))) return [trimmed];
return trimmed.split('+').map(p => p.trim()).filter(Boolean);
const tokens = (note ?? '').split('+').map(p => p.trim()).filter(Boolean);
if (menu.length === 0 || tokens.length < 2) return tokens;
const names = new Set(menu.map(d => normalizeDishName(d.name)));
const isDish = (text: string) => names.has(normalizeDishName(text)) || names.has(normalizeDishName(parseQuantity(text).rest));
// Sousední části, které dohromady tvoří název jídla s „+" („Stripsy 6 Ks + Coleslaw"), spojíme zpět
const result: string[] = [];
for (let i = 0; i < tokens.length;) {
let j = tokens.length;
while (j > i + 1 && !isDish(tokens.slice(i, j).join(' + '))) j--;
result.push(tokens.slice(i, j).join(' + '));
i = j;
}
return result;
}
/**
@@ -100,3 +107,17 @@ export function removeNoteItem(note: string | undefined, index: number, menu: St
else parts.splice(index, 1);
return { note: parts.join(' + '), removedPrice: dish?.price };
}
/**
* Přidá do poznámky jeden kus jídla. Pokud už v poznámce je (i s počtem, např. „2x Hranolky"),
* zvýší jeho počet („Hranolky" → „2x Hranolky"), jinak ho připojí za „+".
*/
export function addNoteItem(note: string | undefined, dishName: string, menu: StoreMenuDish[] = []): string {
const parts = splitNoteItems(note, menu);
const target = normalizeDishName(dishName);
const index = parts.findIndex(p => normalizeDishName(p) === target || normalizeDishName(parseQuantity(p).rest) === target);
if (index < 0) return [...parts, dishName].join(' + ');
const existing = normalizeDishName(parts[index]) === target ? { quantity: 1, rest: parts[index] } : parseQuantity(parts[index]);
parts[index] = `${existing.quantity + 1}x ${existing.rest.trim()}`;
return parts.join(' + ');
}