diff --git a/application/items/__pycache__/database_items.cpython-312.pyc b/application/items/__pycache__/database_items.cpython-312.pyc index dc314a3..2fb752e 100644 Binary files a/application/items/__pycache__/database_items.cpython-312.pyc and b/application/items/__pycache__/database_items.cpython-312.pyc differ diff --git a/application/items/__pycache__/items_API.cpython-312.pyc b/application/items/__pycache__/items_API.cpython-312.pyc index a830ec9..e03a95a 100644 Binary files a/application/items/__pycache__/items_API.cpython-312.pyc and b/application/items/__pycache__/items_API.cpython-312.pyc differ diff --git a/application/items/database_items.py b/application/items/database_items.py index de3fa7c..bf97b1d 100644 --- a/application/items/database_items.py +++ b/application/items/database_items.py @@ -56,5 +56,29 @@ def getItemAllByID(site:str, payload: tuple, convert:bool=True): if rows and not convert: record = rows return record + except Exception as error: + postsqldb.DatabaseError(error, payload, sql) + +def getItemsWithQOH(site:str, payload: tuple, convert:bool=True): + database_config = config.config() + with open('application/items/sql/getItemsWithQOH.sql', 'r+') as file: + sql = file.read().replace("%%site_name%%", site).replace("%%sort_order%%", payload[3]) + payload = list(payload) + payload.pop(3) + sql_count = f"SELECT COUNT(*) FROM {site}_items WHERE search_string LIKE '%%' || %s || '%%';" + recordset = () + count = 0 + try: + with psycopg2.connect(**database_config) as conn: + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchall() + if rows and convert: + recordset = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows] + if rows and not convert: + recordset = rows + cur.execute(sql_count, (payload[0],)) + count = cur.fetchone()[0] + return recordset, count except Exception as error: postsqldb.DatabaseError(error, payload, sql) \ No newline at end of file diff --git a/application/items/items_API.py b/application/items/items_API.py index d6c2956..2e72052 100644 --- a/application/items/items_API.py +++ b/application/items/items_API.py @@ -15,6 +15,7 @@ def itemLink(parent_id, id): return render_template("items/itemlink.html", current_site=session['selected_site'], sites=sites, proto={'referrer': request.referrer}, id=id) @items_api.route("/item/getTransactions", methods=["GET"]) +@login_required def getTransactions(): """ GET a subquery of transactions by passing a logistics_info_id, limit, and page --- @@ -35,6 +36,7 @@ def getTransactions(): return jsonify({"transactions": recordset, "end": math.ceil(count/limit), "error": True, "message": f"method {request.method} is not allowed."}) @items_api.route("/item/getTransaction", methods=["GET"]) +@login_required def getTransaction(): """ GET a transaction from the system by passing an ID --- @@ -60,6 +62,7 @@ def getTransaction(): return jsonify({"transaction": transaction, "error": True, "message": f"method {request.method} is not allowed."}) @items_api.route("/item/getItem", methods=["GET"]) +@login_required def get_item(): """ GET item from system by passing its ID --- @@ -83,33 +86,66 @@ def get_item(): return jsonify({'item': item, 'error': False, 'message': ''}) return jsonify({'item': item, 'error': True, 'message': f'method {request.method} not allowed.'}) - @items_api.route("/item/getItemsWithQOH", methods=['GET']) @login_required def pagninate_items(): - pantry_inventory = [] - count = {'count': 0} + """ GET items from the system by passing a page, limit, search_string, sort, and order + --- + parameters: + - in: query + name: page + schema: + type: integer + default: 1 + description: page number for offset + - in: query + name: limit + schema: + type: integer + default: 50 + description: number of records to grab + - in: query + name: search_string + schema: + type: string + default: '' + description: string to look for in column search_string + - in: query + name: sort + schema: + type: string + default: '' + description: items table column to sort by + - in: query + name: order + schema: + type: string + enum: ['ASC', 'DESC'] + default: 'ASC' + description: Order to sort items table sort parameter by + responses: + 200: + description: Items received successfully. + """ + items = [] + count = 0 if request.method == "GET": page = int(request.args.get('page', 1)) limit = int(request.args.get('limit', 10)) search_string = str(request.args.get('search_text', "")) sort = request.args.get('sort', "") order = request.args.get('order', "") - - view = request.args.get('view', "") site_name = session['selected_site'] offset = (page - 1) * limit if sort == 'total_qoh': sort_order = f"{sort} {order}" else: - sort_order = f"{site_name}_items.{sort} {order}" - print(sort_order) - database_config = config() - with psycopg2.connect(**database_config) as conn: - pantry_inventory, count = database.getItemsWithQOH(conn, site_name, (search_string, limit, offset, sort_order), convert=True) + sort_order = f"item.{sort} {order}" - return jsonify({'items': pantry_inventory, "end": math.ceil(count['count']/limit), 'error':False, 'message': 'Items Loaded Successfully!'}) - return jsonify({'items': pantry_inventory, "end": math.ceil(count['count']/limit), 'error':True, 'message': 'There was a problem loading the items!'}) + items, count = database_items.getItemsWithQOH(site_name, (search_string, limit, offset, sort_order)) + + return jsonify({'items': items, "end": math.ceil(count/limit), 'error':False, 'message': 'Items Loaded Successfully!'}) + return jsonify({'items': items, "end": math.ceil(count/limit), 'error':True, 'message': 'There was a problem loading the items!'}) @items_api.route('/item/getModalItems', methods=["GET"]) @login_required diff --git a/application/items/sql/getItemsWithQOH.sql b/application/items/sql/getItemsWithQOH.sql new file mode 100644 index 0000000..c7d4b8a --- /dev/null +++ b/application/items/sql/getItemsWithQOH.sql @@ -0,0 +1,16 @@ +WITH sum_cte AS ( + SELECT mi.id, 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 + ) + +SELECT item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullname +FROM %%site_name%%_items item +LEFT JOIN sum_cte ON item.id = sum_cte.id +LEFT JOIN %%site_name%%_item_info item_info ON item.item_info_id = item_info.id +LEFT JOIN units u ON item_info.uom = u.id +WHERE item.search_string LIKE '%%' || %s || '%%' +ORDER BY %%sort_order%% +LIMIT %s OFFSET %s; + diff --git a/database.log b/database.log index d718389..e0dc025 100644 --- a/database.log +++ b/database.log @@ -1874,4 +1874,28 @@ sql='SELECT * FROM main_transactions WHERE logistics_info_id=%s LIMIT %s OFFSET %s;') 2025-04-27 12:35:10.632770 --- ERROR --- DatabaseError(message=''int' object does not support indexing', payload=(1, 50, 0), - sql='SELECT * FROM main_transactions WHERE logistics_info_id=%s LIMIT %s OFFSET %s;') \ No newline at end of file + sql='SELECT * FROM main_transactions WHERE logistics_info_id=%s LIMIT %s OFFSET %s;') +2025-04-27 13:18:16.283058 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:19:31.121839 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:19:53.062262 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:20:02.283977 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:20:51.587376 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:21:15.614158 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:22:17.783755 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "main_items"LINE 14: ORDER BY main_items.id ASC ^HINT: Perhaps you meant to reference the table alias "item".', + payload=['', 50, 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY main_items.id ASCLIMIT %s OFFSET %s;') +2025-04-27 13:32:50.773052 --- ERROR --- DatabaseError(message='syntax error at or near "5"LINE 15: LIMIT 5 OFFSET 5; ^', + payload=['', 5, 5], + 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 item.id, item.description, item.item_name, sum_cte.total_sum as total_qoh, u.fullnameFROM main_items itemLEFT JOIN sum_cte ON item.id = sum_cte.idLEFT JOIN main_item_info item_info ON item.item_info_id = item_info.idLEFT JOIN units u ON item_info.uom = u.idWHERE item.search_string LIKE '%%' || %s || '%%'ORDER BY item. LIMIT %s OFFSET %s;') \ No newline at end of file diff --git a/static/handlers/ItemListHandler.js b/static/handlers/ItemListHandler.js index 8e40e98..3173ab3 100644 --- a/static/handlers/ItemListHandler.js +++ b/static/handlers/ItemListHandler.js @@ -203,7 +203,7 @@ async function updateTableElements(){ descriptionCell.setAttribute('class', 'uk-text-truncate uk-table-expand uk-visible@m') let qtyUOMCell = document.createElement('td') - qtyUOMCell.innerHTML = `${parseFloat(items[i].total_qoh)} ${items[i].uom.fullname}` + qtyUOMCell.innerHTML = `${parseFloat(items[i].total_qoh)} ${items[i].fullname}` let opsCell = document.createElement('td') opsCell.setAttribute('class', 'uk-width-1-4') @@ -255,7 +255,7 @@ async function updateListElements(){ header.classList.add('uk-card-header') header.style = "border-radius: 0px, 10px, 0px, 10px;" - header.innerHTML = `