From bbd51978cbaec30588992d408ecd55d1e5da33c2 Mon Sep 17 00:00:00 2001 From: Paul Brinkmeier Date: Tue, 6 Jun 2023 16:51:28 +0200 Subject: [PATCH] Implement some more python features --- .gitignore | 2 + py/jon/db/__init__.py | 7 ++- py/jon/db/add_views.sql | 59 +++++++++++++++++++++++ py/jon/db/get_inventory_overview.sql | 19 ++------ py/jon/db/get_item_by_id.sql | 18 +------ py/jon/db/get_items_by_barcode.sql | 5 +- py/jon/db/get_snacks_by_item_id.sql | 3 ++ py/jon/templates/base.html | 11 ++++- py/jon/templates/inventory/index.html | 18 +++---- py/jon/templates/inventory/read_item.html | 52 +++++++++++--------- static/jon.css | 8 +++ 11 files changed, 133 insertions(+), 69 deletions(-) create mode 100644 py/jon/db/add_views.sql diff --git a/.gitignore b/.gitignore index 75fe1dc..a97ea05 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .setjonpass elm-stuff static/jon.js +__pycache__ +*.swp diff --git a/py/jon/db/__init__.py b/py/jon/db/__init__.py index 6a9150b..b56e274 100644 --- a/py/jon/db/__init__.py +++ b/py/jon/db/__init__.py @@ -10,6 +10,7 @@ def get_db(): # TODO: Make this configurable and use a default that works # on the pool computers. g.db = psycopg2.connect("host=localhost dbname=garfield") + run_query_on(g.db, "add_views.sql", None) return g.db @@ -25,8 +26,10 @@ def init_app(app): def run_query(query_name, params=None): - db = get_db() - + return run_query_on(get_db(), query_name, params) + + +def run_query_on(db, query_name, params): query = (Path(__file__).parent / Path(query_name)).read_text() cursor = db.cursor(cursor_factory=RealDictCursor) diff --git a/py/jon/db/add_views.sql b/py/jon/db/add_views.sql new file mode 100644 index 0000000..684fde9 --- /dev/null +++ b/py/jon/db/add_views.sql @@ -0,0 +1,59 @@ +-- Modified version of garfield.inventory_item_overview. + +CREATE TEMPORARY VIEW all_inventory_item_overview AS +SELECT + item_id, + inventory_items.item_barcode, + inventory_items.bought, + inventory_items.name, + inventory_items.sales_units, + inventory_items.unit_price, + inventory_items.available, + inventory_items.item_group, + inventory_items.location, + inventory_item_groups.group_name, + COALESCE(b.sales::numeric, 0::numeric) - COALESCE(cancel.count::numeric, 0::numeric) AS sales, + inventory_items.sales_units::numeric - COALESCE(b.sales, 0::bigint)::numeric + COALESCE(c.delta, 0::numeric) + COALESCE(cancel.count::numeric, 0::numeric) AS units_left, + COALESCE(c.delta, 0::numeric) AS correction_delta, + COALESCE(m.mappings::numeric, 0::numeric) AS active_mappings, + m.mappings_array AS active_mappings_array, + locations.location_name +FROM garfield.inventory_items + JOIN garfield.locations ON inventory_items.location = locations.location_id + LEFT JOIN garfield.inventory_item_groups ON inventory_item_groups.group_id = inventory_items.item_group + LEFT JOIN ( + SELECT + snack_sales_log.inventory_line AS item_id, + count(*) AS sales + FROM garfield.snack_sales_log + WHERE snack_sales_log.inventory_line IS NOT NULL + AND snack_sales_log.type_id::text = 'SNACK_BUY'::text + GROUP BY snack_sales_log.inventory_line + ) b USING (item_id) + LEFT JOIN ( + SELECT + snack_sales_log.inventory_line AS item_id, + count(*) AS count + FROM garfield.snack_sales_log + WHERE snack_sales_log.inventory_line IS NOT NULL + AND snack_sales_log.type_id::text = 'SNACK_CANCEL'::text + GROUP BY snack_sales_log.inventory_line + ) cancel USING (item_id) + LEFT JOIN ( + SELECT + inventory_correction.item_id, + sum(inventory_correction.delta) AS delta + FROM garfield.inventory_correction + GROUP BY inventory_correction.item_id + ) c USING (item_id) + LEFT JOIN ( + SELECT + count(inventory_map.snack_id) AS mappings, + array_agg(inventory_map.snack_id) AS mappings_array, + inventory_map.inventory_id AS item_id + FROM garfield.inventory_map + JOIN garfield.snacks_available ON snacks_available.snack_available AND snacks_available.snack_id = inventory_map.snack_id + GROUP BY inventory_map.inventory_id + ) m USING (item_id) +ORDER BY inventory_items.name; + diff --git a/py/jon/db/get_inventory_overview.sql b/py/jon/db/get_inventory_overview.sql index 4c50225..fe2a44f 100644 --- a/py/jon/db/get_inventory_overview.sql +++ b/py/jon/db/get_inventory_overview.sql @@ -1,19 +1,8 @@ SELECT - inventory_items.item_id, - inventory_items.item_barcode, - inventory_items.name, - inventory_items.unit_price, - inventory_items.bought, - inventory_item_overview.group_name, - inventory_item_overview.units_left, - inventory_item_overview.correction_delta, - inventory_item_overview.sales_units, - inventory_item_overview.active_mappings, - inventory_item_overview.location_name -FROM garfield.inventory_item_overview -LEFT JOIN garfield.inventory_items USING (item_id) -WHERE - (%(location_id)s IS NULL OR inventory_items.location = %(location_id)s) + * +FROM all_inventory_item_overview +WHERE (%(location_id)s IS NULL OR location = %(location_id)s) + AND available ORDER BY name ASC, item_barcode DESC, diff --git a/py/jon/db/get_item_by_id.sql b/py/jon/db/get_item_by_id.sql index fe427f2..58cfdae 100644 --- a/py/jon/db/get_item_by_id.sql +++ b/py/jon/db/get_item_by_id.sql @@ -1,18 +1,4 @@ SELECT - inventory_items.item_id, - inventory_items.available, - inventory_items.item_barcode, - inventory_items.name, - inventory_items.unit_price, - inventory_items.bought, - inventory_items.item_group, - inventory_items.location, - inventory_item_overview.group_name, - inventory_item_overview.units_left, - inventory_item_overview.correction_delta, - inventory_item_overview.sales_units, - inventory_item_overview.active_mappings, - inventory_item_overview.location_name -FROM garfield.inventory_item_overview -LEFT JOIN garfield.inventory_items USING (item_id) + * +FROM all_inventory_item_overview WHERE item_id = %(item_id)s diff --git a/py/jon/db/get_items_by_barcode.sql b/py/jon/db/get_items_by_barcode.sql index 415d63d..6a28427 100644 --- a/py/jon/db/get_items_by_barcode.sql +++ b/py/jon/db/get_items_by_barcode.sql @@ -1,9 +1,6 @@ SELECT * -FROM garfield.inventory_item_overview -LEFT JOIN garfield.inventory_items USING (item_id) -LEFT JOIN garfield.locations ON location = location_id -LEFT JOIN garfield.inventory_item_groups ON item_group = group_id +FROM all_inventory_item_overview WHERE item_barcode = %(item_barcode)s AND location = %(location_id)s ORDER BY available DESC, bought DESC diff --git a/py/jon/db/get_snacks_by_item_id.sql b/py/jon/db/get_snacks_by_item_id.sql index c4731cd..472491f 100644 --- a/py/jon/db/get_snacks_by_item_id.sql +++ b/py/jon/db/get_snacks_by_item_id.sql @@ -6,3 +6,6 @@ LEFT JOIN garfield.snacks_available USING (snack_id) LEFT JOIN garfield.tax_groups USING (tax_group_id) LEFT JOIN garfield.locations USING (location_id) WHERE inventory_id = %(item_id)s +ORDER BY + snack_available DESC, + snack_timestamp DESC diff --git a/py/jon/templates/base.html b/py/jon/templates/base.html index 88c4212..afa7b0c 100644 --- a/py/jon/templates/base.html +++ b/py/jon/templates/base.html @@ -4,6 +4,9 @@ jon