From 29ba974704bb3b62a03544e26f90ecbf821cbd41 Mon Sep 17 00:00:00 2001 From: Jadowyne Ulve Date: Sat, 9 Aug 2025 11:10:18 -0500 Subject: [PATCH] Added PLU DASH and fixed receipt scanner --- .../database_payloads.cpython-313.pyc | Bin 27799 -> 27853 bytes .../sql/CREATE/receipt_items.sql | 3 +- application/database_payloads.py | 2 + .../poe/__pycache__/poe_api.cpython-313.pyc | Bin 4649 -> 5814 bytes .../__pycache__/poe_database.cpython-313.pyc | Bin 21216 -> 20947 bytes .../__pycache__/poe_processes.cpython-313.pyc | Bin 5852 -> 5894 bytes application/poe/poe_api.py | 15 +++ application/poe/poe_database.py | 41 +++--- application/poe/poe_processes.py | 1 + .../poe/sql/insertReceiptItemsTuple.sql | 4 +- application/poe/sql/receipts/getPLUItems.sql | 4 + .../poe/sql/scanner/selectItemByBarcode.sql | 5 + application/poe/static/js/receiptsHandler.js | 121 +++++++++++++++--- application/poe/templates/receipts.html | 61 ++++++++- application/poe/templates/scanner.html | 2 +- logs/database.log | 5 +- 16 files changed, 212 insertions(+), 52 deletions(-) create mode 100644 application/poe/sql/receipts/getPLUItems.sql diff --git a/application/__pycache__/database_payloads.cpython-313.pyc b/application/__pycache__/database_payloads.cpython-313.pyc index 7c9c46e6727be9a9254181a060724bbf0cbad2c3..134fe43aeade247942effad063ee847f1e1c100f 100644 GIT binary patch delta 574 zcmWkqYe>^^6#bw1sQqORH%Oft8rpEoIh~oa(#!`|I4i&5-z}`Khs1nY-R-j1) z_St||Rk3i&r4=KEWx#oUFZzmZ&hH;Y6VDa@MvpjkU5}6dmOWkr)*>5BY)TTsb_ha{ZN8fN2ru`3SrezpB-+vn;C_#WYuICNR&tN2c(e z_1k;BgBR@k`G e{2IH(qmzn8eO+oxpSnD3xuBtPCP5UO4dOp?cEl_I delta 581 zcmW-dT}V@L7{<@DY;$Kj`=})5a)D7(5#3TFEobHk%em4sH-%%gmL@D(9J{mZV`5k| zsJBuguOg&c==xs-!c3`)ilh&Tw2M+IyeSL3NFt%Xz85d=^SnQvi)V5M{WCBvN|Gq> ziT2*=SgcH$ii^-g?iL4)J9GT9R@Et)%34|HXi(x^eajca|Oj9i{(&_ih;X^ zRmP}FtBka&Oxc2JlFh35xFz38?}}WcE%riBIa{yOrVRlatuh)sJWNflEImbBA?-Q{ zLT5dVyBzf0m9MkvE#hxMPg(A>S+$(HB+QCZeE+m%ef;3GWQqGI=`MvxbM7~Au+(-l z;A9geexQIXWh>rn*+!t0E$z4sR1xj$L@DXY|DujG6_b$ZZN*OnX>8XJ>R9`3ClF?d z$^zg7|75c%508pb?w)yckyt%|Fx{5$?VAod?pa-v1eR&I%9l&{x#eFoZO1X-wfgeP|rRC%Pf`@Y@y`z#Kge zq%lvYn!5S@t0{p6)*aji%_3+yVyB7FBmALQ^BFAAkLE!vv&$_PHCV$Wr3NriL+b@B z(^Tt6SlPqFPXHT>94P@dQ-62_R;oSvK%1xGt+&(F;2_bSzi*N)Q~>WkXQ6Sc9vs2BeM!L!1| diff --git a/application/administration/sql/CREATE/receipt_items.sql b/application/administration/sql/CREATE/receipt_items.sql index cfb9eb6..2e04a88 100644 --- a/application/administration/sql/CREATE/receipt_items.sql +++ b/application/administration/sql/CREATE/receipt_items.sql @@ -2,7 +2,8 @@ CREATE TABLE IF NOT EXISTS %%site_name%%_receipt_items ( id SERIAL PRIMARY KEY, type VARCHAR(255) NOT NULL, receipt_id INTEGER NOT NULL, - barcode VARCHAR(255) NOT NULL, + barcode VARCHAR(255), + item_uuid UUID, name VARCHAR(255) NOT NULL, qty FLOAT8 NOT NULL, uom VARCHAR(32) NOT NULL, diff --git a/application/database_payloads.py b/application/database_payloads.py index 0f692d0..84cd7d8 100644 --- a/application/database_payloads.py +++ b/application/database_payloads.py @@ -265,6 +265,7 @@ class ReceiptItemPayload: type: str receipt_id: int barcode: str + item_uuid: str name: str qty: float = 1.0 uom: str = "each" @@ -276,6 +277,7 @@ class ReceiptItemPayload: self.type, self.receipt_id, self.barcode, + self.item_uuid, self.name, self.qty, self.uom, diff --git a/application/poe/__pycache__/poe_api.cpython-313.pyc b/application/poe/__pycache__/poe_api.cpython-313.pyc index 18a2a52157b79a70ed89500874e2b33debdd2860..51c9bc93269a544f64db3d0c4f53c6f94d17d64a 100644 GIT binary patch delta 1172 zcmZXSO>7%Q6vt=w!ymEZuU(tkN!@jAL0uAz-9*UXCQ9=~AZ-F0!yyvLIO}*Nd)Lga z1qx~nT-X{%Ns(GMg*Jz!&@RK_<>xf!Jg1Q%v(tO^)ue{bG<|2Mn) z-rR`Xo^%|Kj*bAl{F&YSWk=0%f?A@!I`a{%eH(K0}`neYJZh z{r&)$CPjD+EgIjZqJe{FsWI!MHkOQy>SUj!Vdg%Q_71nuNy4mMzFd zSwBjE3IJ#vM~;5P*l{mOdNwbJ$oxuWQ3 ziuh#K$V}iQ8P|U&jL0N9*2NFAQc0Ip1)alw)P&BHk{N;|5t!6mPLp&rMACjOZmO0#SC7*R2tqrt(jVDaqCU{I{pkhSNAmL_fy}QzjxesG-ubE zYo%uV{gw?i8T7{!7P$P!0Fnc_K*O^){|$F1{dJ(lE&O6%_^U^g%%2**IpBWs^o1mN zkQ|v0(GO{Eew=>jgJeI>V(z$NB~{Zm4qmmr3E{GF-R_4g#x46zR>ZZl2g>NDFuqJ$ zMQ#ULAs{{7K(CYSDn``&bdrO~yy#+FJRntm;MHZuo4ge delta 209 zcmdm{yHbVkGcPX}0}xE#F*#!a_e4GkreBO3HL4jIMJ67QWfYx!h*6taELddn2Sy{7 zbS6!S%|%SooSUcfM=~3v&mp`~bBgmS-F5};^{QMW~cR-^(73KnRk23p)*gG8fd zG+;DHVoZ2cHzueL3KZj$mWxu2A^ZUi0TUAO!EYrdev_G;Ip;fPW-_Z!@Zw|4Z0K}q z1ogIKv^Uf9jM>UJD`88)+*p?(bPok_OdgcQXtH9eCeea=;>|g+LlJ~g3A$7cWJBa) zZ4F7~xSeivs0t&fcr#7M%4KFK4yv&G>lSj zwru)uG#M|-BJV0~Bw)80o_i@fieO&mfQXnTLK^M6u$NHI8cN%4B5MIVJKd_Rl?Vgs%3*Lp=_!qo6O^9~DX*@koRZ3xy6&11A5;YbE5F%ap@~ zyTj1|fiFKF78;K>*9+l(zKp-v$N8a)tAiy#63)G3>9~m~^Yr9WNv@MS3iMa~e~wPc z;gB4AC5htVm&u2c-NlB1(D`UAB!vG(bIqV9Ve(Fl&=6YH=!V#oA$_QxyvVB<^h^m$ zD)zlRWwkvjykGdBc-dMyZ!MjSPYH`wc38hjA+-;$$r-v1uj+Q(Y9DF8adxabrPbeR z7-<;OPnwssu9Puj)N{u}YKPesy>VRerLAMp+_})!kqovxR4rTF3l{g3@s0hZ{e8}7 zOJKgOzS!*9iScQ%*E>nkUBIwn`azS#6dmfPa4Q+}_0Si9?-H@! zK-2vIuZtNCL7L_Oj*GFz*Em=DBu+Yolkzz!nUlge$;n9`jw8pKcB?M|gnvYQHxZf+ Sq-Ehc{Bs|9)wD-00Q(070P{Bh delta 1218 zcmYjRO-vg{6rSoV8x`a6VwFQcZ!I(lwz}~pfx)pJa-B>YeSR7QM zsO0EKkpdYia;QkEsBLxp&O2s`7tQb47RqyHWl##KxV_* zeFQ*=ZG-z*Vmg)ph%^Hb=1bNwRw~<%4XGryos#JgE2#++q9qO4CGIfMnAZ%6)+jDs$! z8pNTy{FFk*?LV!MObUy|Hl0k!=iDkqN0>&!Xrn24c03-5rc=tcCXtR!jwj@JYFl?c zH90A4FHk*TRxn4Q z)I>~q9|z>{J2Qn=Tz&J#hTFcirn?tFtJ|f(eEGZZ8C|ZC;1h#oSzHvCY&YwQ zf@xX1sLfTi+!=i&bQP_Y%NG|fqR$rS$0qAa|BmR~5<4G?ool`KhJP5|JY5ij3qEZ6 znk|ae3%*?*7_0vlfKX8s%*)&&x1=kYteF$LHh`=B#`nM6Rb!9OZF?^c%>zT_7jJKg zO?j~?r*D1^AZ}&HC~g_u4~_2I^|_8f!5GZxf_u*>VtP5#g=crazP8UnJ zI{I3uby$OybqCjXj9qWx{E%JmVllHpSNc1s4ZGFfMs2h)7)NQGp|r@?p8d7)GR1s| zseiH`H0{#N84NAi_ul-2W}+B2X9qfs5PpR0-U{qnRH2jI-!pM+8O~~so3SNp_fAqU zjIQ`57#Z`E*}r@O!%Sm%CCd#;3^R-2x7m+}e}qnQ0TfbAIYR`gppaw=iBw38GK;(c e8#jj``N7OgptFH))&(W_Vg#bqfP?-N)Bgf>@iGqp diff --git a/application/poe/__pycache__/poe_processes.cpython-313.pyc b/application/poe/__pycache__/poe_processes.cpython-313.pyc index 9fd9d8a55abcf428a38e0c4cb041f0a55dc8c25a..e02cea010a354cff4fffb28e94003d0f49e122cf 100644 GIT binary patch delta 271 zcmcbk+os3&nU|M~0SIJ@re}zYZsfZpz{LaPG6V7Fw8^goau|gthYKEO%$_VSR3#M3 z8O+HFlnUktlLD3;ljjO~GUiTxE)>ow7%Zg6q{5&nGTB|&-SHM@W=U#pd}(QBN|7{B zOOZE_xW!zWpIgKRWNC5~g@8nZK!g;C2m=vvAOfVaD17sNVGTyEcpy6sh>NWze-zoy zEhaU?Y+}v=>x*Lglb4GcatLxtaCPu}5t;lzRGLkkK~U_Q)MQ4nVtJ6ZB3%$61S0r> h#4Qe+-29Z%oK(A_wE!Z`(k1@)Lz7&L_^hYGtJ7D)p&6?p@RTg;{TxkYS1mL_{q2uL&t zL`Z=MIS>I-R1~)PuCN9pR~(R?2E@gBlleurPrf8-z`@TU!PUX@MQAdYm^7OxgP_Xt%=T8v~Fk5(4T505!xgNB{r; diff --git a/application/poe/poe_api.py b/application/poe/poe_api.py index 71fdbb9..39bf225 100644 --- a/application/poe/poe_api.py +++ b/application/poe/poe_api.py @@ -45,6 +45,21 @@ 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"}) +@point_of_ease.route('/api/paginatePLUItems', methods=['GET']) +@access_api.login_required +def paginatePLUItems(): + if request.method == 'GET': + page = int(request.args.get('page', 1)) + limit = int(request.args.get('limit', 50)) + site_name = session['selected_site'] + offset = (page - 1) * limit + try: + items = poe_database.paginatePLUItems(site_name, (limit, offset)) + return jsonify(items=items, status=201, message="Fetch Successful!") + except Exception as error: + return jsonify(items=[], status=400, message=str(error)) + return jsonify(items=[], status=405, message=f"The method: {request.method} is not allowed on this endpoint!") + @point_of_ease.route('/postTransaction', methods=["POST"]) @access_api.login_required def post_transaction(): diff --git a/application/poe/poe_database.py b/application/poe/poe_database.py index 07544ac..dd0d6df 100644 --- a/application/poe/poe_database.py +++ b/application/poe/poe_database.py @@ -205,45 +205,34 @@ def selectItemByBarcode(site, payload, convert=True, conn=None): except (Exception, psycopg2.DatabaseError) as error: raise postsqldb.DatabaseError(error, payload, selectItemByBarcode_sql) -def selectItemAllByBarcode(site, payload, convert=True, conn=None): +def paginatePLUItems(site, payload, convert=True, conn=None): + """ payload = (limit, offset) """ item = () self_conn = False - if convert: - item = {} - if not conn: database_config = config.config() conn = psycopg2.connect(**database_config) conn.autocommit = True self_conn = True - linked_item = selectLinkedItemByBarcode(site, (payload[0],)) + with open(f"application/poe/sql/receipts/getPLUItems.sql", "r+") as file: + getPLUItems_sql = file.read().replace("%%site_name%%", site) + try: + + with conn.cursor() as cur: + cur.execute(getPLUItems_sql, payload) + rows = cur.fetchall() + if rows and convert: + item = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows] + if rows and not convert: + item = rows - if len(linked_item) > 1: - item = selectItemAllByID(site, payload=(linked_item['link'], ), convert=convert) - item['item_info']['uom_quantity'] = linked_item['conv_factor'] if self_conn: conn.close() return item - else: - with open(f"application/poe/sql/getItemAllByBarcode.sql", "r+") as file: - getItemAllByBarcode_sql = file.read().replace("%%site_name%%", site) - try: - - with conn.cursor() as cur: - cur.execute(getItemAllByBarcode_sql, payload) - rows = cur.fetchone() - if rows and convert: - item = postsqldb.tupleDictionaryFactory(cur.description, rows) - if rows and not convert: - item = rows - - if self_conn: - conn.close() - return item - except (Exception, psycopg2.DatabaseError) as error: - raise postsqldb.DatabaseError(error, payload, getItemAllByBarcode_sql) + except (Exception, psycopg2.DatabaseError) as error: + raise postsqldb.DatabaseError(error, payload, getPLUItems_sql) def insertCostLayersTuple(site, payload, convert=True, conn=None): cost_layer = () diff --git a/application/poe/poe_processes.py b/application/poe/poe_processes.py index 6d187f6..685e8fe 100644 --- a/application/poe/poe_processes.py +++ b/application/poe/poe_processes.py @@ -122,6 +122,7 @@ def post_receipt(site_name, user_id, data: dict, conn=None): type=item['type'], receipt_id=receipt['id'], barcode=item['item']['barcode'], + item_uuid=item['item']['item_uuid'], name=item['item']['item_name'], qty=item['item']['qty'], uom=item['item']['uom'], diff --git a/application/poe/sql/insertReceiptItemsTuple.sql b/application/poe/sql/insertReceiptItemsTuple.sql index 6aeb85f..8f06d55 100644 --- a/application/poe/sql/insertReceiptItemsTuple.sql +++ b/application/poe/sql/insertReceiptItemsTuple.sql @@ -1,4 +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) +(type, receipt_id, barcode, item_uuid, name, qty, uom, data, status) +VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING *; \ No newline at end of file diff --git a/application/poe/sql/receipts/getPLUItems.sql b/application/poe/sql/receipts/getPLUItems.sql new file mode 100644 index 0000000..96538fa --- /dev/null +++ b/application/poe/sql/receipts/getPLUItems.sql @@ -0,0 +1,4 @@ +SELECT items.item_uuid, items.item_name +FROM %%site_name%%_items items +WHERE items.item_type = 'FOOD_PLU' ORDER BY items.item_name ASC +LIMIT %s OFFSET %s; \ No newline at end of file diff --git a/application/poe/sql/scanner/selectItemByBarcode.sql b/application/poe/sql/scanner/selectItemByBarcode.sql index cf22e74..98084ef 100644 --- a/application/poe/sql/scanner/selectItemByBarcode.sql +++ b/application/poe/sql/scanner/selectItemByBarcode.sql @@ -11,17 +11,22 @@ SELECT barcodes.*, item.id as item_id, item.logistics_info_id as logistics_info_id, item.item_name as item_name, + item.item_uuid as item_uuid, primary_location.id as primary_location_id, primary_location.uuid as primary_location_uuid, auto_issue_location.id as auto_issue_location_id, auto_issue_location.uuid as auto_issue_location_uuid, item_info.cost as cost, item_info.uom_quantity as uom_quantity, + item_info.uom as uom, + food_info.expires as expires, + food_info.default_expiration as default_expiration, (SELECT COALESCE(array_agg(row_to_json(ils)), '{}') FROM cte_item_locations ils) AS item_locations FROM %%site_name%%_barcodes barcodes LEFT JOIN %%site_name%%_items item ON barcodes.item_uuid = item.item_uuid LEFT JOIN %%site_name%%_item_info as item_info ON item_info.id = item.item_info_id LEFT JOIN %%site_name%%_logistics_info logistics_info ON logistics_info.id = item.logistics_info_id +LEFT JOIN %%site_name%%_food_info food_info ON food_info.id = item.food_info_id LEFT JOIN %%site_name%%_locations primary_location ON logistics_info.primary_location = primary_location.id LEFT JOIN %%site_name%%_locations auto_issue_location ON logistics_info.auto_issue_location = auto_issue_location.id WHERE barcodes.barcode = (SELECT passed_barcode FROM passed_id); \ No newline at end of file diff --git a/application/poe/static/js/receiptsHandler.js b/application/poe/static/js/receiptsHandler.js index 67b9c34..bd5bba1 100644 --- a/application/poe/static/js/receiptsHandler.js +++ b/application/poe/static/js/receiptsHandler.js @@ -30,9 +30,6 @@ async function changeSite(site){ location.reload(true) } - - - async function getItemBarcode(barcode) { console.log(`selected item: ${barcode}`) const url = new URL('/poe/getItem/barcode', window.location.origin); @@ -74,9 +71,9 @@ async function startReceipt() { document.getElementById('barcode-input').classList.remove('uk-disabled') document.getElementById('barcode-table').classList.remove('uk-disabled') - document.getElementById('receiptStart').classList.add('uk-disabled') - document.getElementById('receiptComplete').classList.remove('uk-disabled') - document.getElementById('receiptClose').classList.remove('uk-disabled') + document.getElementById('receiptStart').setAttribute('class', 'uk-button uk-button-default uk-disabled') + document.getElementById('receiptComplete').setAttribute('class', 'uk-button uk-button-primary') + document.getElementById('receiptClose').setAttribute('class', 'uk-button uk-button-danger') } @@ -85,9 +82,9 @@ async function completeReceipt() { document.getElementById('barcode-input').classList.add('uk-disabled') document.getElementById('barcode-table').classList.add('uk-disabled') - document.getElementById('receiptStart').classList.remove('uk-disabled') - document.getElementById('receiptComplete').classList.add('uk-disabled') - document.getElementById('receiptClose').classList.add('uk-disabled') + document.getElementById('receiptStart').setAttribute('class', 'uk-button uk-button-primary') + document.getElementById('receiptComplete').setAttribute('class', 'uk-button uk-button-default uk-disabled') + document.getElementById('receiptClose').setAttribute('class', 'uk-button uk-button-default uk-disabled') await submitScanReceipt(scannedReceiptItems) let scanReceiptTableBody = document.getElementById("scanReceiptTableBody") @@ -101,9 +98,9 @@ async function closeReceipt(){ document.getElementById('barcode-input').classList.add('uk-disabled') document.getElementById('barcode-table').classList.add('uk-disabled') - document.getElementById('receiptStart').classList.remove('uk-disabled') - document.getElementById('receiptComplete').classList.add('uk-disabled') - document.getElementById('receiptClose').classList.add('uk-disabled') + document.getElementById('receiptStart').setAttribute('class', 'uk-button uk-button-primary') + document.getElementById('receiptComplete').setAttribute('class', 'uk-button uk-button-default uk-disabled') + document.getElementById('receiptClose').setAttribute('class', 'uk-button uk-button-default uk-disabled') let scanReceiptTableBody = document.getElementById("scanReceiptTableBody") scanReceiptTableBody.innerHTML = "" @@ -117,24 +114,27 @@ async function addToReceipt(event) { let barcode = document.getElementById('barcode-scan-receipt').value let data = await getItemBarcode(barcode) let scannedItem = data.item + console.log(scannedItem) if(scannedItem){ - let expires = scannedItem.food_info.expires - if(scannedItem.food_info.expires){ + let expires = scannedItem.expires + if(scannedItem.expires){ let today = new Date(); - today.setDate(today.getDate() + Number(scannedItem.food_info.default_expiration)) + today.setDate(today.getDate() + Number(scannedItem.default_expiration)) expires = today.toISOString().split('T')[0]; } scannedReceiptItems.push({item: { barcode: scannedItem.barcode, + item_uuid: scannedItem.item_uuid, item_name: scannedItem.item_name, - qty: scannedItem.item_info.uom_quantity, - uom: scannedItem.item_info.uom.id, - data: {cost: scannedItem.item_info.cost, expires: expires} + qty: scannedItem.uom_quantity, + uom: scannedItem.uom, + data: {cost: scannedItem.cost, expires: expires} }, type: 'sku'}) document.getElementById('barcode-scan-receipt').value = "" } else { scannedReceiptItems.push({item: { - barcode: `%${barcode}%`, + barcode: `%${barcode}%`, + item_uuid: null, item_name: "unknown", qty: 1, uom: 1, @@ -224,6 +224,89 @@ async function openLineEditModal(ind, line_data) { UIkit.modal(document.getElementById("lineEditModal")).show(); } +// PLU Modal Controls +async function openPLUModal() { + let items = await getPLUItems() + await generatePLUCards(items) + UIkit.modal(document.getElementById("PLUDASHModal")).show(); +} + +plu_current_page = 1 +plu_limit = 50 +async function getPLUItems() { + const url = new URL('/poe/api/paginatePLUItems', window.location.origin); + url.searchParams.append('page', plu_current_page); + url.searchParams.append('limit', plu_limit); + const response = await fetch(url); + data = await response.json(); + return data.items; +} + +async function generatePLUCards(plu_items) { + let PLUCardsBody = document.getElementById('PLUCardsBody') + PLUCardsBody.innerHTML = "" + + for (let i = 0; i < plu_items.length; i++){ + let container_div = document.createElement('div') + + let card_div = document.createElement('div') + card_div.setAttribute('class','uk-card uk-card-default uk-card-small uk-card-hover uk-text-center') + + // need to check for key, use placeholder + let image_div = document.createElement('div') + image_div.setAttribute('class', 'uk-card-media-top uk-flex uk-flex-center uk-padding-small') + + let item_image = document.createElement('img') + //item_image.src = "https://cdn-icons-png.flaticon.com/128/2756/2756716.png" + item_image.width = "60" + + image_div.append(item_image) + + let card_body_div = document.createElement('div') + card_body_div.setAttribute('class', 'uk-card-body uk-padding-small') + + let item_header = document.createElement('h5') + item_header.setAttribute('class', 'uk-card-title') + item_header.style = "margin-bottom: 4px;" + item_header.innerHTML = plu_items[i].item_name + + let id_text = document.createElement('div') + id_text.style = "font-size: 0.8em; margin-bottom: 7px;" + id_text.innerHTML = `ID: ${plu_items[i].item_uuid}` + + let add_button = document.createElement('button') + add_button.setAttribute('class', 'uk-button uk-button-primary uk-button-small') + add_button.onclick = async function(){await addPLUToReceipt(plu_items[i])} + add_button.innerHTML = "Add" + + + card_body_div.append(item_header, id_text, add_button) + + card_div.append(image_div, card_body_div) + + container_div.append(card_div) + + PLUCardsBody.append(container_div) + + + } + +} + +async function addPLUToReceipt(item) { + scannedReceiptItems.push({item: { + barcode: null, + item_uuid: item.item_uuid , + item_name: item.item_name, + qty: 1, + uom: 1, + data: {'cost': 0.00, 'expires': false} + }, type: 'PLU SKU'}) + await replenishScannedReceiptTable(scannedReceiptItems) +} + + + var mode = false async function toggleDarkMode() { let darkMode = document.getElementById("dark-mode"); diff --git a/application/poe/templates/receipts.html b/application/poe/templates/receipts.html index fa4889f..cc8bc10 100644 --- a/application/poe/templates/receipts.html +++ b/application/poe/templates/receipts.html @@ -105,7 +105,7 @@
- +
@@ -113,6 +113,9 @@
+
+ +

@@ -152,7 +155,7 @@ - QTY + Item Name @@ -185,6 +188,60 @@

+ +
+
+

Add PLU Line...

+
+ +
+
+
+ Apple +
+
+
Apple
+
PLU: 4017
+ +
+
+
+
+
+

Small

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+
+
+
+
+

Small

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+
+
+
+
+

Small

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+
+
+
+
+

Small

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+
+
+
+
+

Small

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

+
+
+
+
+ +
{% assets "js_all" %} diff --git a/application/poe/templates/scanner.html b/application/poe/templates/scanner.html index 163e05e..ab2145b 100644 --- a/application/poe/templates/scanner.html +++ b/application/poe/templates/scanner.html @@ -105,7 +105,7 @@
- +