diff --git a/application/__pycache__/database_payloads.cpython-313.pyc b/application/__pycache__/database_payloads.cpython-313.pyc index 3ac6fb9..7c9c46e 100644 Binary files a/application/__pycache__/database_payloads.cpython-313.pyc and b/application/__pycache__/database_payloads.cpython-313.pyc differ diff --git a/application/administration/sql/CREATE/barcodes.sql b/application/administration/sql/CREATE/barcodes.sql index 1403f8c..97ace78 100644 --- a/application/administration/sql/CREATE/barcodes.sql +++ b/application/administration/sql/CREATE/barcodes.sql @@ -2,5 +2,6 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_barcodes ( barcode VARCHAR(32) PRIMARY KEY, item_uuid UUID, in_exchange FLOAT, - out_exchange FLOAT + out_exchange FLOAT, + descriptor VARCHAR(255) ); \ No newline at end of file diff --git a/application/administration/sql/CREATE/item.sql b/application/administration/sql/CREATE/item.sql index b83b617..5824864 100644 --- a/application/administration/sql/CREATE/item.sql +++ b/application/administration/sql/CREATE/item.sql @@ -1,6 +1,6 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_items( id SERIAL PRIMARY KEY, - item_uuid UUID, + item_uuid UUID DEFAULT gen_random_uuid(), barcode VARCHAR(255) NOT NULL, item_name VARCHAR(255) NOT NULL, brand INTEGER, diff --git a/application/database_payloads.py b/application/database_payloads.py index f6a3e76..0f692d0 100644 --- a/application/database_payloads.py +++ b/application/database_payloads.py @@ -8,13 +8,15 @@ class BarcodesPayload: item_uuid: str in_exchange: float out_exchange: float + descriptor: str def payload(self): return ( self.barcode, self.item_uuid, self.in_exchange, - self.out_exchange + self.out_exchange, + self.descriptor ) @dataclass @@ -597,7 +599,8 @@ class SiteManager: "shopping_list_items", "item_locations", "conversions", - "sku_prefix" + "sku_prefix", + "barcodes" ] self.drop_order = [ "item_info", @@ -621,5 +624,6 @@ class SiteManager: "shopping_lists", "item_locations", "conversions", - "sku_prefix" + "sku_prefix", + "barcodes" ] \ No newline at end of file diff --git a/application/items/__pycache__/database_items.cpython-313.pyc b/application/items/__pycache__/database_items.cpython-313.pyc index 87b55f2..15865c0 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 438e57c..288fd8f 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/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!