diff --git a/wuttapos/controls/deptlookup.py b/wuttapos/controls/deptlookup.py new file mode 100644 index 0000000..b378efd --- /dev/null +++ b/wuttapos/controls/deptlookup.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# WuttaPOS -- Pythonic Point of Sale System +# Copyright © 2023 Lance Edgar +# +# This file is part of WuttaPOS. +# +# WuttaPOS is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# WuttaPOS is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# WuttaPOS. If not, see . +# +################################################################################ +""" +WuttaPOS - department lookup control +""" + +from .lookup import WuttaLookup + + +class WuttaDepartmentLookup(WuttaLookup): + + def __init__(self, *args, **kwargs): + + # nb. this forces first query + kwargs.setdefault('initial_search', '') + kwargs.setdefault('allow_empty_query', True) + + super().__init__(*args, **kwargs) + + def get_results_columns(self): + return [ + "Number", + "Name", + ] + + def get_results(self, session, entry): + model = self.app.model + query = session.query(model.Department)\ + .order_by(model.Department.number) + + if entry: + query = query.filter(model.Department.name.ilike(f'%{entry}%')) + + departments = [] + for dept in query: + departments.append({ + 'uuid': dept.uuid, + 'number': str(dept.number), + 'name': dept.name, + }) + return departments + + def make_result_row(self, dept): + return [ + dept['number'], + dept['name'], + ] diff --git a/wuttapos/controls/lookup.py b/wuttapos/controls/lookup.py index 7f66a4c..5a3f083 100644 --- a/wuttapos/controls/lookup.py +++ b/wuttapos/controls/lookup.py @@ -41,6 +41,7 @@ class WuttaLookup(WuttaControl): def __init__(self, *args, **kwargs): self.initial_search = kwargs.pop('initial_search', None) + self.allow_empty_query = kwargs.pop('allow_empty_query', False) self.on_select = kwargs.pop('on_select', None) self.on_cancel = kwargs.pop('on_cancel', None) super().__init__(*args, **kwargs) @@ -165,7 +166,7 @@ class WuttaLookup(WuttaControl): raise NotImplementedError def did_mount(self): - if self.initial_search: + if self.initial_search is not None: self.searchbox.value = self.initial_search self.initial_search = None # only do it once self.update() @@ -201,11 +202,11 @@ class WuttaLookup(WuttaControl): raise NotImplementedError def make_result_row(self, obj): - raise NotImplementedError + return obj def lookup(self, e=None): entry = self.searchbox.value - if not entry: + if not entry and not self.allow_empty_query: self.searchbox.focus() self.update() return diff --git a/wuttapos/controls/txnitem.py b/wuttapos/controls/txnitem.py index 6bbd2b2..9ad380c 100644 --- a/wuttapos/controls/txnitem.py +++ b/wuttapos/controls/txnitem.py @@ -48,7 +48,8 @@ class WuttaTxnItem(WuttaControl): self.minor_style = ft.TextStyle(size=int(self.font_size * 0.8), italic=True) - if self.row.row_type == self.enum.POS_ROW_TYPE_SELL: + if self.row.row_type in (self.enum.POS_ROW_TYPE_SELL, + self.enum.POS_ROW_TYPE_OPEN_RING): return self.build_item_sell() elif self.row.row_type in (self.enum.POS_ROW_TYPE_TENDER, @@ -129,7 +130,8 @@ class WuttaTxnItem(WuttaControl): self.minor_style.color = None self.minor_style.decoration = None - if self.row.row_type == self.enum.POS_ROW_TYPE_SELL: + if self.row.row_type in (self.enum.POS_ROW_TYPE_SELL, + self.enum.POS_ROW_TYPE_OPEN_RING): self.quantity.text = self.app.render_quantity(self.row.quantity) self.txn_price.text = self.app.render_currency(self.row.txn_price) self.sales_total.text = self.app.render_currency(self.row.sales_total) @@ -140,7 +142,8 @@ class WuttaTxnItem(WuttaControl): self.sales_total_style.decoration = ft.TextDecoration.LINE_THROUGH self.sales_total_style.weight = None else: - if self.row.txn_price < self.row.reg_price: + if (self.row.row_type == self.enum.POS_ROW_TYPE_SELL + and self.row.txn_price < self.row.reg_price): self.sales_total_style.color = 'blue' else: self.sales_total_style.color = None diff --git a/wuttapos/views/pos.py b/wuttapos/views/pos.py index c0116db..8cb47f3 100644 --- a/wuttapos/views/pos.py +++ b/wuttapos/views/pos.py @@ -34,6 +34,7 @@ from .base import WuttaView from wuttapos.controls.loginform import WuttaLoginForm from wuttapos.controls.custlookup import WuttaCustomerLookup from wuttapos.controls.itemlookup import WuttaProductLookup +from wuttapos.controls.deptlookup import WuttaDepartmentLookup from wuttapos.controls.txnitem import WuttaTxnItem from wuttapos.controls.tenkey import WuttaTenkeyMenu @@ -168,8 +169,7 @@ class POSView(WuttaView): bgcolor='yellow') else: - self.add_row_item(row) - self.items.scroll_to(offset=-1, duration=100) + self.add_row_item(row, scroll=True) self.refresh_totals(batch) self.reset() @@ -657,15 +657,16 @@ class POSView(WuttaView): ), ft.Row( [ - meta_button("Adjust\nPrice", font_size=30, bgcolor='yellow', - on_click=self.adjust_price_click), + meta_button("OPEN RING", font_size=32, bgcolor='blue', + on_click=self.open_ring_click), meta_button("NO SALE", bgcolor='yellow', on_click=self.nosale_click), ], spacing=0, ), ft.Row( [ - meta_button("TODO", bgcolor='blue', on_click=self.not_supported), + meta_button("Adjust\nPrice", font_size=30, bgcolor='yellow', + on_click=self.adjust_price_click), meta_button("(TEST ERROR)", bgcolor='red', on_click=self.not_supported, font_size=24, data={'error': True}), ], @@ -856,6 +857,54 @@ class POSView(WuttaView): self.show_snackbar(text, bgcolor='yellow') self.page.update() + def open_ring_click(self, e): + value = self.main_input.value or None + if not value: + self.show_snackbar("Must first enter an amount") + self.reset() + return + + try: + amount = decimal.Decimal(value) + except decimal.InvalidOperation: + self.show_snackbar("Amount is not valid") + self.reset() + return + + def select(uuid): + session = self.app.make_session() + user = self.get_current_user(session) + batch = self.get_current_batch(session, user=user) + handler = self.get_batch_handler() + + quantity = 1 + if self.set_quantity.data is not None: + quantity = self.set_quantity.data + + row = handler.add_open_ring(batch, uuid, amount, quantity=quantity, user=user) + session.commit() + + self.add_row_item(row, scroll=True) + self.refresh_totals(batch) + session.close() + + dlg.open = False + self.reset() + + def cancel(e): + dlg.open = False + self.reset(clear_quantity=False) + + dlg = ft.AlertDialog( + modal=True, + title=ft.Text(f"Department Lookup - for {self.app.render_currency(amount)} OPEN RING"), + content=WuttaDepartmentLookup(self.config, on_select=select, on_cancel=cancel), + ) + + self.page.dialog = dlg + dlg.open = True + self.page.update() + def adjust_price_click(self, e): if not len(self.items.controls): @@ -1014,10 +1063,11 @@ class POSView(WuttaView): self.show_snackbar("TODO: Drawer Kick", bgcolor='yellow') self.page.update() - def add_row_item(self, row): + def add_row_item(self, row, scroll=False): # TODO: row types ugh if row.row_type not in (self.enum.POS_ROW_TYPE_SELL, + self.enum.POS_ROW_TYPE_OPEN_RING, self.enum.POS_ROW_TYPE_TENDER, self.enum.POS_ROW_TYPE_CHANGE_BACK): return @@ -1032,6 +1082,9 @@ class POSView(WuttaView): key=row.uuid, )) + if scroll: + self.items.scroll_to(offset=-1, duration=100) + def list_item_click(self, e): self.select_txn_item(e.control) @@ -1142,7 +1195,8 @@ class POSView(WuttaView): # cannot void an already void line self.show_snackbar("LINE ALREADY VOID", bgcolor='yellow') - elif row.row_type != self.enum.POS_ROW_TYPE_SELL: + elif row.row_type not in (self.enum.POS_ROW_TYPE_SELL, + self.enum.POS_ROW_TYPE_OPEN_RING): # cannot void line unless of type 'sell' self.show_snackbar("LINE DOES NOT ALLOW VOID", bgcolor='yellow') @@ -1275,7 +1329,7 @@ class POSView(WuttaView): # update screen to reflect new items/balance for row in rows: - self.add_row_item(row) + self.add_row_item(row, scroll=True) self.refresh_totals(batch) # executed batch means txn was finalized