items_api.paginate_items updated to new schema

This commit is contained in:
Jadowyne Ulve 2025-04-27 13:38:20 -05:00
parent fdd156c3ce
commit 6dbe5752ad
7 changed files with 115 additions and 15 deletions

View File

@ -58,3 +58,27 @@ def getItemAllByID(site:str, payload: tuple, convert:bool=True):
return record return record
except Exception as error: except Exception as error:
postsqldb.DatabaseError(error, payload, sql) 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)

View File

@ -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) 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"]) @items_api.route("/item/getTransactions", methods=["GET"])
@login_required
def getTransactions(): def getTransactions():
""" GET a subquery of transactions by passing a logistics_info_id, limit, and page """ 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."}) 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"]) @items_api.route("/item/getTransaction", methods=["GET"])
@login_required
def getTransaction(): def getTransaction():
""" GET a transaction from the system by passing an ID """ 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."}) return jsonify({"transaction": transaction, "error": True, "message": f"method {request.method} is not allowed."})
@items_api.route("/item/getItem", methods=["GET"]) @items_api.route("/item/getItem", methods=["GET"])
@login_required
def get_item(): def get_item():
""" GET item from system by passing its ID """ 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': False, 'message': ''})
return jsonify({'item': item, 'error': True, 'message': f'method {request.method} not allowed.'}) return jsonify({'item': item, 'error': True, 'message': f'method {request.method} not allowed.'})
@items_api.route("/item/getItemsWithQOH", methods=['GET']) @items_api.route("/item/getItemsWithQOH", methods=['GET'])
@login_required @login_required
def pagninate_items(): def pagninate_items():
pantry_inventory = [] """ GET items from the system by passing a page, limit, search_string, sort, and order
count = {'count': 0} ---
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": if request.method == "GET":
page = int(request.args.get('page', 1)) page = int(request.args.get('page', 1))
limit = int(request.args.get('limit', 10)) limit = int(request.args.get('limit', 10))
search_string = str(request.args.get('search_text', "")) search_string = str(request.args.get('search_text', ""))
sort = request.args.get('sort', "") sort = request.args.get('sort', "")
order = request.args.get('order', "") order = request.args.get('order', "")
view = request.args.get('view', "")
site_name = session['selected_site'] site_name = session['selected_site']
offset = (page - 1) * limit offset = (page - 1) * limit
if sort == 'total_qoh': if sort == 'total_qoh':
sort_order = f"{sort} {order}" sort_order = f"{sort} {order}"
else: else:
sort_order = f"{site_name}_items.{sort} {order}" sort_order = f"item.{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)
return jsonify({'items': pantry_inventory, "end": math.ceil(count['count']/limit), 'error':False, 'message': 'Items Loaded Successfully!'}) items, count = database_items.getItemsWithQOH(site_name, (search_string, limit, offset, sort_order))
return jsonify({'items': pantry_inventory, "end": math.ceil(count['count']/limit), 'error':True, 'message': 'There was a problem loading the items!'})
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"]) @items_api.route('/item/getModalItems', methods=["GET"])
@login_required @login_required

View File

@ -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;

View File

@ -1875,3 +1875,27 @@
2025-04-27 12:35:10.632770 --- ERROR --- DatabaseError(message=''int' object does not support indexing', 2025-04-27 12:35:10.632770 --- ERROR --- DatabaseError(message=''int' object does not support indexing',
payload=(1, 50, 0), payload=(1, 50, 0),
sql='SELECT * FROM main_transactions WHERE logistics_info_id=%s LIMIT %s OFFSET %s;') 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;')

View File

@ -203,7 +203,7 @@ async function updateTableElements(){
descriptionCell.setAttribute('class', 'uk-text-truncate uk-table-expand uk-visible@m') descriptionCell.setAttribute('class', 'uk-text-truncate uk-table-expand uk-visible@m')
let qtyUOMCell = document.createElement('td') 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') let opsCell = document.createElement('td')
opsCell.setAttribute('class', 'uk-width-1-4') opsCell.setAttribute('class', 'uk-width-1-4')
@ -255,7 +255,7 @@ async function updateListElements(){
header.classList.add('uk-card-header') header.classList.add('uk-card-header')
header.style = "border-radius: 0px, 10px, 0px, 10px;" header.style = "border-radius: 0px, 10px, 0px, 10px;"
header.innerHTML = `<h3>${items[i].item_name}</h3><div style="color: black;background-color: lightgrey; border-radius:10px;" class="uk-label uk-text-default">Quantity on Hand: ${parseFloat(items[i].total_qoh)} ${items[i].uom.fullname}</div>` header.innerHTML = `<h3>${items[i].item_name}</h3><div style="color: black;background-color: lightgrey; border-radius:10px;" class="uk-label uk-text-default">Quantity on Hand: ${parseFloat(items[i].total_qoh)} ${items[i].fullname}</div>`
let content = document.createElement('div') let content = document.createElement('div')
content.classList.add('uk-card-body') content.classList.add('uk-card-body')