diff --git a/application/__pycache__/postsqldb.cpython-313.pyc b/application/__pycache__/postsqldb.cpython-313.pyc index 8c75ecb..6664be4 100644 Binary files a/application/__pycache__/postsqldb.cpython-313.pyc and b/application/__pycache__/postsqldb.cpython-313.pyc differ diff --git a/application/postsqldb.py b/application/postsqldb.py index dae0f88..ea0fbde 100644 --- a/application/postsqldb.py +++ b/application/postsqldb.py @@ -560,7 +560,7 @@ class RecipesTable: @dataclass class ItemPayload: - uuid: str + item_uuid: str rp_id: int item_type: str item_name:str @@ -571,7 +571,7 @@ class RecipesTable: def payload(self): return ( - self.uuid, + self.item_uuid, self.rp_id, self.item_type, self.item_name, diff --git a/application/recipes/__pycache__/recipes_api.cpython-313.pyc b/application/recipes/__pycache__/recipes_api.cpython-313.pyc index b1810c3..ee5a6fa 100644 Binary files a/application/recipes/__pycache__/recipes_api.cpython-313.pyc and b/application/recipes/__pycache__/recipes_api.cpython-313.pyc differ diff --git a/application/recipes/recipes_api.py b/application/recipes/recipes_api.py index e1ee10e..8157925 100644 --- a/application/recipes/recipes_api.py +++ b/application/recipes/recipes_api.py @@ -110,7 +110,7 @@ def postCustomItem(): site_name = session['selected_site'] rp_id = int(request.get_json()['rp_id']) recipe_item = db.RecipesTable.ItemPayload( - uuid=f"%{int(request.get_json()['rp_id'])}{database_recipes.getUUID(6)}%", + item_uuid=None, rp_id=rp_id, item_type=request.get_json()['item_type'], item_name=request.get_json()['item_name'], @@ -133,7 +133,7 @@ def postSKUItem(): site_name = session['selected_site'] item = database_recipes.getItemData(site_name, (item_id, )) recipe_item = db.RecipesTable.ItemPayload( - uuid=item['barcode'], + item_uuid=item['item_uuid'], rp_id=recipe_id, item_type='sku', item_name=item['item_name'], diff --git a/application/recipes/sql/getItemData.sql b/application/recipes/sql/getItemData.sql index ca66227..94029c3 100644 --- a/application/recipes/sql/getItemData.sql +++ b/application/recipes/sql/getItemData.sql @@ -1,4 +1,4 @@ -SELECT item.id, item.barcode, item.item_name, item.links, item_info.uom_quantity, item_info.uom +SELECT item.id, item.barcode, item.item_name, item.links, item_info.uom_quantity, item_info.uom, item.item_uuid FROM %%site_name%%_items item LEFT JOIN %%site_name%%_item_info item_info ON item_info.id = item.item_info_id WHERE item.id = %s; \ No newline at end of file diff --git a/application/recipes/sql/getRecipes.sql b/application/recipes/sql/getRecipes.sql index 1703d1e..30cc811 100644 --- a/application/recipes/sql/getRecipes.sql +++ b/application/recipes/sql/getRecipes.sql @@ -1,3 +1,17 @@ +WITH sum_cte AS ( + SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum + FROM %%site_name%%_item_locations mil + JOIN %%site_name%%_items mi ON mil.part_id = mi.id + GROUP BY mi.id + ), + cte_recipe_items AS ( + SELECT rp_item.*, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM %%site_name%%_recipe_items rp_item + LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid + ) + + + SELECT *, - (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM %%site_name%%_recipe_items g WHERE rp_id = %%site_name%%_recipes.id) AS rp_items - FROM %%site_name%%_recipes LIMIT %s OFFSET %s; \ No newline at end of file + (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_recipe_items g WHERE g.rp_id = recipes.id) AS rp_items +FROM %%site_name%%_recipes recipes +LIMIT %s OFFSET %s; \ No newline at end of file diff --git a/application/recipes/static/js/recipesListHandler.js b/application/recipes/static/js/recipesListHandler.js index 4bc06a2..cda669f 100644 --- a/application/recipes/static/js/recipesListHandler.js +++ b/application/recipes/static/js/recipesListHandler.js @@ -70,10 +70,27 @@ async function replenishRecipesTable() { let table_body = document.createElement('tbody') for(let i = 0; i < recipes.length; i++){ + console.log(recipes[i]) + + + + let rp_items = recipes[i].rp_items + let rp_items_count = 0 + let rp_items_availble = 0 + + for(let y = 0; y < rp_items.length; y++){ + if (rp_items[y].quantity_on_hand >= rp_items[y].qty && rp_items[y].item_type == "sku"){ + rp_items_availble = rp_items_availble + 1 + } + if (rp_items[y].item_type == "sku"){ + rp_items_count = rp_items_count + 1 + } + } + let table_row = document.createElement('tr') let nameCell = document.createElement('td') - nameCell.innerHTML = recipes[i].name + nameCell.innerHTML = `${recipes[i].name} ${rp_items_availble}/${rp_items_count}` nameCell.setAttribute('class', 'uk-width-1-4') let descriptionCell = document.createElement('td') descriptionCell.innerHTML = recipes[i].description @@ -113,6 +130,25 @@ async function replenishRecipesCards() { console.log('cards') for(let i=0; i < recipes.length; i++){ + + let rp_items = recipes[i].rp_items + let rp_items_count = 0 + let rp_items_availble = 0 + let badge_color = 'uk-label-success' + + for(let y = 0; y < rp_items.length; y++){ + if (rp_items[y].quantity_on_hand >= rp_items[y].qty && rp_items[y].item_type == "sku"){ + rp_items_availble = rp_items_availble + 1 + } + if (rp_items[y].item_type == "sku"){ + rp_items_count = rp_items_count + 1 + } + } + + if (rp_items_availble < rp_items_count){ + badge_color = 'uk-label-danger' + } + let main_div = document.createElement('div') main_div.setAttribute('class', 'uk-card uk-card-default uk-card-small uk-margin') @@ -125,7 +161,7 @@ async function replenishRecipesCards() { let title_div = document.createElement('div') title_div.setAttribute('class', '') - title_div.innerHTML = ` + title_div.innerHTML = `
${rp_items_availble}/${rp_items_count} Ingredients

${recipes[i].name}

` header_grid_div.append(title_div) @@ -144,12 +180,12 @@ async function replenishRecipesCards() { editOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') editOp.innerHTML = ' Edit' editOp.style = "margin-right: 10px;" - editOp.href = `/recipe/edit/${recipes[i].id}` + editOp.href = `/recipes/edit/${recipes[i].id}` let viewOp = document.createElement('a') viewOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') viewOp.innerHTML = ' View' - viewOp.href = `/recipe/view/${recipes[i].id}` + viewOp.href = `/recipes/view/${recipes[i].id}` footer_div.append(editOp, viewOp) diff --git a/application/recipes/templates/recipes_index.html b/application/recipes/templates/recipes_index.html index df42319..ed76676 100644 --- a/application/recipes/templates/recipes_index.html +++ b/application/recipes/templates/recipes_index.html @@ -133,7 +133,7 @@ - +
@@ -143,11 +143,11 @@

Add a Recipe to the system by providing a name for the item and a general description.

- +
- +
diff --git a/logs/database.log b/logs/database.log index 9fd9f24..a1c5208 100644 --- a/logs/database.log +++ b/logs/database.log @@ -67,4 +67,40 @@ sql='WITH passed_id AS (SELECT %s AS passed_id), cte_receipt_items AS ( SELECT items.* , (SELECT COALESCE(row_to_json(un), '{}') FROM units un WHERE un.id = items.uom LIMIT 1) AS uom FROM testa_receipt_items items WHERE items.receipt_id = (SELECT passed_id FROM passed_id) ORDER BY items.name ASC )SELECT (SELECT passed_id FROM passed_id) AS passed_id, testa_receipts.*, logins.username as submitted_by, (SELECT COALESCE(array_agg(row_to_json(ris)), '{}') FROM cte_receipt_items ris) AS receipt_items, row_to_json(testa_vendors.*) as vendorFROM testa_receiptsJOIN logins ON testa_receipts.submitted_by = logins.idLEFT JOIN testa_vendors ON testa_receipts.vendor_id = testa_vendors.id WHERE testa_receipts.id=(SELECT passed_id FROM passed_id)') 2025-08-09 16:20:46.492869 --- ERROR --- DatabaseError(message='relation "testa_recipes" does not existLINE 3: FROM testa_recipes LIMIT 10 OFFSET 0; ^', payload=(10, 0), - sql='SELECT *, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM testa_recipe_items g WHERE rp_id = testa_recipes.id) AS rp_items FROM testa_recipes LIMIT %s OFFSET %s;') \ No newline at end of file + sql='SELECT *, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM testa_recipe_items g WHERE rp_id = testa_recipes.id) AS rp_items FROM testa_recipes LIMIT %s OFFSET %s;') +2025-08-09 19:39:51.459243 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "%812446030134%"LINE 3: VALUES ('%812446030134%', 6, 'sku', 'Rice cooked in bone bro... ^', + payload=('%812446030134%', 6, 'sku', 'Rice cooked in bone broth', 1, 1.0, 8, '{}'), + sql='INSERT INTO main_recipe_items(item_uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 19:39:52.911421 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "%812446030134%"LINE 3: VALUES ('%812446030134%', 6, 'sku', 'Rice cooked in bone bro... ^', + payload=('%812446030134%', 6, 'sku', 'Rice cooked in bone broth', 1, 1.0, 8, '{}'), + sql='INSERT INTO main_recipe_items(item_uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 19:39:53.115678 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "%812446030134%"LINE 3: VALUES ('%812446030134%', 6, 'sku', 'Rice cooked in bone bro... ^', + payload=('%812446030134%', 6, 'sku', 'Rice cooked in bone broth', 1, 1.0, 8, '{}'), + sql='INSERT INTO main_recipe_items(item_uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 19:39:54.082880 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "%812446030134%"LINE 3: VALUES ('%812446030134%', 6, 'sku', 'Rice cooked in bone bro... ^', + payload=('%812446030134%', 6, 'sku', 'Rice cooked in bone broth', 1, 1.0, 8, '{}'), + sql='INSERT INTO main_recipe_items(item_uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 19:39:54.266687 --- ERROR --- DatabaseError(message='invalid input syntax for type uuid: "%812446030134%"LINE 3: VALUES ('%812446030134%', 6, 'sku', 'Rice cooked in bone bro... ^', + payload=('%812446030134%', 6, 'sku', 'Rice cooked in bone broth', 1, 1.0, 8, '{}'), + sql='INSERT INTO main_recipe_items(item_uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 19:56:12.367519 --- ERROR --- DatabaseError(message='column "g" does not existLINE 2: (SELECT COALESCE(array_agg(row_to_json(g)), '{}') ^', + payload=(25, 0), + sql='SELECT *, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM test_recipe_items rp_item LEFT JOIN test_items items ON items.item_uuid = rp_item.item_uuid WHERE rp_id = test_recipes.id) AS rp_itemsFROM test_recipes LIMIT %s OFFSET %s;') +2025-08-09 20:03:06.560301 --- ERROR --- DatabaseError(message='column sum_cte.id does not existLINE 14: LEFT JOIN sum_cte ON items.id = sum_cte.id ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT items.item_uuid, SUM(items_locations.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations items_locations JOIN main_items items ON items_locations.part_id = items.id GROUP BY items.item_uuid )SELECT *, (SELECT COALESCE(array_agg(row_to_json(rp_item)), '{}') FROM main_recipe_items rp_item LEFT JOIN main_items items ON items.item_uuid = rp_item.item_uuid LEFT JOIN sum_cte ON items.id = sum_cte.id WHERE rp_item.rp_id = main_recipes.id) AS rp_itemsFROM main_recipes LIMIT %s OFFSET %s;') +2025-08-09 20:05:35.624889 --- ERROR --- DatabaseError(message='column "sum_cte.total_sum" must appear in the GROUP BY clause or be used in an aggregate functionLINE 11: ...OALESCE(array_agg(row_to_json(rp_item.*)), '{}'), sum_cte.to... ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT mi.id, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id )SELECT *, (SELECT COALESCE(array_agg(row_to_json(rp_item.*)), '{}'), sum_cte.total_sum FROM main_recipe_items rp_item LEFT JOIN main_items items ON items.item_uuid = rp_item.item_uuid LEFT JOIN sum_cte ON items.id = sum_cte.id WHERE rp_item.rp_id = main_recipes.id) AS rp_itemsFROM main_recipes LIMIT %s OFFSET %s;') +2025-08-09 20:17:43.956632 --- ERROR --- DatabaseError(message='missing FROM-clause entry for table "rp_item"LINE 17: LEFT JOIN cte_recipe_items rp_items ON rp_item.rp_id = recip... ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ), cte_recipe_items AS ( SELECT rp_item.*, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid )SELECT *, (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items rp_it) AS rp_itemsFROM main_recipes recipesLEFT JOIN cte_recipe_items rp_items ON rp_item.rp_id = recipes.id LIMIT %s OFFSET %s;') +2025-08-09 20:17:56.230829 --- ERROR --- DatabaseError(message='missing FROM-clause entry for table "rp_item"LINE 17: LEFT JOIN cte_recipe_items rp_items ON rp_item.rp_id = recip... ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ), cte_recipe_items AS ( SELECT rp_item.*, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid )SELECT *, (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items rp_it) AS testFROM main_recipes recipesLEFT JOIN cte_recipe_items rp_items ON rp_item.rp_id = recipes.id LIMIT %s OFFSET %s;') +2025-08-09 20:18:34.287696 --- ERROR --- DatabaseError(message='relation "rp_items" does not existLINE 15: ... (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items r... ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ), cte_recipe_items AS ( SELECT rp_item.*, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid )SELECT *, (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items rp_its) AS testFROM main_recipes recipesLEFT JOIN cte_recipe_items rp_items ON rp_items.rp_id = recipes.id LIMIT %s OFFSET %s;') +2025-08-09 20:19:12.850845 --- ERROR --- DatabaseError(message='relation "rp_items" does not existLINE 15: ... (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items r... ^', + payload=(25, 0), + sql='WITH sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ), cte_recipe_items AS ( SELECT rp_item.*, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid )SELECT *, (SELECT COALESCE(row_to_json(rp_it), '{}') FROM rp_items rp_its) AS testFROM main_recipes recipesLEFT JOIN cte_recipe_items ON cte_recipe_items.rp_id = recipes.id LIMIT %s OFFSET %s;') \ No newline at end of file diff --git a/static/css/dark-mode.css b/static/css/dark-mode.css index d7ba9df..009f683 100644 --- a/static/css/dark-mode.css +++ b/static/css/dark-mode.css @@ -231,4 +231,14 @@ select, option { .instruction-list{ list-style-type: none; padding: 0; +} + +.uk-label.uk-label-success { + background-color: rgb(54, 160, 98); + color: var(--background-text) +} + +.uk-label.uk-label-danger { + background-color: #b6596a; + color: var(--background-text) } \ No newline at end of file