diff --git a/application/items/__pycache__/database_items.cpython-313.pyc b/application/items/__pycache__/database_items.cpython-313.pyc index ff16a8e..2fcfacd 100644 Binary files a/application/items/__pycache__/database_items.cpython-313.pyc and b/application/items/__pycache__/database_items.cpython-313.pyc differ diff --git a/application/items/__pycache__/items_API.cpython-313.pyc b/application/items/__pycache__/items_API.cpython-313.pyc index bf6c8b4..18f42d6 100644 Binary files a/application/items/__pycache__/items_API.cpython-313.pyc and b/application/items/__pycache__/items_API.cpython-313.pyc differ diff --git a/application/items/__pycache__/items_processes.cpython-313.pyc b/application/items/__pycache__/items_processes.cpython-313.pyc index 68e8454..a9c1524 100644 Binary files a/application/items/__pycache__/items_processes.cpython-313.pyc and b/application/items/__pycache__/items_processes.cpython-313.pyc differ diff --git a/application/items/database_items.py b/application/items/database_items.py index cf64e14..975018e 100644 --- a/application/items/database_items.py +++ b/application/items/database_items.py @@ -51,7 +51,6 @@ def getItemAllByID(site:str, payload: tuple, convert:bool=True): with open('application/items/sql/getItemAllByID.sql', 'r+') as file: sql = file.read().replace("%%site_name%%", site) record = () - print(sql) try: with psycopg2.connect(**database_config) as conn: with conn.cursor() as cur: @@ -138,7 +137,6 @@ def getModalSKUs(site:str, payload:tuple, convert:bool=True): try: with psycopg2.connect(**database_config) as conn: with conn.cursor() as cur: - print(payload) cur.execute(sql, payload) rows = cur.fetchall() if rows and convert: @@ -906,7 +904,6 @@ def postUpdateItem(site:str, payload:dict): transaction_data = {} database_config = config.config() data = payload['update'] - print(data) for key in data.keys(): for key_2 in data[key].keys(): transaction_data[f"{key_2}_new"] = data[key][key_2] diff --git a/application/items/items_API.py b/application/items/items_API.py index ab661fd..1f1b8c6 100644 --- a/application/items/items_API.py +++ b/application/items/items_API.py @@ -135,7 +135,6 @@ def getModalItems(): site_name = session['selected_site'] offset = (page - 1) * limit recordset, count = database_items.getModalSKUs(site_name, (search_string, limit, offset)) - print(recordset, count) return jsonify({"items":recordset, "end":math.ceil(count/limit), "error":False, "message":"items fetched succesfully!"}) return jsonify({"items":recordset, "end":math.ceil(count/limit), "error":True, "message": f"method {request.method} is not allowed."}) @@ -459,7 +458,6 @@ def saveBarcode(): """ if request.method == "POST": payload = {'barcode': request.get_json()['barcode'], 'update': request.get_json()['update']} - print(payload) site_name = session['selected_site'] try: database_items.updateBarcodesTuple(site_name, payload) diff --git a/application/items/items_processes.py b/application/items/items_processes.py index 2827460..408f8a1 100644 --- a/application/items/items_processes.py +++ b/application/items/items_processes.py @@ -141,16 +141,12 @@ def postLinkedItem(site, payload): 'location_id': location['location_id'] } - print(conn) conn = postAdjustment(site, payload['user_id'], adjustment_payload, conn=conn) - print(conn) #process.postTransaction(conn, site_name, user_id, payload) - print(sum_child_qoh) - + primary_location = database_items.selectItemLocationsTuple(site, (parent_item['id'], parent_item['logistics_info']['primary_location']['id']), convert=True) - print(primary_location) adjustment_payload = { 'item_id': parent_item['id'], @@ -165,9 +161,9 @@ def postLinkedItem(site, payload): 'expires': None, 'location_id': primary_location['location_id'] } - print(conn) + conn=postAdjustment(site, payload['user_id'], adjustment_payload, conn=conn) - print(conn) + itemLink = db.ItemLinkPayload( barcode=child_item['barcode'], link=parent_item['id'], @@ -176,11 +172,10 @@ def postLinkedItem(site, payload): ) _, conn = database_items.postInsertItemLink(site, itemLink.payload(), conn=conn) - print(conn) - print(_['id']) + + _, conn = database_items.postUpdateItemByID(site, {'id': child_item['id'], 'update': {'row_type': 'link'}}, conn=conn) - print(conn) - print(_['id']) + conn.commit() conn.close() diff --git a/application/meal_planner/__pycache__/meal_planner_api.cpython-313.pyc b/application/meal_planner/__pycache__/meal_planner_api.cpython-313.pyc index ea0ba63..e6ecc7a 100644 Binary files a/application/meal_planner/__pycache__/meal_planner_api.cpython-313.pyc and b/application/meal_planner/__pycache__/meal_planner_api.cpython-313.pyc differ diff --git a/application/meal_planner/__pycache__/meal_planner_database.cpython-313.pyc b/application/meal_planner/__pycache__/meal_planner_database.cpython-313.pyc index 81b57f1..4c8bad4 100644 Binary files a/application/meal_planner/__pycache__/meal_planner_database.cpython-313.pyc and b/application/meal_planner/__pycache__/meal_planner_database.cpython-313.pyc differ diff --git a/application/meal_planner/__pycache__/meal_planner_processes.cpython-313.pyc b/application/meal_planner/__pycache__/meal_planner_processes.cpython-313.pyc index 8bfe966..e7d07d1 100644 Binary files a/application/meal_planner/__pycache__/meal_planner_processes.cpython-313.pyc and b/application/meal_planner/__pycache__/meal_planner_processes.cpython-313.pyc differ diff --git a/application/meal_planner/meal_planner_api.py b/application/meal_planner/meal_planner_api.py index c5d6163..8d9d440 100644 --- a/application/meal_planner/meal_planner_api.py +++ b/application/meal_planner/meal_planner_api.py @@ -28,8 +28,9 @@ def getEventsByMonth(): site_name = session['selected_site'] year = int(request.args.get('year', 2025)) month = int(request.args.get('month', 1)) - events = () - events = meal_planner_database.selectPlanEventsByMonth(site_name, (year, month)) + + events = meal_planner_processes.selectPlanEventsByMonth(site_name, year, month) + return jsonify(status=201, message="Events fetched Successfully!", events=events) return jsonify(status=405, message=f"{request.method} is not an allowed method on this endpoint!", events=events) diff --git a/application/meal_planner/meal_planner_database.py b/application/meal_planner/meal_planner_database.py index 6b2a9b1..bec38b0 100644 --- a/application/meal_planner/meal_planner_database.py +++ b/application/meal_planner/meal_planner_database.py @@ -167,6 +167,36 @@ def selectPlanEventByUUID(site: str, payload: tuple, convert=True, conn=None): except Exception as error: raise postsqldb.DatabaseError(error, payload, sql) +def selectConversionsTuple(site: str, payload: tuple, convert=True, conn=None): + """payload=(event_uuid,)""" + self_conn = False + conversions = () + + sql = f"SELECT * FROM {site}_conversions WHERE item_id = %s AND uom_id = %s;" + + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = True + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchone() + if rows and convert: + conversions = postsqldb.tupleDictionaryFactory(cur.description, rows) + if rows and not convert: + conversions = rows + + + if self_conn: + conn.close() + + return conversions + except Exception as error: + raise postsqldb.DatabaseError(error, payload, sql) + def insertPlanEventTuple(site: str, payload: tuple, convert=True, conn=None): self_conn = False event_tuple = () diff --git a/application/meal_planner/meal_planner_processes.py b/application/meal_planner/meal_planner_processes.py index 460614c..5249e63 100644 --- a/application/meal_planner/meal_planner_processes.py +++ b/application/meal_planner/meal_planner_processes.py @@ -5,6 +5,22 @@ from application.meal_planner import meal_planner_database from application import postsqldb, database_payloads import config + +def selectPlanEventsByMonth(site_name, year, month): + events = () + events = meal_planner_database.selectPlanEventsByMonth(site_name, (year, month)) + for event in events: + event['has_missing_ingredients'] = False + for recipe_item in event['recipe_items']: + if recipe_item['item_uom'] != None and recipe_item['ingrediant_uom'] != recipe_item['item_uom']: + conversion = meal_planner_database.selectConversionsTuple(site_name, (recipe_item['item_id'], recipe_item['ingrediant_uom'])) + conv_factor = conversion.get('conv_factor', 1) + qty = float(recipe_item['qty']) / float(conv_factor) + recipe_item['qty'] = qty + if float(qty) > float(recipe_item['quantity_on_hand']): + event['has_missing_ingredients'] = True + return events + def addTakeOutEvent(site, data, user_id, conn=None): event_date_start = datetime.datetime.strptime(data['event_date_start'], "%Y-%m-%d") event_date_end = datetime.datetime.strptime(data['event_date_end'], "%Y-%m-%d") @@ -31,6 +47,9 @@ def addTakeOutEvent(site, data, user_id, conn=None): print(receipt) + attendees = data['attendees'] + cost = float(data['cost'])/int(attendees) + receipt_item = database_payloads.ReceiptItemPayload( type = 'custom', receipt_id=receipt['id'], @@ -39,7 +58,7 @@ def addTakeOutEvent(site, data, user_id, conn=None): name=data['event_shortname'], qty=data['attendees'], uom=1, - data={'cost': data['cost'], 'expires': False} + data={'cost': cost, 'expires': False} ) receipt_item = meal_planner_database.insertReceiptItemsTuple(site, receipt_item.payload(), conn=conn) @@ -57,7 +76,6 @@ def addTakeOutEvent(site, data, user_id, conn=None): ) event = meal_planner_database.insertPlanEventTuple(site, event_payload.payload(), conn=conn) - print(event) if self_conn: conn.commit() conn.close() diff --git a/application/meal_planner/sql/selectPlanEventsByMonth.sql b/application/meal_planner/sql/selectPlanEventsByMonth.sql index 751f8d1..8812530 100644 --- a/application/meal_planner/sql/selectPlanEventsByMonth.sql +++ b/application/meal_planner/sql/selectPlanEventsByMonth.sql @@ -8,22 +8,22 @@ sum_cte AS ( GROUP BY mi.id ), cte_recipe_items AS ( - SELECT rp_item.rp_id, rp_item.qty, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM %%site_name%%_recipe_items rp_item + SELECT items.id AS item_id, rp_item.rp_id, rp_item.qty, rp_item.uom AS ingrediant_uom, item_info.uom AS item_uom, 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 - ), -recipe_missing_items AS ( - SELECT - rp_id, bool_or(qty > quantity_on_hand) AS has_missing_ingredients - FROM cte_recipe_items - GROUP BY rp_id -) - + LEFT JOIN %%site_name%%_items items ON rp_item.item_uuid = items.item_uuid + LEFT JOIN %%site_name%%_item_info item_info ON items.item_info_id = item_info.id + ) + SELECT events.*, COALESCE(row_to_json(recipes.*), '{}') as recipe, - COALESCE(recipe_missing_items.has_missing_ingredients, FALSE) AS has_missing_ingredients + COALESCE(ritems.recipe_items, '{}') as recipe_items FROM %%site_name%%_plan_events events LEFT JOIN %%site_name%%_recipes recipes ON recipes.recipe_uuid = events.recipe_uuid -LEFT JOIN recipe_missing_items ON recipe_missing_items.rp_id = recipes.id +LEFT JOIN LATERAL ( + SELECT array_agg(row_to_json(ri.*)) AS recipe_items + FROM cte_recipe_items ri + WHERE ri.rp_id = recipes.id +) ritems ON TRUE WHERE event_date_end >= make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) AND diff --git a/application/receipts/__pycache__/receipts_api.cpython-313.pyc b/application/receipts/__pycache__/receipts_api.cpython-313.pyc index 8479051..ce4980b 100644 Binary files a/application/receipts/__pycache__/receipts_api.cpython-313.pyc and b/application/receipts/__pycache__/receipts_api.cpython-313.pyc differ diff --git a/application/receipts/__pycache__/receipts_processes.cpython-313.pyc b/application/receipts/__pycache__/receipts_processes.cpython-313.pyc index 159121e..cbe998f 100644 Binary files a/application/receipts/__pycache__/receipts_processes.cpython-313.pyc and b/application/receipts/__pycache__/receipts_processes.cpython-313.pyc differ diff --git a/application/receipts/receipts_api.py b/application/receipts/receipts_api.py index f5dd547..21790f1 100644 --- a/application/receipts/receipts_api.py +++ b/application/receipts/receipts_api.py @@ -252,6 +252,18 @@ def resolveLine(): return jsonify({'error': False, "message": "Line Saved Succesfully"}) return jsonify({'error': True, "message": "Something went wrong while saving line!"}) +@receipt_api.route('/api/resolveServiceLine', methods=["POST"]) +@access_api.login_required +def resolveServiceLine(): + if request.method == "POST": + line_id = int(request.get_json()['line_id']) + site_name = session['selected_site'] + user_id = session['user_id'] + payload = {'line_id': line_id} + receipts_processes.postService(site_name, user_id, payload) + return jsonify({'error': False, "message": "Line Saved Succesfully"}) + return jsonify({'error': True, "message": "Something went wrong while saving line!"}) + @receipt_api.route('/api/postVendorUpdate', methods=["POST"]) @access_api.login_required def postVendorUpdate(): diff --git a/application/receipts/receipts_processes.py b/application/receipts/receipts_processes.py index f49ae11..34a3057 100644 --- a/application/receipts/receipts_processes.py +++ b/application/receipts/receipts_processes.py @@ -146,6 +146,26 @@ def linkItem(site, user_id, data, conn=None): return conn + +def postService(site, user_id, data, conn=None): + self_conn = False + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = False + self_conn = True + + receipt_item = receipts_database.selectReceiptItemsTuple(site, (data['line_id'],), conn=conn) + + receipts_database.updateReceiptItemsTuple(site, {'id': receipt_item['id'], 'update': {'status': "Resolved"}}, conn=conn) + + if self_conn: + conn.commit() + conn.close() + return False + + return conn + def postLine(site, user_id, data, conn=None): self_conn = False if not conn: diff --git a/application/receipts/static/js/receiptHandler.js b/application/receipts/static/js/receiptHandler.js index 610f146..c43c56e 100644 --- a/application/receipts/static/js/receiptHandler.js +++ b/application/receipts/static/js/receiptHandler.js @@ -67,7 +67,11 @@ async function replenishLinesTable(receipt_items) { label_color = 'purple' } if(receipt_items[i].type == 'PLU SKU'){ - label_color = 'blue' + label_color = 'light blue' + } + if(receipt_items[i].type == 'take out'){ + console.log(receipt_items[i]) + label_color = 'brown' } typeCell.innerHTML = `${receipt_items[i].type}` @@ -76,7 +80,6 @@ async function replenishLinesTable(receipt_items) { let operationsCell = document.createElement('td') - let linkOp = document.createElement('a') linkOp.style = "margin-right: 5px;" linkOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') @@ -98,7 +101,7 @@ async function replenishLinesTable(receipt_items) { resolveOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') resolveOp.setAttribute('uk-icon', 'icon: check') resolveOp.onclick = async function(){ - await resolveLine(receipt_items[i].id) + await resolveLine(receipt_items[i].id, receipt_items[i].type) } let denyOp = document.createElement('a') @@ -244,8 +247,12 @@ async function addSKULine(item_id) { } -async function resolveLine(line_id) { - const response = await fetch(`/receipts/api/resolveLine`, { +async function resolveLine(line_id, type) { + let url = '/receipts/api/resolveLine' + if(type==="take out"){ + url = '/receipts/api/resolveServiceLine' + } + const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/logs/database.log b/logs/database.log index 1271c8a..bbcfd87 100644 --- a/logs/database.log +++ b/logs/database.log @@ -655,4 +655,7 @@ sql='SELECT items.item_uuid as item_uuid, items.item_name as item_name, units.fullname AS fullname, units.id AS unit_id, items.links AS linksFROM main_items itemsLEFT JOIN main_item_info item_info ON item_info.id = items.item_info_idLEFT JOIN units ON item_info.uom = units.idWHERE items.search_string LIKE '%%' || %s || '%%' AND items.inactive IS false AND item_info.safety_stock > 0ORDER BY items.item_name LIMIT %s OFFSET %s;') 2025-08-21 18:44:41.870684 --- ERROR --- DatabaseError(message='column "name" does not existLINE 1: SELECT * FROM test_vendors ORDER BY name ASC LIMIT 10 OFFSET... ^', payload=(10, 0), - sql='SELECT * FROM test_vendors ORDER BY name ASC LIMIT %s OFFSET %s;') \ No newline at end of file + sql='SELECT * FROM test_vendors ORDER BY name ASC LIMIT %s OFFSET %s;') +2025-08-23 07:01:48.754381 --- ERROR --- DatabaseError(message='column rp_item.type does not existLINE 11: ... SELECT items.id AS item_id, rp_item.rp_id, rp_item.ty... ^', + payload=(2025, 8), + sql='WITH arguments AS ( SELECT %s AS year, %s AS month),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 items.id AS item_id, rp_item.rp_id, rp_item.type, rp_item.qty, rp_item.uom AS ingrediant_uom, item_info.uom AS item_uom, 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 LEFT JOIN main_items items ON rp_item.item_uuid = items.item_uuid LEFT JOIN main_item_info item_info ON items.item_info_id = item_info.id ) SELECT events.*, COALESCE(row_to_json(recipes.*), '{}') as recipe, COALESCE(ritems.recipe_items, '{}') as recipe_itemsFROM main_plan_events eventsLEFT JOIN main_recipes recipes ON recipes.recipe_uuid = events.recipe_uuidLEFT JOIN LATERAL ( SELECT array_agg(row_to_json(ri.*)) AS recipe_items FROM cte_recipe_items ri WHERE ri.rp_id = recipes.id) ritems ON TRUEWHERE event_date_end >= make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) AND event_date_start < (make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) + INTERVAL '1 month');') \ No newline at end of file