feat: trvalé zobrazení QR kódu do ručního zavření (#31)

QR kódy pro platbu za pizza day jsou nyní zobrazeny persistentně
i po následující dny, dokud uživatel nepotvrdí platbu tlačítkem
"Zaplatil jsem". Nevyřízené QR kódy jsou uloženy per-user v storage
a zobrazeny v sekci "Nevyřízené platby".
This commit is contained in:
2026-02-04 17:11:45 +01:00
parent d366ac39d4
commit b8629afef2
4 changed files with 101 additions and 7 deletions

View File

@@ -4,9 +4,10 @@ import { generateQr } from "./qr";
import getStorage from "./storage";
import { downloadPizzy } from "./chefie";
import { getClientData, getToday, initIfNeeded } from "./service";
import { Pizza, ClientData, PizzaDayState, PizzaSize, PizzaOrder, PizzaVariant, UdalostEnum } from "../../types/gen/types.gen";
import { Pizza, ClientData, PizzaDayState, PizzaSize, PizzaOrder, PizzaVariant, UdalostEnum, PendingQr } from "../../types/gen/types.gen";
const storage = getStorage();
const PENDING_QR_PREFIX = 'pending_qr';
/**
* Vrátí seznam dostupných pizz pro dnešní den.
@@ -241,6 +242,12 @@ export async function finishPizzaDelivery(login: string, bankAccount?: string, b
let message = order.pizzaList!.map(pizza => `Pizza ${pizza.name} (${pizza.size})`).join(', ');
await generateQr(order.customer, bankAccount, bankAccountHolder, order.totalPrice, message);
order.hasQr = true;
// Uložíme nevyřízený QR kód pro persistentní zobrazení
await addPendingQr(order.customer, {
date: today,
creator: login,
totalPrice: order.totalPrice,
});
}
}
}
@@ -307,4 +314,41 @@ export async function updatePizzaFee(login: string, targetLogin: string, text?:
targetOrder.totalPrice = targetOrder.pizzaList.reduce((price, pizzaOrder) => price + pizzaOrder.price, 0) + (targetOrder.fee?.price ?? 0);
await storage.setData(today, clientData);
return clientData;
}
/**
* Vrátí klíč pro uložení nevyřízených QR kódů uživatele.
*/
function getPendingQrKey(login: string): string {
return `${PENDING_QR_PREFIX}_${login}`;
}
/**
* Přidá nevyřízený QR kód pro uživatele.
*/
async function addPendingQr(login: string, pendingQr: PendingQr): Promise<void> {
const key = getPendingQrKey(login);
const existing = await storage.getData<PendingQr[]>(key) ?? [];
// Nepřidáváme duplicity pro stejný den
if (!existing.some(qr => qr.date === pendingQr.date)) {
existing.push(pendingQr);
await storage.setData(key, existing);
}
}
/**
* Vrátí nevyřízené QR kódy pro uživatele.
*/
export async function getPendingQrs(login: string): Promise<PendingQr[]> {
return await storage.getData<PendingQr[]>(getPendingQrKey(login)) ?? [];
}
/**
* Označí QR kód pro daný den jako uhrazený (odstraní ho ze seznamu nevyřízených).
*/
export async function dismissPendingQr(login: string, date: string): Promise<void> {
const key = getPendingQrKey(login);
const existing = await storage.getData<PendingQr[]>(key) ?? [];
const filtered = existing.filter(qr => qr.date !== date);
await storage.setData(key, filtered);
}