From 642dbd9d2f1ba262ddf079adf6d4cabc90717ffd Mon Sep 17 00:00:00 2001 From: Jadowyne Ulve Date: Sat, 9 Aug 2025 08:18:28 -0500 Subject: [PATCH] Barcode Association added to items page you can now ADD, EDIT, DELETE barcodes from within the items edit page. --- .../database_payloads.cpython-313.pyc | Bin 27723 -> 27799 bytes .../administration/sql/CREATE/barcodes.sql | 3 +- .../administration/sql/CREATE/item.sql | 2 +- application/database_payloads.py | 10 +- .../database_items.cpython-313.pyc | Bin 56658 -> 60485 bytes .../__pycache__/items_API.cpython-313.pyc | Bin 30200 -> 33884 bytes application/items/database_items.py | 90 +++++++++ application/items/items_API.py | 65 ++++++- application/items/sql/getItemAllByID.sql | 13 +- application/items/static/itemEditHandler.js | 184 +++++++++++++++++- application/items/templates/item_new.html | 60 +++++- logs/database.log | 26 ++- logs/process.log | 130 +++++++++++++ 13 files changed, 571 insertions(+), 12 deletions(-) diff --git a/application/__pycache__/database_payloads.cpython-313.pyc b/application/__pycache__/database_payloads.cpython-313.pyc index 3ac6fb983307c6b421c1ec00401e6f93a5125b04..7c9c46e6727be9a9254181a060724bbf0cbad2c3 100644 GIT binary patch delta 7587 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 delta 7554 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 OWB#6&+e)~WoB9VTyWPwH delta 81 zcmcc9!Sv%bBj0CUUM>b8Q2o)L@!Dr1p9E6}=SGbVPL^~gP4CS!xLi`0G_5ypu3o@6 hIjL5X>k&{XBM=uGZ*HwMVB`MC!oe8BSQG>l0st(K7ia(g diff --git a/application/items/database_items.py b/application/items/database_items.py index cd8a710..c5c0bc6 100644 --- a/application/items/database_items.py +++ b/application/items/database_items.py @@ -630,6 +630,37 @@ def insertConversionTuple(site: str, payload: list, convert=True, conn=None): except Exception as error: raise postsqldb.DatabaseError(error, payload, sql) +def insertBarcodesTuple(site: str, payload: list, convert=True, conn=None): + """ payload (tuple): (barcode, item_uuid, in_exchange, out_exchange, descriptor) """ + record = () + self_conn = False + + sql = f"INSERT INTO {site}_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (%s, %s, %s, %s, %s) RETURNING *;" + + 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: + record = postsqldb.tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + record = rows + + if self_conn: + conn.commit() + conn.close() + + return record + + except Exception as error: + raise postsqldb.DatabaseError(error, payload, sql) + def postDeleteCostLayer(site_name, payload, convert=True, conn=None): """ payload (tuple): (table_to_delete_from, tuple_id) """ deleted = () @@ -749,6 +780,37 @@ def updateItemInfoTuple(site:str, payload: dict, convert=True, conn=None): except Exception as error: raise postsqldb.DatabaseError(error, payload, sql) +def updateBarcodesTuple(site:str, payload: dict, convert=True, conn=None): + """ payload (dict): {'barcode': row_id, 'update': {... column_to_update: value_to_update_to...}} """ + updated = () + self_conn = False + set_clause, values = postsqldb.updateStringFactory(payload['update']) + values.append(payload['barcode']) + sql = f"UPDATE {site}_barcodes SET {set_clause} WHERE barcode=%s RETURNING *;" + try: + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = False + self_conn = True + + with conn.cursor() as cur: + cur.execute(sql, values) + rows = cur.fetchone() + if rows and convert: + updated = postsqldb.tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + updated = rows + + if self_conn: + conn.commit() + conn.close() + + return updated + + except Exception as error: + raise postsqldb.DatabaseError(error, payload, sql) + def postUpdateItemLocation(site: str, payload: tuple, conn=None): item_location = () @@ -1041,3 +1103,31 @@ def postUpdateItemByID(site, payload, convert=True, conn=None): return updated, conn except Exception as error: raise postsqldb.DatabaseError(error, payload, sql) + + +def deleteBarcodesTuple(site, payload, convert=True, conn=None): + deleted = () + self_conn = False + sql = f"WITH deleted_rows AS (DELETE FROM {site}_Barcodes WHERE Barcode IN ({','.join(['%s'] * len(payload))}) RETURNING *) SELECT * FROM deleted_rows;" + 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.fetchall() + if rows and convert: + deleted = [postsqldb.tupleDictionaryFactory(cur.description, r) for r in rows] + elif rows and not convert: + deleted = rows + + if self_conn: + conn.commit() + conn.close() + + return deleted + except Exception as error: + raise 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 d5aa8f5..6ab288a 100644 --- a/application/items/items_API.py +++ b/application/items/items_API.py @@ -409,4 +409,67 @@ def post_transaction(): data=dict(request.json) ) return jsonify(result) - return jsonify({"error":True, "message":"There was an error with this POST statement"}) \ No newline at end of file + return jsonify({"error":True, "message":"There was an error with this POST statement"}) + + +@items_api.route('/api/addBarcode', methods=['POST']) +@access_api.login_required +def addBarcode(): + """API endpoint to add a barcode + + Returns: + Response: returns a status and status message to requestor + """ + if request.method == "POST": + site_name = session['selected_site'] + barcode_tuple = dbPayloads.BarcodesPayload( + barcode = request.get_json()['barcode'], + item_uuid= request.get_json()['item_uuid'], + in_exchange= request.get_json()['in_exchange'], + out_exchange= request.get_json()['out_exchange'], + descriptor= request.get_json()['descriptor'] + ) + try: + database_items.insertBarcodesTuple(site_name, barcode_tuple.payload()) + return jsonify(status=201, message=f"Barcode {request.get_json()['barcode']} was added successfully.") + except Exception as error: + return jsonify(status=400, message=str(error)) + + return jsonify(status=405, message=f"The request method: {request.method} is not allowed on this endpoint!") + +@items_api.route('/api/saveBarcode', methods=["POST"]) +@access_api.login_required +def saveBarcode(): + """API endpoint to update a barcode + + Returns: + Response: returns a status and status message to requestor + """ + 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) + return jsonify(status=201, message=f"{payload['barcode']} was updated successfully.") + except Exception as error: + return jsonify(status=400, message=str(error)) + return jsonify(status=405, message=f"The request method: {request.method} is not allowed on this endpoint!") + +@items_api.route('/api/deleteBarcode', methods=["POST"]) +@access_api.login_required +def deleteBarcode(): + """API endpoint to delete a barcode + + Returns: + Response: returns a status and status message to requestor + """ + if request.method == "POST": + barcode = request.get_json()['barcode'] + site_name = session['selected_site'] + try: + database_items.deleteBarcodesTuple(site_name, (barcode,)) + return jsonify(status=201, message=f"{barcode} was deleted successfully.") + except Exception as error: + return jsonify(status=400, message=str(error)) + return jsonify(status=405, message=f"The request method: {request.method} is not allowed on this endpoint!") \ No newline at end of file diff --git a/application/items/sql/getItemAllByID.sql b/application/items/sql/getItemAllByID.sql index 8b5ca81..709c3ce 100644 --- a/application/items/sql/getItemAllByID.sql +++ b/application/items/sql/getItemAllByID.sql @@ -61,6 +61,16 @@ WITH passed_id AS (SELECT %s AS passed_id), LEFT JOIN %%site_name%%_zones AS pz ON li.primary_zone = pz.id LEFT JOIN %%site_name%%_zones AS aiz ON li.auto_issue_zone = aiz.id WHERE li.id=(SELECT logistics_info_id FROM logistics_id) + ), + cte_barcodes AS ( + SELECT + barcode.barcode As barcode, + barcode.in_exchange AS in_exchange, + barcode.out_exchange AS out_exchange, + barcode.descriptor AS descriptor + FROM %%site_name%%_barcodes AS barcode + LEFT JOIN %%site_name%%_items AS item ON item.id = (SELECT passed_id FROM passed_id) + WHERE barcode.item_uuid = item.item_uuid ) SELECT @@ -73,7 +83,8 @@ SELECT (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_groups g) AS item_groups, (SELECT COALESCE(array_agg(row_to_json(sl)), '{}') FROM cte_shopping_lists sl) AS item_shopping_lists, (SELECT COALESCE(array_agg(row_to_json(il)), '{}') FROM cte_itemlinks il) AS linked_items, - (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations + (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations, + (SELECT COALESCE(array_agg(row_to_json(bar)), '{}') FROM cte_barcodes bar) AS item_barcodes FROM %%site_name%%_items LEFT JOIN %%site_name%%_item_info ON %%site_name%%_items.item_info_id = %%site_name%%_item_info.id LEFT JOIN %%site_name%%_food_info ON %%site_name%%_items.food_info_id = %%site_name%%_food_info.id diff --git a/application/items/static/itemEditHandler.js b/application/items/static/itemEditHandler.js index 88edcfc..bd21e67 100644 --- a/application/items/static/itemEditHandler.js +++ b/application/items/static/itemEditHandler.js @@ -59,8 +59,12 @@ var item_subtypes = [['Food', 'FOOD'], ['Food PLU', 'FOOD_PLU'], ['Other', 'OTHE document.addEventListener('DOMContentLoaded', async function() { await setupFormDefaults() + await refreshForm() +}) + + +async function refreshForm(){ await fetchItem() - console.log(item) document.getElementById('title').innerHTML = item.item_name; await setBasicInfo() await updateWebLinksTable() @@ -70,7 +74,8 @@ document.addEventListener('DOMContentLoaded', async function() { await updateConversionsTableBody() await updatePrefixTableBody() await updateTags() -}) + await updateBarcodes() +} async function setupFormDefaults() { let itemTypeSelect = document.getElementById('itemTypeSelect') @@ -90,6 +95,179 @@ async function setupFormDefaults() { } } +async function updateBarcodes(){ + let barcodes = item.item_barcodes + let barcodesTableBody = document.getElementById('barcodesTableBody'); + barcodesTableBody.innerHTML = ""; + + for (let i = 0; i < barcodes.length; i++){ + let tableRow = document.createElement('tr') + + let barcodeCell = document.createElement('td') + barcodeCell.innerHTML = barcodes[i].barcode + + let inexchangeCell = document.createElement('td') + inexchangeCell.innerHTML = barcodes[i].in_exchange + + let outexchangeCell = document.createElement('td') + outexchangeCell.innerHTML = barcodes[i].out_exchange + + let descriptorCell = document.createElement('td') + descriptorCell.innerHTML = barcodes[i].descriptor + + let operationsCell = document.createElement('td') + + let editButton = document.createElement('button') + editButton.innerHTML = "Edit" + editButton.setAttribute('class', 'uk-button uk-button-default uk-button-small') + editButton.onclick = async function(){await openEditBarcodeModal(barcodes[i])} + + let deleteButton = document.createElement('button') + deleteButton.innerHTML = "Delete" + deleteButton.setAttribute('class', 'uk-button uk-button-danger uk-button-small') + deleteButton.onclick = async function(){await deleteBarcodeToItem(barcodes[i].barcode)} + + + operationsCell.append(editButton, deleteButton) + + tableRow.append(barcodeCell, inexchangeCell, outexchangeCell, descriptorCell, operationsCell) + + barcodesTableBody.append(tableRow) + } + +} + +async function openAddBarcodeModal() { + document.getElementById('barcodeModalTitle').innerHTML = "Add Barcode" + document.getElementById('barcodeModalButton').innerHTML = "Add Barcode" + document.getElementById('barcodeNumber').value = "" + document.getElementById('barcodeNumber').classList.remove('uk-disabled') + document.getElementById('inExchangeNumber').value = "" + document.getElementById('outExchangeNumber').value = "" + document.getElementById('barcodeDescriptor').value = "" + document.getElementById('barcodeModalButton').onclick = async function () { await addBarcodeToItem()} + UIkit.modal(document.getElementById('barcodeModal')).show() +} + +async function openEditBarcodeModal(barcode) { + document.getElementById('barcodeModalTitle').innerHTML = "Edit Barcode" + document.getElementById('barcodeModalButton').innerHTML = "Save Barcode" + document.getElementById('barcodeNumber').value = barcode.barcode + document.getElementById('barcodeNumber').classList.add('uk-disabled') + document.getElementById('inExchangeNumber').value = barcode.in_exchange + document.getElementById('outExchangeNumber').value = barcode.out_exchange + document.getElementById('barcodeDescriptor').value = barcode.descriptor + document.getElementById('barcodeModalButton').onclick = async function () { await saveBarcodeToItem(barcode)} + + UIkit.modal(document.getElementById('barcodeModal')).show() +} + +async function addBarcodeToItem() { + let barcode = document.getElementById('barcodeNumber').value + let in_exchange = document.getElementById('inExchangeNumber').value + let out_exchange = document.getElementById('outExchangeNumber').value + let descriptor = document.getElementById('barcodeDescriptor').value + + UIkit.modal(document.getElementById('barcodeModal')).hide() + + const response = await fetch('/items/api/addBarcode', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + barcode: barcode, + item_uuid: item.item_uuid, + in_exchange: in_exchange, + out_exchange: out_exchange, + descriptor: descriptor + }) + }); + + data = await response.json(); + response_status = 'primary' + if (data.status === 404){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await refreshForm() + +} + +async function saveBarcodeToItem(barcode) { + let in_exchange = document.getElementById('inExchangeNumber').value + let out_exchange = document.getElementById('outExchangeNumber').value + let descriptor = document.getElementById('barcodeDescriptor').value + + UIkit.modal(document.getElementById('barcodeModal')).hide() + + const response = await fetch('/items/api/saveBarcode', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + barcode: barcode.barcode, + update: { + in_exchange: in_exchange, + out_exchange: out_exchange, + descriptor: descriptor + } + }) + }); + + data = await response.json(); + response_status = 'primary' + if (!data.status === 201){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await refreshForm() + +} + +async function deleteBarcodeToItem(barcode) { + const response = await fetch('/items/api/deleteBarcode', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + barcode: barcode, + }) + }); + + data = await response.json(); + response_status = 'primary' + if (!data.status === 201){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await refreshForm() + +} + async function updateConversionsTableBody(){ let conversionsTableBody = document.getElementById('conversionsTableBody') conversionsTableBody.innerHTML = ""; @@ -753,7 +931,6 @@ async function openEditConversionsModal(conversion) { UIkit.modal(conversionsModal).show() } - async function postConversion() { const response = await fetch(`/items/addConversion`, { method: 'POST', @@ -999,6 +1176,7 @@ async function fetchItem() { locations = item.item_locations brand = item.brand.name + return item; }; async function searchTable(event, logis, elementID) { diff --git a/application/items/templates/item_new.html b/application/items/templates/item_new.html index 84a099d..97d99b1 100644 --- a/application/items/templates/item_new.html +++ b/application/items/templates/item_new.html @@ -202,6 +202,7 @@
  • Food Info
  • Logistics Info
  • +
  • Associated Barcodes
  • Search String
  • @@ -433,6 +434,26 @@ + +
    +
    + +
    +
    + + + + + + + + + + + +
    BarcodeIn ExchangeOut ExchangedescriptorOperations
    +
    +
    @@ -450,7 +471,7 @@
    - +

    Select Zone

    @@ -553,6 +574,43 @@
    + +
    +
    +

    Add Barcode

    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    diff --git a/logs/database.log b/logs/database.log index a9f57ba..80371c3 100644 --- a/logs/database.log +++ b/logs/database.log @@ -19,4 +19,28 @@ sql='WITH passed_id AS (SELECT test_items.id AS passed_id FROM test_barcodes LEFT JOIN test_items ON test_items.item_uuid = test_barcodes.item_uuid WHERE barcode=%s), logistics_id AS (SELECT logistics_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), info_id AS (SELECT item_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), cte_item_info AS ( SELECT test_item_info.*, row_to_json(units.*) as uom FROM test_item_info LEFT JOIN units ON test_item_info.uom = units.id WHERE test_item_info.id = (SELECT item_info_id FROM info_id) ), cte_groups AS ( SELECT test_groups.*, test_group_items.uuid, test_group_items.item_type, test_group_items.qty FROM test_groups JOIN test_group_items ON test_groups.id = test_group_items.gr_id WHERE test_group_items.item_id = (SELECT passed_id FROM passed_id) ), cte_shopping_lists AS ( SELECT test_shopping_lists.*, test_shopping_list_items.uuid, test_shopping_list_items.item_type, test_shopping_list_items.qty FROM test_shopping_lists JOIN test_shopping_list_items ON test_shopping_lists.id = test_shopping_list_items.sl_id WHERE test_shopping_list_items.item_id = (SELECT passed_id FROM passed_id) ), cte_itemlinks AS ( SELECT * FROM test_itemlinks WHERE link=(SELECT passed_id FROM passed_id) ), cte_item_locations AS ( SELECT * FROM test_item_locations LEFT JOIN test_locations ON test_locations.id = test_item_locations.location_id WHERE part_id = (SELECT passed_id FROM passed_id) ), cte_logistics_info AS ( SELECT li.*, row_to_json(pl) AS primary_location, row_to_json(ail) AS auto_issue_location, row_to_json(pz) AS primary_zone, row_to_json(aiz) AS auto_issue_zone FROM test_logistics_info AS li LEFT JOIN test_locations AS pl ON li.primary_location = pl.id LEFT JOIN test_locations AS ail ON li.auto_issue_location = ail.id LEFT JOIN test_zones AS pz ON li.primary_zone = pz.id LEFT JOIN test_zones AS aiz ON li.auto_issue_zone = aiz.id WHERE li.id=(SELECT logistics_info_id FROM logistics_id) )SELECT (SELECT passed_id FROM passed_id) AS passed_id, test_items.*, (SELECT COALESCE(row_to_json(logis), '{}') FROM cte_logistics_info logis) AS logistics_info, row_to_json(test_food_info.*) as food_info, row_to_json(test_brands.*) as brand, (SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_groups g) AS item_groups, (SELECT COALESCE(array_agg(row_to_json(sl)), '{}') FROM cte_shopping_lists sl) AS item_shopping_lists, (SELECT COALESCE(array_agg(row_to_json(il)), '{}') FROM cte_itemlinks il) AS linked_items, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locationsFROM test_items LEFT JOIN test_item_info ON test_items.item_info_id = test_item_info.id LEFT JOIN test_food_info ON test_items.food_info_id = test_food_info.id LEFT JOIN test_brands ON test_items.brand = test_brands.id LEFT JOIN units ON test_item_info.uom = units.id LEFT JOIN cte_groups ON test_items.id = cte_groups.id LEFT JOIN cte_shopping_lists ON test_items.id = cte_shopping_lists.idWHERE test_items.id=(SELECT passed_id FROM passed_id)GROUP BY test_items.id, test_item_info.id, test_food_info.id, test_brands.id;') 2025-08-05 15:25:24.830194 --- ERROR --- DatabaseError(message='invalid reference to FROM-clause entry for table "test_items"LINE 1: WITH passed_id AS (SELECT test_items.id AS passed_id FROM te... ^HINT: Perhaps you meant to reference the table alias "items".', payload=('%041789001314%',), - sql='WITH passed_id AS (SELECT test_items.id AS passed_id FROM test_barcodes barcodes LEFT JOIN test_items items ON items.item_uuid = barcodes.item_uuid WHERE barcodes.barcode=%s), logistics_id AS (SELECT logistics_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), info_id AS (SELECT item_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), cte_item_info AS ( SELECT test_item_info.*, row_to_json(units.*) as uom FROM test_item_info LEFT JOIN units ON test_item_info.uom = units.id WHERE test_item_info.id = (SELECT item_info_id FROM info_id) ), cte_groups AS ( SELECT test_groups.*, test_group_items.uuid, test_group_items.item_type, test_group_items.qty FROM test_groups JOIN test_group_items ON test_groups.id = test_group_items.gr_id WHERE test_group_items.item_id = (SELECT passed_id FROM passed_id) ), cte_shopping_lists AS ( SELECT test_shopping_lists.*, test_shopping_list_items.uuid, test_shopping_list_items.item_type, test_shopping_list_items.qty FROM test_shopping_lists JOIN test_shopping_list_items ON test_shopping_lists.id = test_shopping_list_items.sl_id WHERE test_shopping_list_items.item_id = (SELECT passed_id FROM passed_id) ), cte_itemlinks AS ( SELECT * FROM test_itemlinks WHERE link=(SELECT passed_id FROM passed_id) ), cte_item_locations AS ( SELECT * FROM test_item_locations LEFT JOIN test_locations ON test_locations.id = test_item_locations.location_id WHERE part_id = (SELECT passed_id FROM passed_id) ), cte_logistics_info AS ( SELECT li.*, row_to_json(pl) AS primary_location, row_to_json(ail) AS auto_issue_location, row_to_json(pz) AS primary_zone, row_to_json(aiz) AS auto_issue_zone FROM test_logistics_info AS li LEFT JOIN test_locations AS pl ON li.primary_location = pl.id LEFT JOIN test_locations AS ail ON li.auto_issue_location = ail.id LEFT JOIN test_zones AS pz ON li.primary_zone = pz.id LEFT JOIN test_zones AS aiz ON li.auto_issue_zone = aiz.id WHERE li.id=(SELECT logistics_info_id FROM logistics_id) )SELECT (SELECT passed_id FROM passed_id) AS passed_id, test_items.*, (SELECT COALESCE(row_to_json(logis), '{}') FROM cte_logistics_info logis) AS logistics_info, row_to_json(test_food_info.*) as food_info, row_to_json(test_brands.*) as brand, (SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_groups g) AS item_groups, (SELECT COALESCE(array_agg(row_to_json(sl)), '{}') FROM cte_shopping_lists sl) AS item_shopping_lists, (SELECT COALESCE(array_agg(row_to_json(il)), '{}') FROM cte_itemlinks il) AS linked_items, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locationsFROM test_items LEFT JOIN test_item_info ON test_items.item_info_id = test_item_info.id LEFT JOIN test_food_info ON test_items.food_info_id = test_food_info.id LEFT JOIN test_brands ON test_items.brand = test_brands.id LEFT JOIN units ON test_item_info.uom = units.id LEFT JOIN cte_groups ON test_items.id = cte_groups.id LEFT JOIN cte_shopping_lists ON test_items.id = cte_shopping_lists.idWHERE test_items.id=(SELECT passed_id FROM passed_id)GROUP BY test_items.id, test_item_info.id, test_food_info.id, test_brands.id;') \ No newline at end of file + sql='WITH passed_id AS (SELECT test_items.id AS passed_id FROM test_barcodes barcodes LEFT JOIN test_items items ON items.item_uuid = barcodes.item_uuid WHERE barcodes.barcode=%s), logistics_id AS (SELECT logistics_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), info_id AS (SELECT item_info_id FROM test_items WHERE id=(SELECT passed_id FROM passed_id)), cte_item_info AS ( SELECT test_item_info.*, row_to_json(units.*) as uom FROM test_item_info LEFT JOIN units ON test_item_info.uom = units.id WHERE test_item_info.id = (SELECT item_info_id FROM info_id) ), cte_groups AS ( SELECT test_groups.*, test_group_items.uuid, test_group_items.item_type, test_group_items.qty FROM test_groups JOIN test_group_items ON test_groups.id = test_group_items.gr_id WHERE test_group_items.item_id = (SELECT passed_id FROM passed_id) ), cte_shopping_lists AS ( SELECT test_shopping_lists.*, test_shopping_list_items.uuid, test_shopping_list_items.item_type, test_shopping_list_items.qty FROM test_shopping_lists JOIN test_shopping_list_items ON test_shopping_lists.id = test_shopping_list_items.sl_id WHERE test_shopping_list_items.item_id = (SELECT passed_id FROM passed_id) ), cte_itemlinks AS ( SELECT * FROM test_itemlinks WHERE link=(SELECT passed_id FROM passed_id) ), cte_item_locations AS ( SELECT * FROM test_item_locations LEFT JOIN test_locations ON test_locations.id = test_item_locations.location_id WHERE part_id = (SELECT passed_id FROM passed_id) ), cte_logistics_info AS ( SELECT li.*, row_to_json(pl) AS primary_location, row_to_json(ail) AS auto_issue_location, row_to_json(pz) AS primary_zone, row_to_json(aiz) AS auto_issue_zone FROM test_logistics_info AS li LEFT JOIN test_locations AS pl ON li.primary_location = pl.id LEFT JOIN test_locations AS ail ON li.auto_issue_location = ail.id LEFT JOIN test_zones AS pz ON li.primary_zone = pz.id LEFT JOIN test_zones AS aiz ON li.auto_issue_zone = aiz.id WHERE li.id=(SELECT logistics_info_id FROM logistics_id) )SELECT (SELECT passed_id FROM passed_id) AS passed_id, test_items.*, (SELECT COALESCE(row_to_json(logis), '{}') FROM cte_logistics_info logis) AS logistics_info, row_to_json(test_food_info.*) as food_info, row_to_json(test_brands.*) as brand, (SELECT COALESCE(row_to_json(ii), '{}') FROM cte_item_info ii) AS item_info, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_groups g) AS item_groups, (SELECT COALESCE(array_agg(row_to_json(sl)), '{}') FROM cte_shopping_lists sl) AS item_shopping_lists, (SELECT COALESCE(array_agg(row_to_json(il)), '{}') FROM cte_itemlinks il) AS linked_items, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locationsFROM test_items LEFT JOIN test_item_info ON test_items.item_info_id = test_item_info.id LEFT JOIN test_food_info ON test_items.food_info_id = test_food_info.id LEFT JOIN test_brands ON test_items.brand = test_brands.id LEFT JOIN units ON test_item_info.uom = units.id LEFT JOIN cte_groups ON test_items.id = cte_groups.id LEFT JOIN cte_shopping_lists ON test_items.id = cte_shopping_lists.idWHERE test_items.id=(SELECT passed_id FROM passed_id)GROUP BY test_items.id, test_item_info.id, test_food_info.id, test_brands.id;') +2025-08-08 18:22:06.689520 --- ERROR --- DatabaseError(message='syntax error at or near ","LINE 1: ..., in_exchange, out_exchange, descriptor) VALUES (?, ?, ?, ?,... ^', + payload=('%test%', '44c41878-e645-4e16-a402-e480936ac4aa', 1, 1, 'normal test'), + sql='INSERT INTO test_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (?, ?, ?, ?, ?);') +2025-08-08 18:23:47.408991 --- ERROR --- DatabaseError(message='syntax error at or near ","LINE 1: ..., in_exchange, out_exchange, descriptor) VALUES (?, ?, ?, ?,... ^', + payload=('%test%', '44c41878-e645-4e16-a402-e480936ac4aa', 1, 1, 'normal test'), + sql='INSERT INTO test_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (?, ?, ?, ?, ?) RETURNING *;') +2025-08-08 18:25:41.824363 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "test_barcodes_pkey"DETAIL: Key (barcode)=(%test%) already exists.', + payload=('%test%', '44c41878-e645-4e16-a402-e480936ac4aa', 1, 1, 'normal test'), + sql='INSERT INTO test_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 07:32:58.410729 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "test_barcodes_pkey"DETAIL: Key (barcode)=(tsath) already exists.', + payload=('tsath', '44c41878-e645-4e16-a402-e480936ac4aa', '2', '2', 'test2'), + sql='INSERT INTO test_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 07:34:13.926705 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "test_barcodes_pkey"DETAIL: Key (barcode)=(tsath) already exists.', + payload=('tsath', '44c41878-e645-4e16-a402-e480936ac4aa', '1', '1', 'test'), + sql='INSERT INTO test_barcodes (barcode, item_uuid, in_exchange, out_exchange, descriptor) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-09 08:07:31.538747 --- ERROR --- DatabaseError(message='can't adapt type 'dict'', + payload={'barcode': {'barcode': 'tsath', 'descriptor': 'test', 'in_exchange': 1, 'out_exchange': 1}, 'update': {'in_exchange': '1', 'out_exchange': '1', 'descriptor': 'test changed'}}, + sql='UPDATE test_barcodes SET in_exchange = %s, out_exchange = %s, descriptor = %s WHERE barcode=%s RETURNING *;') +2025-08-09 08:08:14.996560 --- ERROR --- DatabaseError(message='can't adapt type 'dict'', + payload={'barcode': {'barcode': 'tsath', 'descriptor': 'test', 'in_exchange': 1, 'out_exchange': 1}, 'update': {'in_exchange': '1', 'out_exchange': '1', 'descriptor': 'test c'}}, + sql='UPDATE test_barcodes SET in_exchange = %s, out_exchange = %s, descriptor = %s WHERE barcode=%s RETURNING *;') +2025-08-09 08:08:51.302903 --- ERROR --- DatabaseError(message='can't adapt type 'dict'', + payload={'barcode': {'barcode': 'tsath', 'descriptor': 'test', 'in_exchange': 1, 'out_exchange': 1}, 'update': {'in_exchange': '1', 'out_exchange': '1', 'descriptor': 'test ggh'}}, + sql='UPDATE test_barcodes SET in_exchange = %s, out_exchange = %s, descriptor = %s WHERE barcode=%s RETURNING *;') \ No newline at end of file diff --git a/logs/process.log b/logs/process.log index 9db2238..6d3202d 100644 --- a/logs/process.log +++ b/logs/process.log @@ -371,3 +371,133 @@ 2025-08-02 18:29:58.939191 --- INFO --- item_locations DROPPED! 2025-08-02 18:29:58.943407 --- INFO --- conversions DROPPED! 2025-08-02 18:29:58.947995 --- INFO --- sku_prefix DROPPED! +2025-08-06 15:26:50.996830 --- INFO --- logins Created! +2025-08-06 15:26:51.004741 --- INFO --- sites Created! +2025-08-06 15:26:51.012565 --- INFO --- roles Created! +2025-08-06 15:26:51.019685 --- INFO --- units Created! +2025-08-06 15:26:51.029864 --- INFO --- cost_layers Created! +2025-08-06 15:26:51.040399 --- INFO --- linked_items Created! +2025-08-06 15:26:51.048281 --- INFO --- brands Created! +2025-08-06 15:26:51.057531 --- INFO --- food_info Created! +2025-08-06 15:26:51.067986 --- INFO --- item_info Created! +2025-08-06 15:26:51.079043 --- INFO --- zones Created! +2025-08-06 15:26:51.088589 --- INFO --- locations Created! +2025-08-06 15:26:51.099331 --- INFO --- logistics_info Created! +2025-08-06 15:26:51.109340 --- INFO --- transactions Created! +2025-08-06 15:26:51.118603 --- INFO --- item Created! +2025-08-06 15:26:51.127832 --- INFO --- vendors Created! +2025-08-06 15:26:51.138219 --- INFO --- groups Created! +2025-08-06 15:26:51.148890 --- INFO --- group_items Created! +2025-08-06 15:26:51.159250 --- INFO --- receipts Created! +2025-08-06 15:26:51.169940 --- INFO --- receipt_items Created! +2025-08-06 15:26:51.179778 --- INFO --- recipes Created! +2025-08-06 15:26:51.190695 --- INFO --- recipe_items Created! +2025-08-06 15:26:51.200941 --- INFO --- shopping_lists Created! +2025-08-06 15:26:51.212987 --- INFO --- shopping_list_items Created! +2025-08-06 15:26:51.223729 --- INFO --- item_locations Created! +2025-08-06 15:26:51.233171 --- INFO --- conversions Created! +2025-08-06 15:26:51.243293 --- INFO --- sku_prefix Created! +2025-08-06 15:26:51.250811 --- INFO --- barcodes Created! +2025-08-06 15:26:51.255426 --- INFO --- Admin User Created! +2025-08-06 15:27:21.859234 --- INFO --- item_info DROPPED! +2025-08-06 15:27:21.867323 --- INFO --- items DROPPED! +2025-08-06 15:27:21.873916 --- INFO --- cost_layers DROPPED! +2025-08-06 15:27:21.880427 --- INFO --- linked_items DROPPED! +2025-08-06 15:27:21.886946 --- INFO --- transactions DROPPED! +2025-08-06 15:27:21.893522 --- INFO --- brands DROPPED! +2025-08-06 15:27:21.901142 --- INFO --- food_info DROPPED! +2025-08-06 15:27:21.908294 --- INFO --- logistics_info DROPPED! +2025-08-06 15:27:21.915098 --- INFO --- zones DROPPED! +2025-08-06 15:27:21.921773 --- INFO --- locations DROPPED! +2025-08-06 15:27:21.928619 --- INFO --- vendors DROPPED! +2025-08-06 15:27:21.935711 --- INFO --- group_items DROPPED! +2025-08-06 15:27:21.942315 --- INFO --- groups DROPPED! +2025-08-06 15:27:21.949753 --- INFO --- receipt_items DROPPED! +2025-08-06 15:27:21.956366 --- INFO --- receipts DROPPED! +2025-08-06 15:27:21.963181 --- INFO --- recipe_items DROPPED! +2025-08-06 15:27:21.969612 --- INFO --- recipes DROPPED! +2025-08-06 15:27:21.976482 --- INFO --- shopping_list_items DROPPED! +2025-08-06 15:27:21.983015 --- INFO --- shopping_lists DROPPED! +2025-08-06 15:27:21.989605 --- INFO --- item_locations DROPPED! +2025-08-06 15:27:21.996485 --- INFO --- conversions DROPPED! +2025-08-06 15:27:22.003412 --- INFO --- sku_prefix DROPPED! +2025-08-06 15:27:22.007038 --- INFO --- barcodes DROPPED! +2025-08-06 15:27:46.246440 --- INFO --- logins Created! +2025-08-06 15:27:46.251081 --- INFO --- sites Created! +2025-08-06 15:27:46.255711 --- INFO --- roles Created! +2025-08-06 15:27:46.260244 --- INFO --- units Created! +2025-08-06 15:27:46.267095 --- INFO --- cost_layers Created! +2025-08-06 15:27:46.273727 --- INFO --- linked_items Created! +2025-08-06 15:27:46.279822 --- INFO --- brands Created! +2025-08-06 15:27:46.285656 --- INFO --- food_info Created! +2025-08-06 15:27:46.292120 --- INFO --- item_info Created! +2025-08-06 15:27:46.298632 --- INFO --- zones Created! +2025-08-06 15:27:46.304633 --- INFO --- locations Created! +2025-08-06 15:27:46.311199 --- INFO --- logistics_info Created! +2025-08-06 15:27:46.317532 --- INFO --- transactions Created! +2025-08-06 15:27:46.325242 --- INFO --- item Created! +2025-08-06 15:27:46.331866 --- INFO --- vendors Created! +2025-08-06 15:27:46.338359 --- INFO --- groups Created! +2025-08-06 15:27:46.345345 --- INFO --- group_items Created! +2025-08-06 15:27:46.352180 --- INFO --- receipts Created! +2025-08-06 15:27:46.358114 --- INFO --- receipt_items Created! +2025-08-06 15:27:46.364046 --- INFO --- recipes Created! +2025-08-06 15:27:46.370972 --- INFO --- recipe_items Created! +2025-08-06 15:27:46.377996 --- INFO --- shopping_lists Created! +2025-08-06 15:27:46.385875 --- INFO --- shopping_list_items Created! +2025-08-06 15:27:46.393272 --- INFO --- item_locations Created! +2025-08-06 15:27:46.399040 --- INFO --- conversions Created! +2025-08-06 15:27:46.405959 --- INFO --- sku_prefix Created! +2025-08-06 15:27:46.410637 --- INFO --- barcodes Created! +2025-08-06 15:27:46.414482 --- INFO --- Admin User Created! +2025-08-06 15:29:59.500393 --- INFO --- item_info DROPPED! +2025-08-06 15:29:59.506101 --- INFO --- items DROPPED! +2025-08-06 15:29:59.510377 --- INFO --- cost_layers DROPPED! +2025-08-06 15:29:59.514568 --- INFO --- linked_items DROPPED! +2025-08-06 15:29:59.518595 --- INFO --- transactions DROPPED! +2025-08-06 15:29:59.522422 --- INFO --- brands DROPPED! +2025-08-06 15:29:59.526227 --- INFO --- food_info DROPPED! +2025-08-06 15:29:59.530681 --- INFO --- logistics_info DROPPED! +2025-08-06 15:29:59.534747 --- INFO --- zones DROPPED! +2025-08-06 15:29:59.538678 --- INFO --- locations DROPPED! +2025-08-06 15:29:59.542693 --- INFO --- vendors DROPPED! +2025-08-06 15:29:59.546730 --- INFO --- group_items DROPPED! +2025-08-06 15:29:59.550606 --- INFO --- groups DROPPED! +2025-08-06 15:29:59.554496 --- INFO --- receipt_items DROPPED! +2025-08-06 15:29:59.558462 --- INFO --- receipts DROPPED! +2025-08-06 15:29:59.562550 --- INFO --- recipe_items DROPPED! +2025-08-06 15:29:59.566293 --- INFO --- recipes DROPPED! +2025-08-06 15:29:59.570395 --- INFO --- shopping_list_items DROPPED! +2025-08-06 15:29:59.574440 --- INFO --- shopping_lists DROPPED! +2025-08-06 15:29:59.578461 --- INFO --- item_locations DROPPED! +2025-08-06 15:29:59.582328 --- INFO --- conversions DROPPED! +2025-08-06 15:29:59.586310 --- INFO --- sku_prefix DROPPED! +2025-08-06 15:29:59.590039 --- INFO --- barcodes DROPPED! +2025-08-06 15:30:30.212846 --- INFO --- logins Created! +2025-08-06 15:30:30.217600 --- INFO --- sites Created! +2025-08-06 15:30:30.221630 --- INFO --- roles Created! +2025-08-06 15:30:30.225442 --- INFO --- units Created! +2025-08-06 15:30:30.232110 --- INFO --- cost_layers Created! +2025-08-06 15:30:30.238786 --- INFO --- linked_items Created! +2025-08-06 15:30:30.243490 --- INFO --- brands Created! +2025-08-06 15:30:30.248847 --- INFO --- food_info Created! +2025-08-06 15:30:30.254853 --- INFO --- item_info Created! +2025-08-06 15:30:30.261052 --- INFO --- zones Created! +2025-08-06 15:30:30.267069 --- INFO --- locations Created! +2025-08-06 15:30:30.273126 --- INFO --- logistics_info Created! +2025-08-06 15:30:30.279108 --- INFO --- transactions Created! +2025-08-06 15:30:30.290397 --- INFO --- item Created! +2025-08-06 15:30:30.296232 --- INFO --- vendors Created! +2025-08-06 15:30:30.302301 --- INFO --- groups Created! +2025-08-06 15:30:30.308844 --- INFO --- group_items Created! +2025-08-06 15:30:30.315229 --- INFO --- receipts Created! +2025-08-06 15:30:30.321004 --- INFO --- receipt_items Created! +2025-08-06 15:30:30.326751 --- INFO --- recipes Created! +2025-08-06 15:30:30.333407 --- INFO --- recipe_items Created! +2025-08-06 15:30:30.339686 --- INFO --- shopping_lists Created! +2025-08-06 15:30:30.346505 --- INFO --- shopping_list_items Created! +2025-08-06 15:30:30.353436 --- INFO --- item_locations Created! +2025-08-06 15:30:30.359018 --- INFO --- conversions Created! +2025-08-06 15:30:30.365281 --- INFO --- sku_prefix Created! +2025-08-06 15:30:30.369764 --- INFO --- barcodes Created! +2025-08-06 15:30:30.373731 --- INFO --- Admin User Created!