From 53e79f3b18f5b0c6eb0e2c139f71046ff2f7af37 Mon Sep 17 00:00:00 2001 From: Stephen Early Date: Wed, 24 Jan 2024 17:07:03 +0000 Subject: [PATCH] Optionally restrict stock label printing based on item unit Add an option to control printing of stock labels for items that will not be individually checked during a stock take. This option defaults to "off". Add an option to print a delivery checklist on the receipt printer. Closes #269 on github. --- quicktill/delivery.py | 44 ++++++++++++++++++++++++++++++++++++++++--- quicktill/printer.py | 27 +++++++++++++++++++------- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/quicktill/delivery.py b/quicktill/delivery.py index 4c05da1..81f8cde 100644 --- a/quicktill/delivery.py +++ b/quicktill/delivery.py @@ -1,7 +1,9 @@ from . import ui, stock, td, keyboard, printer, tillconfig, stocktype from . import user, usestock +from . import config from decimal import Decimal from .models import Delivery, Supplier, StockUnit, StockItem +from .models import StockType, Unit from .models import penny from .plugins import InstancePluginMount import datetime @@ -12,6 +14,18 @@ log = logging.getLogger(__name__) +# Do we print stock labels for items where +# StockItem.stocktype.unit.stocktake_by_items is False? (I.e. where +# individual stock items will not be checked, only a total will be +# entered.) +label_everything = config.BooleanConfigItem( + 'core:label_everything', False, display_name="Label all stock items?", + description="Should stock labels be printed for all items in a delivery, " + "including items that will not be checked individually during a stock " + "take? (I.e. where the Unit for the item's stock type has the stock take " + "method set to 'total quantity'.)") + + @user.permission_required('deliveries', "List deliveries") def deliverymenu(): """Display a list of deliveries and call the edit function. @@ -241,13 +255,37 @@ def deleteline(self): title="Confirm Delete", keymap={keyboard.K_CASH: (self.reallydeleteline, None, True)}) + def _label_query(self): + q = td.s.query(StockItem)\ + .join(StockType)\ + .join(Unit)\ + .filter(StockItem.deliveryid == self.dn)\ + .order_by(StockItem.id) + if not label_everything(): + q = q.filter(Unit.stocktake_by_items == True) + return q + + def _print_labels(self, label_printer): + labels = self._label_query().all() + with label_printer as f: + for l in labels: + printer.stock_label(f, l) + def printout(self): if self.dn is None: return - menu = [(f"Print labels on {x}", - printer.label_print_delivery, (x, self.dn)) - for x in tillconfig.label_printers] + num_labels = self._label_query().count() + menu = [] + if tillconfig.receipt_printer: + menu.append(("Print a delivery checklist", + printer.print_delivery_checklist, + (tillconfig.receipt_printer, self.dn))) + + if num_labels > 0: + menu.extend((f"Print labels on {x}", self._print_labels, (x,)) + for x in tillconfig.label_printers) ui.automenu(menu, title="Delivery print options", + blurb=[f"There are {num_labels} stock labels to print."], colour=ui.colour_confirm) def reallyconfirm(self): diff --git a/quicktill/printer.py b/quicktill/printer.py index 5d8c693..a3a8ef2 100644 --- a/quicktill/printer.py +++ b/quicktill/printer.py @@ -235,6 +235,26 @@ def print_deferred_payment_wrapper(printer, trans, paytype, amount, user_name): d.printline() +def print_delivery_checklist(printer, dn): + d = td.s.query(Delivery).get(dn) + if not d: + return + printtime = ui.formattime(now()) + with printer as p: + p.printline(f"\tDelivery {dn} checklist") + p.printline(f"\tFrom {d.supplier.name}") + if d.docnumber: + p.printline(f"\tRef {d.docnumber}") + p.printline(f"\tPrinted {printtime}") + p.printline() + for item in d.items: + p.printline(f"{item.id}: {item.stocktype}") + p.printline(f"{item.description}\t\t[ ]") + p.printline() + p.printline() + p.printline() + + def stock_label(f, d): """Draw a stock label (d) on a PDF canvas (f). d is a Stock instance """ @@ -272,13 +292,6 @@ def fits(s): f.showPage() -def label_print_delivery(p, delivery): - d = td.s.query(Delivery).get(delivery) - with p as f: - for s in d.items: - stock_label(f, s) - - def print_restock_list(printer, rl): """ Print a list of (stockline,stockmovement) tuples.