feat: add support for dynamic context menu
also add pos cmd, `item_menu_dept` - so a custom button can present list of items for a given department
This commit is contained in:
parent
8fe4c94005
commit
e2e4df4721
|
@ -1,27 +0,0 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaPOS -- Pythonic Point of Sale System
|
||||
# Copyright © 2023-2024 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
WuttaPOS - buttons
|
||||
"""
|
||||
|
||||
from .base import make_button, WuttaButton, WuttaButtonRow
|
69
wuttapos/controls/itemlookup_dept.py
Normal file
69
wuttapos/controls/itemlookup_dept.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
################################################################################
|
||||
#
|
||||
# WuttaPOS -- Pythonic Point of Sale System
|
||||
# Copyright © 2023-2024 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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
"""
|
||||
WuttaPOS - item lookup for department
|
||||
"""
|
||||
|
||||
from .itemlookup import WuttaProductLookup
|
||||
|
||||
|
||||
class WuttaProductLookupByDepartment(WuttaProductLookup):
|
||||
|
||||
def __init__(self, config, department, *args, **kwargs):
|
||||
|
||||
# nb. this forces first query
|
||||
kwargs.setdefault('initial_search', True)
|
||||
|
||||
kwargs.setdefault('show_search', False)
|
||||
|
||||
super().__init__(config, *args, **kwargs)
|
||||
model = self.app.model
|
||||
|
||||
if isinstance(department, model.Department):
|
||||
self.department_key = department.uuid
|
||||
else:
|
||||
self.department_key = department
|
||||
|
||||
# TODO: should somehow combine these 2 approaches, so the user can
|
||||
# still filter items within a department
|
||||
|
||||
# def get_results(self, session, entry):
|
||||
# return self.app.get_products_handler().search_products(session, entry)
|
||||
|
||||
def get_results(self, session, entry):
|
||||
org = self.app.get_org_handler()
|
||||
prod = self.app.get_products_handler()
|
||||
model = self.app.model
|
||||
|
||||
department = org.get_department(session, self.department_key)
|
||||
if not department:
|
||||
raise ValueError(f"department not found: {self.department_key}")
|
||||
|
||||
products = session.query(model.Product)\
|
||||
.filter(model.Product.department == department)\
|
||||
.all()
|
||||
|
||||
products = [prod.normalize_product(p)
|
||||
for p in products]
|
||||
|
||||
return products
|
|
@ -26,7 +26,7 @@ WuttaPOS - button menus
|
|||
|
||||
import flet as ft
|
||||
|
||||
from wuttapos.controls.buttons import make_button
|
||||
from wuttapos.controls.buttons import make_button, WuttaButtonRow
|
||||
|
||||
|
||||
class WuttaMenu(ft.Container):
|
||||
|
@ -58,3 +58,6 @@ class WuttaMenu(ft.Container):
|
|||
kwargs.setdefault('width', self.default_button_size * 2)
|
||||
kwargs.setdefault('pos', self.pos)
|
||||
return make_button(*args, **kwargs)
|
||||
|
||||
def make_button_row(self, *args, **kwargs):
|
||||
return WuttaButtonRow(*args, **kwargs)
|
||||
|
|
|
@ -25,33 +25,9 @@ WuttaPOS - "context" menu
|
|||
"""
|
||||
|
||||
from .base import WuttaMenu
|
||||
from wuttapos.controls.buttons import WuttaButtonRow
|
||||
|
||||
|
||||
class WuttaContextMenu(WuttaMenu):
|
||||
|
||||
def build_controls(self):
|
||||
return [
|
||||
|
||||
WuttaButtonRow([
|
||||
|
||||
self.make_button("Cash",
|
||||
bgcolor='orange',
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'CA'}}),
|
||||
|
||||
self.make_button("Check",
|
||||
bgcolor='orange',
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'CK'}}),
|
||||
]),
|
||||
|
||||
WuttaButtonRow([
|
||||
|
||||
self.make_button("Food Stamps",
|
||||
bgcolor='orange',
|
||||
font_size=34,
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'FS'}}),
|
||||
]),
|
||||
]
|
||||
return []
|
||||
|
|
|
@ -21,18 +21,17 @@
|
|||
#
|
||||
################################################################################
|
||||
"""
|
||||
WuttaPOS - buttons
|
||||
WuttaPOS - menus master control
|
||||
"""
|
||||
|
||||
import flet as ft
|
||||
|
||||
from wuttapos.controls.menus.tenkey import WuttaTenkeyMenu
|
||||
from wuttapos.controls.menus.meta import WuttaMetaMenu
|
||||
from wuttapos.controls.menus.context import WuttaContextMenu
|
||||
from wuttapos.controls.menus.suspend import WuttaSuspendMenu
|
||||
|
||||
|
||||
class WuttaButtonsMaster(ft.Column):
|
||||
class WuttaMenuMaster(ft.Column):
|
||||
"""
|
||||
Base class and default implementation for "buttons master"
|
||||
control. This represents the overall button area in POS view.
|
||||
|
@ -113,7 +112,15 @@ class WuttaButtonsMaster(ft.Column):
|
|||
##############################
|
||||
|
||||
def build_context_menu(self):
|
||||
return WuttaContextMenu(self.config, pos=self.pos)
|
||||
spec = self.config.get('wuttapos.menus.context.spec',
|
||||
default='wuttapos.controls.menus.context:WuttaContextMenu')
|
||||
factory = self.app.load_object(spec)
|
||||
return factory(self.config, pos=self.pos)
|
||||
|
||||
def replace_context_menu(self, menu):
|
||||
controls = menu.build_controls()
|
||||
self.context_menu.content.controls = controls
|
||||
self.update()
|
||||
|
||||
##############################
|
||||
# suspend
|
|
@ -25,7 +25,6 @@ WuttaPOS - "meta" menu
|
|||
"""
|
||||
|
||||
from .base import WuttaMenu
|
||||
from wuttapos.controls.buttons import WuttaButtonRow
|
||||
|
||||
|
||||
class WuttaMetaMenu(WuttaMenu):
|
||||
|
@ -33,7 +32,7 @@ class WuttaMetaMenu(WuttaMenu):
|
|||
def build_controls(self):
|
||||
return [
|
||||
|
||||
WuttaButtonRow([
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("CUST",
|
||||
bgcolor='blue',
|
||||
|
@ -44,7 +43,7 @@ class WuttaMetaMenu(WuttaMenu):
|
|||
pos_cmd='void_dwim'),
|
||||
]),
|
||||
|
||||
WuttaButtonRow([
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("ITEM",
|
||||
bgcolor='blue',
|
||||
|
@ -55,7 +54,7 @@ class WuttaMetaMenu(WuttaMenu):
|
|||
pos_cmd='manager_dwim'),
|
||||
]),
|
||||
|
||||
WuttaButtonRow([
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("OPEN RING",
|
||||
font_size=32,
|
||||
|
@ -67,7 +66,7 @@ class WuttaMetaMenu(WuttaMenu):
|
|||
pos_cmd='no_sale_dwim'),
|
||||
]),
|
||||
|
||||
WuttaButtonRow([
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("Adjust\nPrice",
|
||||
font_size=30,
|
||||
|
|
|
@ -25,7 +25,6 @@ WuttaPOS - "suspend" menu
|
|||
"""
|
||||
|
||||
from .base import WuttaMenu
|
||||
from wuttapos.controls.buttons import WuttaButtonRow
|
||||
|
||||
|
||||
class WuttaSuspendMenu(WuttaMenu):
|
||||
|
@ -33,7 +32,7 @@ class WuttaSuspendMenu(WuttaMenu):
|
|||
def build_controls(self):
|
||||
return [
|
||||
|
||||
WuttaButtonRow([
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("SUSPEND",
|
||||
bgcolor='purple',
|
||||
|
@ -43,4 +42,26 @@ class WuttaSuspendMenu(WuttaMenu):
|
|||
bgcolor='purple',
|
||||
pos_cmd='resume_txn'),
|
||||
]),
|
||||
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("Cash",
|
||||
bgcolor='orange',
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'CA'}}),
|
||||
|
||||
self.make_button("Check",
|
||||
bgcolor='orange',
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'CK'}}),
|
||||
]),
|
||||
|
||||
self.make_button_row([
|
||||
|
||||
self.make_button("Food Stamps",
|
||||
bgcolor='orange',
|
||||
font_size=34,
|
||||
pos_cmd='tender',
|
||||
pos_cmd_kwargs={'tender': {'code': 'FS'}}),
|
||||
]),
|
||||
]
|
||||
|
|
|
@ -34,11 +34,11 @@ 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.itemlookup_dept import WuttaProductLookupByDepartment
|
||||
from wuttapos.controls.deptlookup import WuttaDepartmentLookup
|
||||
from wuttapos.controls.txnlookup import WuttaTransactionLookup
|
||||
from wuttapos.controls.txnitem import WuttaTxnItem
|
||||
from wuttapos.controls.menus.tenkey import WuttaTenkeyMenu
|
||||
from wuttapos.controls.buttons.master import WuttaButtonsMaster
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -568,6 +568,11 @@ class POSView(WuttaView):
|
|||
bgcolor='green',
|
||||
on_click=self.set_quantity_click)
|
||||
|
||||
spec = self.config.get('wuttapos.menus.master.spec',
|
||||
default='wuttapos.controls.menus.master:WuttaMenuMaster')
|
||||
factory = self.app.load_object(spec)
|
||||
self.menu_master = factory(self.config, pos=self)
|
||||
|
||||
return [
|
||||
self.build_header(),
|
||||
|
||||
|
@ -603,7 +608,7 @@ class POSView(WuttaView):
|
|||
ft.Row(
|
||||
[
|
||||
self.items_column,
|
||||
WuttaButtonsMaster(self.config, pos=self),
|
||||
self.menu_master,
|
||||
],
|
||||
vertical_alignment=ft.CrossAxisAlignment.START,
|
||||
),
|
||||
|
@ -1091,6 +1096,15 @@ class POSView(WuttaView):
|
|||
self.authorized_action('pos.override_price', self.adjust_price,
|
||||
message="Adjust Price")
|
||||
|
||||
def cmd_context_menu(self, entry=None, **kwargs):
|
||||
"""
|
||||
Swap out which context menu is currently shown.
|
||||
"""
|
||||
spec = self.config.require(f'wuttapos.menus.{entry}.spec')
|
||||
factory = self.app.load_object(spec)
|
||||
menu = factory(self.config, pos=self)
|
||||
self.menu_master.replace_context_menu(menu)
|
||||
|
||||
def cmd_customer_dwim(self, entry=None, **kwargs):
|
||||
|
||||
# prompt user to replace customer if already set
|
||||
|
@ -1139,6 +1153,40 @@ class POSView(WuttaView):
|
|||
else:
|
||||
self.item_lookup()
|
||||
|
||||
def cmd_item_menu_dept(self, entry=None, **kwargs):
|
||||
"""
|
||||
Show item lookup dialog, restricted to the given department.
|
||||
"""
|
||||
key = entry
|
||||
if not key:
|
||||
raise ValueError("must specify department key")
|
||||
|
||||
org = self.app.get_org_handler()
|
||||
session = self.app.make_session()
|
||||
department = org.get_department(session, key)
|
||||
session.close()
|
||||
if not department:
|
||||
raise ValueError(f"department not found: {key}")
|
||||
|
||||
def select(uuid):
|
||||
self.attempt_add_product(uuid=uuid)
|
||||
dlg.open = False
|
||||
self.reset()
|
||||
|
||||
def cancel(e):
|
||||
dlg.open = False
|
||||
self.reset()
|
||||
|
||||
dlg = ft.AlertDialog(
|
||||
title=ft.Text(f"Item from Department: {department.name}"),
|
||||
content=WuttaProductLookupByDepartment(self.config, department,
|
||||
page=self.page,
|
||||
on_select=select,
|
||||
on_cancel=cancel),
|
||||
)
|
||||
|
||||
self.page.open(dlg)
|
||||
|
||||
def cmd_manager_dwim(self, entry=None, **kwargs):
|
||||
|
||||
def toggle_training(e):
|
||||
|
|
Loading…
Reference in a new issue