From d8689a7b68555403bc63af8c48dcee944ae51385 Mon Sep 17 00:00:00 2001 From: Stephen Early Date: Wed, 12 Feb 2025 13:31:39 +0000 Subject: [PATCH] Restrict the code path that can remove completed payments Fixes #312 on github. The "cancel open transaction" code path in the register would remove any payments while deleting an open transaction. This is now restricted to removing non-pending transactions of zero amount (eg. "Square transaction cancelled" notes). --- quicktill/register.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/quicktill/register.py b/quicktill/register.py index 6c24f0d..cf57094 100644 --- a/quicktill/register.py +++ b/quicktill/register.py @@ -2301,6 +2301,16 @@ def cancelkey(self): "one go. Cancel each line separately instead."], title="Cancel Transaction") return + # If there are any pending or non-zero payments, the + # transaction can't be cancelled. + if not closed and any( + p.pending or p.amount != zero for p in trans.payments): + ui.infopopup( + ["This transaction has (possibly pending) payments, and " + "so can't be cancelled. Void lines and then issue a " + "refund as required."], + title="Cancel Transaction") + return log.info("Register: cancelkey confirm kill " "transaction %d", trans.id) ui.infopopup( @@ -2440,26 +2450,21 @@ def canceltrans(self): else: # Delete this transaction and everything to do with it tn = trans.id + if any(p.pending or p.amount != zero for p in trans.payments): + ui.infopopup(["Cannot delete transaction with pending " + "or non-zero payments."], + title="Error") + return log.info("Register: cancel open transaction %d" % tn) - payments = trans.payments_total # Payment, Transline and StockOut objects should be deleted # implicitly in cascade td.s.delete(trans) self.transid = None td.s.flush() - if payments > zero: - # XXX this is looking at all payments, not just those that - # go in the cash drawer. - if tillconfig.cash_drawer: - printer.kickout(tillconfig.cash_drawer) - refundtext = f"{tillconfig.fc(payments)} had already been "\ - f"put in the cash drawer." - else: - refundtext = "" self._clear() self._redraw() ui.infopopup( - [f"Transaction number {tn} has been cancelled. {refundtext}"], + [f"Transaction number {tn} has been cancelled."], title="Transaction Cancelled", dismiss=keyboard.K_CASH)