diff --git a/application/items/templates/transaction.html b/application/items/templates/transaction.html index 7149f2c..184e898 100644 --- a/application/items/templates/transaction.html +++ b/application/items/templates/transaction.html @@ -254,56 +254,6 @@ - -
-
-

Edit Line...

-

Edit any fields here for the selected Line and then save them.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QTY
QTY
UOM - -
COST
EXPIRES
-

- - -

-
-
- - - {% assets "js_all" %} {% endassets %} diff --git a/application/poe/__init__.py b/application/poe/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/application/poe/poe_api.py b/application/poe/poe_api.py index 3cdfc8d..c1a49f2 100644 --- a/application/poe/poe_api.py +++ b/application/poe/poe_api.py @@ -8,6 +8,7 @@ import time, process from user_api import login_required import webpush from application.poe import poe_processes +from application import postsqldb point_of_ease = Blueprint('poe', __name__, template_folder="templates", static_folder="static") @@ -21,9 +22,14 @@ def scannerEndpoint(): @point_of_ease.route('/receipts', methods=["GET"]) def receiptsEndpoint(): sites = [site[1] for site in main.get_sites(session['user']['sites'])] + database_config = config() + with psycopg2.connect(**database_config) as conn: + units = postsqldb.UnitsTable.getAll(conn) + #units = db.UnitsTable.getAll(conn) return render_template('receipts.html', current_site=session['selected_site'], - sites=sites) + sites=sites, units=units) +# DONT NEED @point_of_ease.route('/getItemLocations', methods=["GET"]) def getItemLocations(): recordset = [] @@ -41,7 +47,7 @@ def getItemLocations(): return jsonify({"locations":recordset, "end": math.ceil(count/limit), "error":True, "message":"There was an error with this GET statement"}) -# in item api +# in item api, DONT NEED @point_of_ease.route('/getItem', methods=["GET"]) def getItem(): record = {} @@ -69,7 +75,7 @@ def getItemBarcode(): return jsonify({"item":record, "error":False, "message":"item fetched succesfully!"}) return jsonify({"item":record, "error":True, "message":"There was an error with this GET statement"}) -# in items api +# in items api DONT NEED @point_of_ease.route('/getModalItems', methods=["GET"]) @login_required def getModalItems(): @@ -97,12 +103,6 @@ def post_transaction(): user_id=session['user_id'], data=dict(request.json) ) - #result = process.postTransaction( - # conn=conn, - # site_name=session['selected_site'], - # user_id=session['user_id'], - # data=dict(request.json) - #) return jsonify(result) return jsonify({"error":True, "message":"There was an error with this POST statement"}) @@ -112,30 +112,7 @@ def post_receipt(): if request.method == "POST": site_name = session['selected_site'] user_id = session['user_id'] - database_config = config() - with psycopg2.connect(**database_config) as conn: - items = request.json['items'] - receipt_id = database.request_receipt_id(conn, site_name) - receipt_id = f"SIR-{receipt_id}" - receipt = MyDataclasses.ReceiptPayload( - receipt_id=receipt_id, - submitted_by=user_id - ) - receipt = database.insertReceiptsTuple(conn, site_name, receipt.payload(), convert=True) - - for item in items: - - receipt_item = MyDataclasses.ReceiptItemPayload( - type=item['type'], - receipt_id=receipt['id'], - barcode=item['item']['barcode'], - name=item['item']['item_name'], - qty=item['item']['qty'], - uom=item['item']['uom'], - data=item['item']['data'] - ) - database.insertReceiptItemsTuple(conn, site_name, receipt_item.payload()) - #webpush.push_notifications('New Receipt', f"Receipt {receipt['receipt_id']} was added to Site -> {site_name}!") - webpush.push_ntfy('New Receipt', f"Receipt {receipt['receipt_id']} was added to Site -> {site_name}!") - return jsonify({"error":False, "message":"Transaction Complete!"}) + data= {'items': request.json['items']} + status = poe_processes.post_receipt(site_name, user_id, data) + return jsonify(status) return jsonify({"error":True, "message":"There was an error with this POST statement"}) \ No newline at end of file diff --git a/application/poe/poe_database.py b/application/poe/poe_database.py index 3b93697..3d690b2 100644 --- a/application/poe/poe_database.py +++ b/application/poe/poe_database.py @@ -2,6 +2,36 @@ import psycopg2 import config from application import postsqldb +def request_receipt_id(conn, site_name): + """gets the next id for receipts_id, currently returns a 8 digit number + + Args: + site (str): site to get the next id for + + Returns: + json: receipt_id, message, error keys + """ + next_receipt_id = None + sql = f"SELECT receipt_id FROM {site_name}_receipts ORDER BY id DESC LIMIT 1;" + try: + database_config = config.config() + with psycopg2.connect(**database_config) as conn: + with conn.cursor() as cur: + cur.execute(sql) + next_receipt_id = cur.fetchone() + if next_receipt_id == None: + next_receipt_id = "00000001" + else: + next_receipt_id = next_receipt_id[0] + next_receipt_id = int(next_receipt_id.split("-")[1]) + 1 + y = str(next_receipt_id) + len_str = len(y) + x = "".join(["0" for _ in range(8 - len_str)]) + next_receipt_id = x + y + except (Exception, psycopg2.DatabaseError) as error: + raise postsqldb.DatabaseError(error, payload=(), sql=sql) + + return next_receipt_id def selectItemLocationsTuple(site_name, payload, convert=True): """select a single tuple from ItemLocations table for site_name @@ -198,6 +228,93 @@ def insertTransactionsTuple(site, payload, convert=True, conn=None): raise postsqldb.DatabaseError(error, payload, sql) return transaction +def insertReceiptsTuple(site, payload, convert=True, conn=None): + """insert payload into receipt table of site + + Args: + conn (_T_connector@connect): Postgresql Connector + site (str): + payload (tuple): + convert (bool, optional): Determines if to return tuple as dictionary. Defaults to False. + + Raises: + DatabaseError: + + Returns: + tuple or dict: inserted tuple + """ + receipt = () + self_conn = False + with open(f"application/poe/sql/insertReceiptsTuple.sql", "r+") as file: + sql = file.read().replace("%%site_name%%", site) + 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: + receipt = postsqldb.tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + receipt = rows + + if self_conn: + conn.commit() + conn.close() + + return receipt + + except Exception as error: + raise postsqldb.DatabaseError(error, payload, sql) + +def insertReceiptItemsTuple(site, payload, convert=True, conn=None): + """insert payload into receipt_items table of site + + Args: + conn (_T_connector@connect): Postgresql Connector + site (str): + payload (tuple): (type[str], receipt_id[int], barcode[str], name[str], + qty[float], data[jsonb], status[str]) + convert (bool, optional): Determines if to return tuple as dictionary. Defaults to False. + + Raises: + DatabaseError: + + Returns: + tuple or dict: inserted tuple + """ + receipt_item = () + self_conn = False + + with open(f"application/poe/sql/insertReceiptItemsTuple.sql", "r+") as file: + sql = file.read().replace("%%site_name%%", site) + 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: + receipt_item = postsqldb.tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + receipt_item = rows + + if self_conn: + conn.commit() + conn.close() + + return receipt_item + + except Exception as error: + raise postsqldb.DatabaseError(error, payload, sql) def updateCostLayersTuple(site, payload, convert=True, conn=None): """_summary_ diff --git a/application/poe/poe_processes.py b/application/poe/poe_processes.py index dcfc930..1d0a9e0 100644 --- a/application/poe/poe_processes.py +++ b/application/poe/poe_processes.py @@ -1,4 +1,4 @@ -from application import postsqldb +from application import postsqldb, database_payloads from application.poe import poe_database import datetime @@ -97,7 +97,47 @@ def postTransaction(site_name, user_id, data: dict, conn=None): #database.insertTransactionsTuple(conn, site_name, transaction.payload()) if self_conn: - conn.rollback() + conn.commit() conn.close() - return {"error": False, "message":f"Transaction Successful!"} \ No newline at end of file + return {"error": False, "message":f"Transaction Successful!"} + +def post_receipt(site_name, user_id, data: dict, conn=None): + # data = {'items': items} + self_conn = False + items = data['items'] + if not conn: + database_config = config.config() + conn = psycopg2.connect(**database_config) + conn.autocommit = False + self_conn = True + + receipt_id = poe_database.request_receipt_id(conn, site_name) + receipt_id = f"SIR-{receipt_id}" + receipt = database_payloads.ReceiptPayload( + receipt_id=receipt_id, + submitted_by=user_id + ) + #receipt = database.insertReceiptsTuple(conn, site_name, receipt.payload(), convert=True) + receipt = poe_database.insertReceiptsTuple(site_name, receipt.payload(), conn=conn) + for item in items: + + receipt_item = database_payloads.ReceiptItemPayload( + type=item['type'], + receipt_id=receipt['id'], + barcode=item['item']['barcode'], + name=item['item']['item_name'], + qty=item['item']['qty'], + uom=item['item']['uom'], + data=item['item']['data'] + ) + #database.insertReceiptItemsTuple(conn, site_name, receipt_item.payload()) + poe_database.insertReceiptItemsTuple(site_name, receipt_item.payload(), conn=conn) + #webpush.push_notifications('New Receipt', f"Receipt {receipt['receipt_id']} was added to Site -> {site_name}!") + #webpush.push_ntfy('New Receipt', f"Receipt {receipt['receipt_id']} was added to Site -> {site_name}!") + + if self_conn: + conn.commit() + conn.close() + + return {"error":False, "message":"Transaction Complete!"} diff --git a/application/poe/sql/insertReceiptItemsTuple.sql b/application/poe/sql/insertReceiptItemsTuple.sql new file mode 100644 index 0000000..6aeb85f --- /dev/null +++ b/application/poe/sql/insertReceiptItemsTuple.sql @@ -0,0 +1,4 @@ +INSERT INTO %%site_name%%_receipt_items +(type, receipt_id, barcode, name, qty, uom, data, status) +VALUES (%s, %s, %s, %s, %s, %s, %s, %s) +RETURNING *; \ No newline at end of file diff --git a/application/poe/sql/insertReceiptsTuple.sql b/application/poe/sql/insertReceiptsTuple.sql new file mode 100644 index 0000000..8ddaf60 --- /dev/null +++ b/application/poe/sql/insertReceiptsTuple.sql @@ -0,0 +1,4 @@ +INSERT INTO %%site_name%%_receipts +(receipt_id, receipt_status, date_submitted, submitted_by, vendor_id, files) +VALUES (%s, %s, %s, %s, %s, %s) +RETURNING *; \ No newline at end of file diff --git a/application/poe/static/js/receiptsHandler.js b/application/poe/static/js/receiptsHandler.js index 0ecb98b..67b9c34 100644 --- a/application/poe/static/js/receiptsHandler.js +++ b/application/poe/static/js/receiptsHandler.js @@ -30,511 +30,20 @@ async function changeSite(site){ location.reload(true) } -async function replenishItemsTable(items) { - let itemsTableBody = document.getElementById("itemsTableBody") - itemsTableBody.innerHTML = "" - - for(let i = 0; i < items.length; i++){ - let tableRow = document.createElement('tr') - let idCell = document.createElement('td') - idCell.innerHTML = items[i].id - let barcodeCell = document.createElement('td') - barcodeCell.innerHTML = items[i].barcode - let nameCell = document.createElement('td') - nameCell.innerHTML = items[i].item_name - - tableRow.append(idCell) - tableRow.append(barcodeCell) - tableRow.append(nameCell) - - tableRow.onclick = function(){ - selectItem(items[i].id) - } - - itemsTableBody.append(tableRow) - } -} - -async function populateForm() { - if (item){ - console.log(item) - document.getElementById('database_id').value = item.id - document.getElementById('barcode').value = item.barcode - document.getElementById('name').value = item.item_name - document.getElementById('transaction_cost').value = parseFloat(item.item_info.cost) - - await selectLocation( - item.logistics_info.primary_zone.id, - item.logistics_info.primary_location.id, - item.logistics_info.primary_zone.name, - item.logistics_info.primary_location.name - ) - - - let quantity_on_hand = 0 - let locations = await getItemLocations() - for(let i = 0; i < locations.length; i++){ - quantity_on_hand = quantity_on_hand + locations[i].quantity_on_hand - } - document.getElementById('QOH').value = quantity_on_hand - document.getElementById('UOM').value = item.item_info.uom.fullname - - await replenishItemLocationsTable(locations) - - } -} - -async function selectItem(id) { - UIkit.modal(document.getElementById("itemsModal")).hide(); - item = await getItem(id) - await populateForm() -} - -var transaction_zone_id = 0 -var transaction_item_location_id = 0 -async function selectLocation(zone_id, location_id, zone_name, location_name) { - document.getElementById('zone').value = zone_name - document.getElementById('location').value = location_name - transaction_zone_id = zone_id - transaction_item_location_id = location_id -} - -async function openItemsModal(elementID){ - UIkit.modal(document.getElementById("itemsModal")).show(); - pagination_current = 1 - search_string = '' - let items = await getItems() - await replenishItemsTable(items) - await updatePaginationElement(elementID) - setFormButtonsEnabled(true) -} - -async function setFormButtonsEnabled(state) { - let item_location_button = document.getElementById("itemLocations") - - if(state){ - item_location_button.classList.remove("uk-disabled") - } else { - item_location_button.classList.add("uk-disabled") - } -} - -async function setTransactionTypeAdjustments() { - let trans_type = document.getElementById('trans_type').value - - if(trans_type=="Adjust Out"){ - document.getElementById('transaction_cost').classList.add('uk-disabled') - } - if(trans_type=="Adjust In"){ - document.getElementById('transaction_cost').classList.remove('uk-disabled') - } - -} - -async function replenishItemLocationsTable(locations) { - let itemLocationTableBody = document.getElementById('itemLocationTableBody') - itemLocationTableBody.innerHTML = "" - for(let i = 0; i < locations.length; i++){ - let tableRow = document.createElement('tr') - - let loca = locations[i].uuid.split('@') - - let zoneCell = document.createElement('td') - zoneCell.innerHTML = loca[0] - - let locationCell = document.createElement('td') - locationCell.innerHTML = loca[1] - - let qohCell = document.createElement('td') - qohCell.innerHTML = parseFloat(locations[i].quantity_on_hand) - - tableRow.append(zoneCell, locationCell, qohCell) - tableRow.onclick = async function(){ - await selectLocation( - locations[i].zone_id, - locations[i].id, - loca[0], - loca[1] - ) - } - itemLocationTableBody.append(tableRow) - } -} - -let locations_limit = 10; -async function getItemLocations() { - console.log("getting Locations") - const url = new URL('/external/getItemLocations', window.location.origin); - url.searchParams.append('page', pagination_current); - url.searchParams.append('limit', locations_limit); - url.searchParams.append('id', item.id); - const response = await fetch(url); - data = await response.json(); - pagination_end = data.end - let locations = data.locations; - console.log(locations) - return locations; -} - - -let items_limit = 50; -async function getItems() { - console.log("getting items") - const url = new URL('/external/getModalItems', window.location.origin); - url.searchParams.append('page', pagination_current); - url.searchParams.append('limit', items_limit); - url.searchParams.append('search_string', search_string) - const response = await fetch(url); - data = await response.json(); - pagination_end = data.end - let items = data.items; - return items; -} - -async function getItem(id) { - console.log(`selected item: ${id}`) - const url = new URL('/external/getItem', window.location.origin); - url.searchParams.append('id', id); - const response = await fetch(url); - data = await response.json(); - item = data.item; - return item; -} - -async function validateTransaction() { - let database_id = document.getElementById("database_id") - let transaction_type = document.getElementById("trans_type") - let transaction_zone = document.getElementById("zone") - let transaction_location = document.getElementById("location") - let transaction_quantity = document.getElementById("transaction_quantity") - let transaction_cost = document.getElementById("transaction_cost") - - - let error_count = 0 - if(database_id.value === ""){ - error_count = error_count + 1 - database_id.classList.add("uk-form-danger") - } else { - database_id.classList.remove("uk-form-danger") - } - if(transaction_type.value === "0"){ - error_count = error_count + 1 - transaction_type.classList.add("uk-form-danger") - } else { - transaction_type.classList.remove("uk-form-danger") - } - - if (transaction_zone.value === ""){ - error_count = error_count + 1 - transaction_zone.classList.add("uk-form-danger") - } else { - transaction_zone.classList.remove("uk-form-danger") - } - - if (transaction_location.value === ""){ - error_count = error_count + 1 - transaction_location.classList.add("uk-form-danger") - } else { - transaction_location.classList.remove("uk-form-danger") - } - - let transaction_quantity_int = parseFloat(transaction_quantity.value) - if (transaction_quantity_int === 0.00 || transaction_quantity_int < 0.00){ - error_count = error_count + 1 - transaction_quantity.classList.add("uk-form-danger") - } else { - transaction_quantity.classList.remove("uk-form-danger") - } - - let transaction_cost_int = parseFloat(transaction_cost.value) - if (transaction_cost_int == 0.00 && transaction_type.value == "Adjust In"){ - error_count = error_count + 1 - transaction_cost.classList.add("uk-form-danger") - } else { - transaction_cost.classList.remove("uk-form-danger") - } - - if(error_count > 0){ - return false - } - - return true -} - -async function submitTransaction() { - let validated = await validateTransaction() - if (validated){ - let cost = parseFloat(document.getElementById('transaction_cost').value.replace(/[^0-9.-]+/g, "")); - const response = await fetch(`/external/postTransaction`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_id: item.id, - logistics_info_id: item.logistics_info_id, - barcode: item.barcode, - item_name: item.item_name, - transaction_type: document.getElementById('trans_type').value, - quantity: parseFloat(document.getElementById('transaction_quantity').value), - description: document.getElementById('transaction_description').value, - cost: cost, - vendor: 0, - expires: null, - location_id: transaction_item_location_id - }), - }); - data = await response.json(); - transaction_status = "success" - if (data.error){ - transaction_status = "danger" - } - - UIkit.notification({ - message: data.message, - status: transaction_status, - pos: 'top-right', - timeout: 5000 - }); - - item = await getItem(item.id) - await populateForm() - document.getElementById('transaction_quantity').value = '0.00' - - } else { - UIkit.notification({ - message: 'Please verify your transaction receipt.', - status: 'warning', - pos: 'top-right', - timeout: 5000 - }) -} -} - -async function searchTable(event, logis, elementID) { - if(event.key==='Enter' && logis==='items'){ - search_string = event.srcElement.value - let items = await getItems() - await replenishItemsTable(items) - } - await updatePaginationElement(elementID) -} - -async function setPage(pageNumber, elementID){ - pagination_current = pageNumber; - - if(elementID=="itemsPage"){ - let items = await getItems() - await replenishItemsTable(items) - } - await updatePaginationElement(elementID) -} - -async function updatePaginationElement(elementID) { - let paginationElement = document.getElementById(elementID); - paginationElement.innerHTML = ""; - // previous - let previousElement = document.createElement('li') - if(pagination_current<=1){ - previousElement.innerHTML = ``; - previousElement.classList.add('uk-disabled'); - }else { - previousElement.innerHTML = ``; - } - paginationElement.append(previousElement) - - //first - let firstElement = document.createElement('li') - if(pagination_current<=1){ - firstElement.innerHTML = `1`; - firstElement.classList.add('uk-disabled'); - }else { - firstElement.innerHTML = `1`; - } - paginationElement.append(firstElement) - - // ... - if(pagination_current-2>1){ - let firstDotElement = document.createElement('li') - firstDotElement.classList.add('uk-disabled') - firstDotElement.innerHTML = ``; - paginationElement.append(firstDotElement) - } - // last - if(pagination_current-2>0){ - let lastElement = document.createElement('li') - lastElement.innerHTML = `${pagination_current-1}` - paginationElement.append(lastElement) - } - // current - if(pagination_current!=1 && pagination_current != pagination_end){ - let currentElement = document.createElement('li') - currentElement.innerHTML = `
  • ${pagination_current}
  • ` - paginationElement.append(currentElement) - } - // next - if(pagination_current+2${pagination_current+1}` - paginationElement.append(nextElement) - } - // ... - if(pagination_current+2<=pagination_end){ - let secondDotElement = document.createElement('li') - secondDotElement.classList.add('uk-disabled') - secondDotElement.innerHTML = ``; - paginationElement.append(secondDotElement) - } - //end - let endElement = document.createElement('li') - if(pagination_current>=pagination_end){ - endElement.innerHTML = `${pagination_end}`; - endElement.classList.add('uk-disabled'); - }else { - endElement.innerHTML = `${pagination_end}`; - } - paginationElement.append(endElement) - //next button - let nextElement = document.createElement('li') - if(pagination_current>=pagination_end){ - nextElement.innerHTML = ``; - nextElement.classList.add('uk-disabled'); - }else { - nextElement.innerHTML = ``; - console.log(nextElement.innerHTML) - } - paginationElement.append(nextElement) -} - -var scannedItems = Array(); -const queueLimit = 5; // 49 should be default - -async function addToQueue(event) { - if (event.key == "Enter"){ - let data = await getItemBarcode(document.getElementById('barcode-scan').value) - let scannedItem = data.item - if(data.error){ - UIkit.notification({ - message: data.message, - status: "danger", - pos: 'top-right', - timeout: 5000 - }); - } - if(scannedItems.length > queueLimit){ - scannedItems.shift() - } - if(!Array.isArray(scannedItem) && !data.error){ - let status = await submitScanTransaction(scannedItem) - scannedItems.push({'item': scannedItem, 'type': `${document.getElementById('scan_trans_type').value}`, 'error': status}) - document.getElementById('barcode-scan').value = "" - } - } - await replenishScanTable() -} async function getItemBarcode(barcode) { console.log(`selected item: ${barcode}`) - const url = new URL('/external/getItem/barcode', window.location.origin); + const url = new URL('/poe/getItem/barcode', window.location.origin); url.searchParams.append('barcode', barcode); const response = await fetch(url); data = await response.json(); return data; } -async function submitScanTransaction(scannedItem) { - /// I need to find the location that matches the items auto issue location id - - let trans_type = document.getElementById('scan_trans_type').value - let scan_transaction_item_location_id = 0 - let comparator = 0 - - if (trans_type === "Adjust In"){ - comparator = scannedItem.logistics_info.primary_location.id - } else if (trans_type === "Adjust Out"){ - comparator = scannedItem.logistics_info.auto_issue_location.id - } - - for (let i = 0; i < scannedItem.item_locations.length; i++){ - if (scannedItem.item_locations[i].location_id === comparator){ - scan_transaction_item_location_id = scannedItem.item_locations[i].id - } - } - - const response = await fetch(`/external/postTransaction`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_id: scannedItem.id, - logistics_info_id: scannedItem.logistics_info_id, - barcode: scannedItem.barcode, - item_name: scannedItem.item_name, - transaction_type: document.getElementById('scan_trans_type').value, - quantity: scannedItem.item_info.uom_quantity, - description: "", - cost: parseFloat(scannedItem.item_info.cost), - vendor: 0, - expires: null, - location_id: scan_transaction_item_location_id - }), - }); - data = await response.json(); - transaction_status = "success" - if (data.error){ - transaction_status = "danger" - } - - UIkit.notification({ - message: data.message, - status: transaction_status, - pos: 'top-right', - timeout: 5000 - }); - - return data.error - -} - -async function replenishScanTable() { - let scanTableBody = document.getElementById("scanTableBody") - scanTableBody.innerHTML = "" - - let reversedScannedItems = scannedItems.slice().reverse() - - for(let i = 0; i < reversedScannedItems.length; i++){ - let tableRow = document.createElement('tr') - - let icon = `` - if(reversedScannedItems[i].error){ - icon = `` - } - - let statusCell = document.createElement('td') - statusCell.innerHTML = icon - let barcodeCell = document.createElement('td') - barcodeCell.innerHTML = reversedScannedItems[i].item.barcode - let nameCell = document.createElement('td') - nameCell.innerHTML = reversedScannedItems[i].item.item_name - let typeCell = document.createElement('td') - typeCell.innerHTML = reversedScannedItems[i].type - let locationCell = document.createElement('td') - if (reversedScannedItems[i].type === "Adjust In"){ - locationCell.innerHTML = reversedScannedItems[i].item.logistics_info.primary_location.uuid - } else { - locationCell.innerHTML = reversedScannedItems[i].item.logistics_info.auto_issue_location.uuid - } - - tableRow.append(statusCell, barcodeCell, nameCell, typeCell, locationCell) - scanTableBody.append(tableRow) - } -} - async function submitScanReceipt(items) { - const response = await fetch(`/external/postReceipt`, { + const response = await fetch(`/poe/postReceipt`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -585,7 +94,6 @@ async function completeReceipt() { scanReceiptTableBody.innerHTML = "" scannedReceiptItems = Array() - } async function closeReceipt(){ @@ -611,7 +119,6 @@ async function addToReceipt(event) { let scannedItem = data.item if(scannedItem){ let expires = scannedItem.food_info.expires - console.log(expires) if(scannedItem.food_info.expires){ let today = new Date(); today.setDate(today.getDate() + Number(scannedItem.food_info.default_expiration)) diff --git a/application/poe/templates/receipts.html b/application/poe/templates/receipts.html index 5eed667..f812556 100644 --- a/application/poe/templates/receipts.html +++ b/application/poe/templates/receipts.html @@ -146,6 +146,53 @@ + +
    +
    +

    Edit Line...

    +

    Edit any fields here for the selected Line and then save them.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    QTY
    QTY
    UOM + +
    COST
    EXPIRES
    +

    + + +

    +
    +
    {% assets "js_all" %} diff --git a/database.log b/database.log index fca24ac..edaa2c5 100644 --- a/database.log +++ b/database.log @@ -1937,4 +1937,10 @@ sql='UPDATE test_itemlinks SET conv_factor = %s WHERE id=%s RETURNING *;') 2025-07-02 18:04:47.600077 --- ERROR --- DatabaseError(message='not all arguments converted during string formatting', payload=(1, 2), - sql='SELECT * FROM main_locations WHERE id=%s;') \ No newline at end of file + sql='SELECT * FROM main_locations WHERE id=%s;') +2025-07-02 18:32:23.140191 --- ERROR --- DatabaseError(message='invalid input syntax for type integer: ""LINE 3: ...041789001314%', 'Chicken Ramen Noodle Soup', '2', '', '{"cos... ^', + payload=('sku', 19, '%041789001314%', 'Chicken Ramen Noodle Soup', '2', '', '{"cost": "1.99", "expires": false}', 'Unresolved'), + sql='INSERT INTO test_receipt_items(type, receipt_id, barcode, name, qty, uom, data, status) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') +2025-07-04 08:19:34.889657 --- ERROR --- DatabaseError(message='invalid input syntax for type integer: "{"cost": 1.99, "expires": false}"LINE 3: ...41789001314%', 'Chicken Ramen Noodle Soup', 1, 5, '{"cost": ... ^', + payload=('sku', 23, '%041789001314%', 'Chicken Ramen Noodle Soup', 1, 5, '{"cost": 1.99, "expires": false}', 'Unresolved'), + sql='INSERT INTO test_recipe_items(uuid, rp_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;') \ No newline at end of file