Commit Graph
4 Commits
Author SHA1 Message Date
Nick SzaunigandClaude Opus 5.5 e0b47faf45 feat(orders): reopen cancelled orders only after confirmation; accurate sales
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m24s
Cancelled orders:
- Moving an order out of STORNIERT is possible again, but only after a
  warning is confirmed in the status form (OrderStatusForm); without
  the confirmation the server changes nothing.
- Reopening books the counter-entry to the cancellation: goods that the
  cancellation restocked are deducted again (atomically, only if enough
  stock is left, otherwise the order stays cancelled). A later second
  cancellation therefore restocks +1 again instead of leaving +2.
- The warning states that no new payment is collected.

Dashboard figures:
- One definition of a counted sale (lib/sales.ts): not unpaid (NEU),
  not cancelled, no refunded return. Used for revenue today/month, sold
  glasses, average cart, top products/categories, revenue trend and
  repeat customers.
- "Verkaufte Gläser" previously summed every order item, including
  cancelled orders and refunded returns.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-27 01:14:12 +02:00
Nick SzaunigandClaude Opus 5.5 dc1523aafd fix(orders): cancelled orders cannot be reopened (stock restocked twice)
After refund + cancellation the stock rose by 2 instead of 1. Cause:
the status form allowed moving an order out of STORNIERT. Cancelling
restocks the goods and refunds the payment; reopening did neither in
reverse, and the next cancellation passed the "not already cancelled"
claim again and restocked a second time (the refund was not repeated
because the payment was already REFUNDED, so only the stock showed it).

STORNIERT is now a final state:
- isOrderStatusChangeAllowed() in lib/inventory.ts next to the other
  cancel rules, with tests
- updateOrderStatusAction rejects the change up front with a clear
  message and moves non-cancel statuses with an atomic
  "status <> STORNIERT" update, so a cancellation from a second tab
  cannot be undone in between
- the order list and detail page no longer offer the status select for
  cancelled orders

Existing stock that was restocked twice has to be corrected by hand.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-27 00:45:31 +02:00
Nick SzaunigandClaude Opus 5.5 d52a762e8a fix: Produkt-Formular ueberschreibt keinen zwischenzeitlich gebuchten Bestand
Das Speichern schrieb den Formularwert immer fest in den Lagerbestand.
Wurde zwischen Oeffnen und Speichern ein Glas verkauft, kam es dadurch
wieder in den Bestand, ohne dass es je zurueckkam.

- Das Formular schickt den Bestand beim Oeffnen mit (quantityLoaded)
- Feld unveraendert: Bestand wird nicht angefasst
- Feld geaendert: Schreiben nur, wenn der Bestand noch dem geladenen Stand
  entspricht (Bedingung atomar im UPDATE); sonst wird nichts gespeichert
  und der aktuelle Wert angezeigt
- Fehlt quantityLoaded (alter Tab), muss neu geladen werden

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-26 05:55:36 +02:00
Nick SzaunigandClaude Opus 5.5 5848eb6ad5 fix: Bestand bei Storno nach erstatteter Retoure nicht doppelt zurueckbuchen
Wurde eine Retoure erstattet und die Bestellung danach auf "STORNIERT"
gesetzt, buchten beide Schritte die Ware zurueck. Bei einer Testbestellung
stieg der Bestand so von 105 auf 106 Glaeser.

- Stornieren bucht nur noch zurueck, wenn keine Retoure erstattet ist
  (needsRestockOnCancel in lib/inventory.ts)
- Retoure einer bereits stornierten Bestellung laesst sich nicht mehr
  erstatten, auch nicht im Wettlauf (Bedingung im atomaren Claim)

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-26 03:12:37 +02:00