From d261076fd4c05f63b51bcac1ed04d8a2534f7d80 Mon Sep 17 00:00:00 2001 From: Jadowyne Ulve Date: Wed, 8 Oct 2025 10:18:31 -0500 Subject: [PATCH] Moving PCS --- .../__pycache__/ItemsModel.cpython-313.pyc | Bin 7442 -> 7442 bytes .../__pycache__/items_API.cpython-313.pyc | Bin 36773 -> 37235 bytes application/items/items_API.py | 8 +- application/items/static/inventoryClasses.js | 94 + application/items/static/itemEditHandler.js | 1689 +---------------- .../items/static/itemEditHandler_old.js | 1685 ++++++++++++++++ application/items/templates/itemEdit.html | 167 ++ application/items/templates/item_new.html | 19 +- requirements.txt | 8 + 9 files changed, 1999 insertions(+), 1671 deletions(-) create mode 100644 application/items/static/inventoryClasses.js create mode 100644 application/items/static/itemEditHandler_old.js create mode 100644 application/items/templates/itemEdit.html create mode 100644 requirements.txt diff --git a/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc b/application/database_postgres/__pycache__/ItemsModel.cpython-313.pyc index 6c6d4a6d8d18d3c660726c774d576db91ed28366..c1d48095814e41011ef2bcac44e45c75ad98e927 100644 GIT binary patch delta 20 acmbPaHOY$mGcPX}0}$BOKikO7E(-uU-vvDY delta 20 acmbPaHOY$mGcPX}0}xDDeqbXvyDR`bRt1s( diff --git a/application/items/__pycache__/items_API.cpython-313.pyc b/application/items/__pycache__/items_API.cpython-313.pyc index da55cdb8dd13d56908e327c7eb804572d8c82b51..39630b6a40e24109e65e449d220c4f8cd13a9d72 100644 GIT binary patch delta 4447 zcmb7H3viQF7S8`Sf6^ut)0R+4A0*hO4fI8T0t;FxO=+PIN(crjeUPMWY?_ptR3KAG z8Nd}*men(|u(}!$tT-!BFFvNege0A)N{LIWNKN4irOjoy}Ah=%vuCHGD5Xh zg;iNDT2rlQh$^ePTr5xV%B@qZ>DZoXy#-NY%|OhwW+6_qYSBXSO0DFYf2`9b8GJjx zpw_0aX4_;H!U8eg;Z?R~jM>Pnx7z)7%fvx4nN76LSgb6N`9(c`y+W7Fq=WKIT_~oo zy1m^VS4`pOzd?0_+uQ4M>KoktKuqpI99Pu`Tz#bS_QvG3KA#h@xw$5oO0s@+gDsXy z?RJu+=0J~&;m_JS%bHkPqs!@bxV@d8SZbrCrha*SlO?9C+t%%B_qrV@tzThjs$b5^ zaT2jKH->2+7;rm-=_Fd5?m$^jpwDAc#N?!iNdsPYz#mg_!@#zFmp{fW+x-KZc#~D2 zBQ_TSE=|jUgPEFYExFcoy8`We)TV7b0+Uc}N@X=uf`K+8n_GqT@sl4YE(c-Gn(rC+F(Pj2%#`>X^=cnf$>WXR$pHiJ( z87-<5;#GlQ=3i{F3i9?MSvUG>4&SlLRYPg`* zzOOdEqc(;IPxp>4jxK0?SKTyJb3u&;r>DIU{KrC>tX6EKkxk-8@d~xtsMRI*QfrEb z8j?r+>dSOl`c}bDlYZ1#T@vZd@(DsMd@!xTP*3xs4kjmPKrp2wrvys0`BD?ADB$WM~sBWRrRF{_0|AxuT6Q;y8xc%tah7eQ=pbl^k^GqoKA;!g z%Qs3M)Y?Fpc~Ee}p_wlTOW~Qkg|JV*x0EyFEN0S3s<~QLf_Ne&zPiZ~;ZB22!Nase zhhat*TS;SRcVl+A6AK(R=%vl5>4cXJ-5FWBaLwrjqifFP)V-TkADvPUe=C?JxFhRl zd4z?D*c6r#fp~1@MR9C~J`^X+upO@5R_KtSjjYIa3judWdFM+I-|Ow(&OVoZnRPka4#!Fj zrXlQ3UiT?6DKOCQaoxQ97fa0x5)(*cE^<8C1a6{jD>F*>qcuc^%BB(Rhs*Ot_xI9{ z*UKIpV3NmD`euDQ^dV6K>y zd7LzKn~l56tt5+DVy0X60<-cp=Ak4zH_82yCh>nUf%(WIrK>H>BBd<6y0Sn5Y>z}fsgzT~K418jcn{HtDT6+*tKIEnRDm&Ne<#E9)|pg8@$Av6WA@TK zK1XN3?eqHCgQ%H&t4~5WZ^`^5!l~@1G?){9n52UQiL$lB;1aWR7?o!tktJp#{Mk~S zc=LAARLv;)zj)ZHiVcaxDcB?9Jd&e7*f2wrh8IsY>-0MP?B{6odw9L-3*_Xe{e?naNH z<^94B9wQsRVn;}#oU=TFqX@O^7>UObl7g@&NqGWH7K8K)6hA}152L?NE$;~m?k@~y zS5&COWcCEXDY&*`SzeMGA8Jk4xst^&Y^XD7!X%y~I7Ki5P-j*>hvF6d`rm@Hwk+tj zq~jb;W4v&E*(59T;i|H^e32*HWsC=&q)cvam^Wd05@j-RdCH~dk;-@QTEo}KV6?GC zh~Hvi)G{07HkVc0ur9$V$-8>OS=~W{+9B9nqrN-v=}1E2S~XvcSIP5hpt0o%$Dzz-j^A{{&}AzUj=+y?Ch2vw zm;=AD{R~~)wJt1V@LC|sF*!Za*sG9gpM|66*cS_J;IbD9!?52zQ;5JbcC+ejG+atl z4st5j>_0?5yVpM=WN|;lJf;}%_0b`563nfo=&7T1zNQU3*f4>T;7vHzIxjmyBENd2 zcy*s6#Ywo>I!}5J#g$;Z`$@d+e|Pu4Fu$*EyaS!3v{hc8R8?Dva2`BuMXDGYZzNV5 zIIGibtB}>Tw%I~1XLX+3@*1ako)B4>E1OWC`8MlP9jy%=pBogt% zocK46eHi0D=a8V|F+QViJ|@|_zRQT-S9F<6Zpi9XGXDf2hL=vC?_L-C3u!3B>{B@2 zrB{7{VkkKtZqu&q7_+atRnYR72gsU-+dGL>3-oPBFJ)n%zea8wx=4RgGIx1%C(`BdS82wrI2IqU z{12<>ce6aG*lm$asQm_lyZ??ySI?d*4KF<%Dp@Xp0e-dTap6t4c;9W2;C<;ri0_~# zni~D>V)UI(1otme};G zQP+hu$Rv$4BI0&sO=!Ld6AO&lTAN$yXmUvVGuqu9c9w};qskY?XFVR9)hBu!Hn)pq zA%m?Tt_Ei7VqjwKynIq+RIyxQaFM0&8H&=qWid`c$b)P1 zvl8-gjuC^AF}4Q57!v3QXkr(Kufu5*{#_$v)Y}z%Ob~L1bg4ovr0I;|g~%dBt~SoT zsJo(!D8eyQ66At)(b9!HzA_y9)Xvscm*g&EX*j~j3*ntbzmDPj5|Sq&mO)Ss`{Ogk zIwT9dm*NMMLJ{QYm#2|8tdd|8LM?lR$ju1GFgc1Un%GLP1qSp>)OD+tn(h^cb8!G#IF@*0xka<{`7^mho zx4`N|9eg%-E-x%hBv(;@mgmFkiQ!@k>S=_5#5VY`AzP^TCNHxKxqe$@hLJ(p7JCiJ z$?%$x3<_@x+)S#7;QD#43ShAzDZCZM_Tb;u52q82u+Jc&l`jmTAyM24&u=O6Ss8q5 ztX1<=mqS%bPDBOG%1MQjI1bF=t&~;kYlvTqV2ofZiQYlr-!LZ)cN38P$^9d$lVB$l zrKX5(BoBByQ#T9f)i2WyDi6=}ie%dfxH>8jp8M{}17_}!^hGrrm;)JQPvhu7xb&@( z+tMys^)8RaBDq>Uc6(O>+lvx`l`+dFx;>qCDY!sFs6r+(O)LG;g|Y2q^<~lVJeL!9 zGN!~VgV=@RL2p&oJc`M(V)1{8Nv@)OxB#0&XeX0eZ3iS53&=dOWT&4->1{5(!|B$W z?RMvW$(n#^=O;8^U&s?Wl}tkriQtQ9lZJ9;8~ov@UmA`a3G6MJ2NgMU#6!4r1e$Z6 zVF-;Y9m<%OZVTMaO)*R#JNeY{vV74q$jVDg^*fc`r|C2^H;w$2C#O|zCcZGc(_(hpoDLUzgY-}P8(0i4 zI!vN7QW@7dw022A5TWb@N%0_#5p|rv??yRPt~H7MIQfCMZ>@=f_}RKR<%=1-O_{WAg;WUJo z45Fvj0@-5mnhiyW_8t;N8g-FQNzk0;qb59-P`zEy#ByceWJnZOzD4{EB(AdbT)*!%!Hh9zY{$+YZydU#`)m@oY@*3f{U`XxTUc z-zMUhu}d^Q3lD1w<@;*Iq&sCEMMCfp69*&iYgiY|%cA z%hTfS>Xh&Tq*->A;2M0nBVITQ&vuxml;`YB7KY%}oksC}lt_mDo##+xQr)N!%~g`W zJ{3Kn*j2b)zZ6$Lsm~XxAbVG`Fboa5mI&`c&n}aA9R>5?r@KaQ`L>4h!d$+b{Pw9m z&JOAqBSVepxIUvXC#nkP*)RcboD;wrvt!?-aX5lelaVFJcPnqLRr~ z4N)yA3*>_SEzTQ*Yk6A>DLve>TKou^7Wh?5H!3Z#ye{bd0fxyJ3B^dNSr5U7aL2lg zl5NeJ^3Wu0i}-|iyyf=5pcF6u0mlv)mo8}eYe<`EmF$vRf)#a(yiJxmA7L#z1G zKm+&N3}_&x-BdjzpOGZ~DS}VUqz>mkiG5Bplv{QiVaBs|mTYq?zYf`-P@o4r!Uog+ zItIJi)*!@iFM4S`cfd*1hj3{(ZRj6&=TAkrV9%~7F2y6Hhca`*8+($)yGWjZu{|eI z;TpShvb*%cct;*;xYuENu_V$Qd2{?Fp^{7DE7<2)E&dI)y#?1Cbiy_`tCey5wv>-C z+4LX#b{N~6r1=p})^?}B19v<;-WwD2vWjIXmHyVQ3An6#gH`d6=HTnFW3-QG->EopI%g+9Gh0X$j`Q(c>e+1WcSr^p>B{3Wxcz;U7$e6kr_zeKfHa0{XsSZUTDu zGI}_&BLw{frwHhY!00|_bmKC*^w=1Im*9PZ>jczP88u5r&5cnj!qbnBJa(5zI%RTc z-zSQ8pV1aDN)Mx`_?Hr+#wC9rhpy>xT0M4Y9ZLaS|M>h6p;-ASM4? { + if(Object.prototype.hasOwnProperty.call(this, key)){ + this[key] = data[key] + } + }) + } +} + + +class FoodInfo { + constructor(data){ + this.item_default_expiration = data.item_default_expiration; + this.item_expires = data.item_expires; + this.item_food_groups = data.item_food_groups; + this.item_ingredients = data.item_ingredients; + this.item_nutrients = data.item_nutrients; + this.item_uuid = data.item_uuid; + } + + update(data) { + Object.keys(data).forEach((key) => { + if(Object.prototype.hasOwnProperty.call(this, key)){ + this[key] = data[key] + } + }) + } +} + +class ItemInfo { + constructor(data){ + this.item_uuid = data.item_uuid; + this.item_uom = data.item_uom; + this.item_packaging = data.item_packaging; + this.item_uom_quantity = data.item_uom_quantity; + this.item_cost = data.item_cost; + this.item_safety_stock = data.item_safety_stock; + this.item_lead_time_days = data.item_lead_time_days; + this.item_ai_pick = data.item_ai_pick; + this.item_prefixes = data.item_prefixes; + this.conversions = data.conversions; + this.prefixes = data.prefixes; + } + + update(data) { + Object.keys(data).forEach((key) => { + if(Object.prototype.hasOwnProperty.call(this, key)){ + this[key] = data[key] + } + }) + } +} + + +class InventoryItem { + constructor(data){ + this.item_uuid = data.item_uuid; // string + this.item_created_at = data.item_created_at; // date + this.item_updated_at = data.item_updated_at; // date + this.item_name = data.item_name; // string + this.item_description = data.item_description; // string + this.item_tags = data.item_tags; // array + this.item_links = data.item_links; // dict + this.item_brand_uuid = data.item_brand_uuid; // uuid + this.item_category = data.item_category; // string + this.item_search_string = data.item_search_string; // string + this.item_inactive = data.item_inactive; // bool + this.item_locations = data.item_locations; // array + this.item_barcodes = data.item_barcodes; // array + } + + update(data) { + Object.keys(data).forEach((key) => { + if(Object.prototype.hasOwnProperty.call(this, key)){ + this[key] = data[key] + } + }) + } + + toString() { + return JSON.stringify(this, null, 2); + } +} + +export { InventoryItem, ItemInfo, FoodInfo, LogisticsInfo }; \ No newline at end of file diff --git a/application/items/static/itemEditHandler.js b/application/items/static/itemEditHandler.js index 270119e..a298d5d 100644 --- a/application/items/static/itemEditHandler.js +++ b/application/items/static/itemEditHandler.js @@ -1,1680 +1,43 @@ +import { FoodInfo, InventoryItem, ItemInfo, LogisticsInfo } from './inventoryClasses.js'; + var item; -var linked_items; -var tags = new Set(); -var weblinks; -var shopping_lists; -var food_groups = new Set(); -var ingrediants = new Set(); -var primary_zone; -var primary_zone_id; -var primary_location; -var auto_zone; -var auto_zone_id; -var auto_location; -var brand; -var locations; +var item_info; +var food_info; +var logistics_info; -var current_page = 1; -var limit = 2; -var end_page = 1; -var search_string = ''; - -var updated = {}; - -// form defaults, make this editable. -var item_types = [['Single', 'single'], ['Linked List', 'list'], ['Linked Item', 'link']]; -var item_subtypes = [['Food', 'FOOD'], ['Food PLU', 'FOOD_PLU'], ['Other', 'OTHER'], ['Medicinal', 'MEDICINE'], ['Hygenic', 'HYGENIC']]; document.addEventListener('DOMContentLoaded', async function() { - await setupFormDefaults() - await refreshForm() + //await setupFormDefaults() + //await refreshForm() + //await fetchItem() + console.log(passed_item) + item = new InventoryItem(passed_item); + item_info = new ItemInfo(passed_item.item_info) + food_info = new FoodInfo(passed_item.food_info) + logistics_info = new LogisticsInfo(passed_item.logistics_info) + console.log(item['item_category']) + console.log(document.getElementById("item_subtype_input").value) + }) -async function refreshForm(){ - await fetchItem() - document.getElementById('title').innerHTML = item.item_name; - await setBasicInfo() - await updateWebLinksTable() - await updateReferenceTable() - await updateLocationsTable() - await updateLinkedItemsTable() - await updateConversionsTableBody() - await updatePrefixTableBody() - await updateTags() - await updateBarcodes() -} - -async function setupFormDefaults() { - let itemTypeSelect = document.getElementById('itemTypeSelect') - for(let i=0; i${weblinks[key]}` - let buttonCell = document.createElement('td') - buttonCell.classList.add('uk-width-1-4') - - let deleteButton = document.createElement('button') - deleteButton.setAttribute('class', 'uk-flex uk-flex-middle uk-flex-center uk-button uk-button-small uk-align-right delete_button') - deleteButton.onclick = function (){ - deleteLink(key) - } - deleteButton.innerHTML = `` - - buttonCell.append(deleteButton) - - tableRow.append(nameCell) - tableRow.append(linkCell) - tableRow.append(buttonCell) - weblinksTableBody.append(tableRow) - } -} - -async function updateTags() { - let chipZoneTags = document.getElementById('tagsRow') - chipZoneTags.innerHTML = ""; - tags.forEach(tagText => { - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `tag_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeTag(tagText, tag.id) - } - chipZoneTags.append(tag) - }); - let foodGroupsTags = document.getElementById('foodGroupsTagsRow') - foodGroupsTags.innerHTML = ""; - food_groups.forEach(tagText => { - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `tag_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeFoodGroup(tagText, tag.id) - } - foodGroupsTags.append(tag) - }); - let ingrediantsRow = document.getElementById('ingrediantsRow') - ingrediantsRow.innerHTML = ""; - ingrediants.forEach(tagText => { - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `ingr_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeIngrediant(tagText, tag.id) - } - ingrediantsRow.append(tag) - }); -} - -async function updateLocationsTable() { - let locationsTableBody = document.getElementById('locationsTableBody') - locationsTableBody.innerHTML = ""; - for(let i=0; i < locations.length; i++){ - console.log(locations[i]) - let tableRow = document.createElement('tr') - - let locationCell = document.createElement('td') - locationCell.innerHTML = `${locations[i].uuid}` - let QOHCell = document.createElement('td') - QOHCell.innerHTML = `${locations[i].quantity_on_hand}` - - tableRow.append(locationCell) - tableRow.append(QOHCell) - locationsTableBody.append(tableRow) - } -} - -async function setBasicInfo() { - document.getElementById('itemName').value = item.item_name - document.getElementById('itemBarcode').innerHTML = item.barcode - document.getElementById('itemBrand').value = brand; - document.getElementById('itemDescription').value = item.description - document.getElementById('itemTypeSelect').value = item.row_type - if(item.row_type === "list"){ - document.getElementById("linkedListLink").classList.remove("uk-disabled") - } else if (item.row_type === "link"){ - document.getElementById('itemTypeSelect').classList.add("uk-disabled") - } else { - document.getElementById("linkedListLink").classList.add("uk-disabled") - document.getElementById('itemTypeSelect').classList.remove("uk-disabled") - } - document.getElementById('itemSubTypeSelect').value = item.item_type - document.getElementById('aiPickableCheckbox').checked = item.item_info.ai_pick - document.getElementById('expiresCheckbox').checked = item.food_info.expires - document.getElementById('expirePeriod').value = item.food_info.default_expiration - document.getElementById('safetyStock').value = item.item_info.safety_stock - document.getElementById('leadTimeInDays').value = item.item_info.lead_time_days - document.getElementById('skuCost').value = item.item_info.cost.toLocaleString('en-US', {style: 'currency', currency: 'USD'}) - document.getElementById('uom_quantity').value = item.item_info.uom_quantity - document.getElementById('uom').value = item.item_info.uom.id - document.getElementById('packaging').value = item.item_info.packaging - document.getElementById('primaryZone').value = primary_zone - document.getElementById('primaryLocation').value = primary_location - document.getElementById('autoZone').value = auto_zone - document.getElementById('autoLocation').value = auto_location - - document.getElementById('main_qty_uom').value = `${item.item_info.uom_quantity} ${item.item_info.uom}` - document.getElementById('main_barcode').value = item.barcode - document.getElementById('search_string_main').value = item.search_string - - console.log(item) - let referenceCount = 0 - referenceCount += item.item_shopping_lists.length - referenceCount += item.item_recipes.length - - if (referenceCount> 0){ - document.getElementById('inactiveButton').classList.add('uk-disabled') - } - - -} - -function addTag(event){ - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - let tagInput = document.getElementById('tagInput'); - tagText = tagInput.value; - if((event.code=="Enter" || event.type=="click") && !tags.has(tagText)){ - console.log(tagText) - tags.add(tagText) - updated['item']['tags'] = Array.from(tags) - let chipZoneTags = document.getElementById('tagsRow') - - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `tag_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeTag(tagText, tag.id) - } - chipZoneTags.append(tag) - tagInput.classList.remove('uk-form-danger') - } else if((event.code=="Enter" || event.type=="click") && tags.has(tagText)){ - tagInput.classList.add('uk-form-danger') - UIkit.notification({ - message: 'Duplicate Tags are not Allowed!', - status: 'danger', - pos: 'top-right', - timeout: 2000 - }); - - } else { - tagInput.classList.remove('uk-form-danger') - } -} - -function addFoodGroup(event){ - if (!updated.hasOwnProperty('food_info')){ - updated['food_info'] = {} - } - let foodGroupsInput = document.getElementById('foodGroupsInput'); - tagText = foodGroupsInput.value; - if((event.code=="Enter" || event.type=="click") && !food_groups.has(tagText)){ - food_groups.add(tagText) - updated['food_info']['food_groups'] = Array.from(food_groups) - let chipZoneTags = document.getElementById('foodGroupsTagsRow') - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `food_group_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeFoodGroup(tagText, tag.id) - } - chipZoneTags.append(tag) - foodGroupsInput.classList.remove('uk-form-danger') - } else if((event.code=="Enter" || event.type=="click") && food_groups.has(tagText)){ - foodGroupsInput.classList.add('uk-form-danger') - UIkit.notification({ - message: 'Duplicate Food Groups are not Allowed!', - status: 'danger', - pos: 'top-right', - timeout: 2000 - }); - - } else { - foodGroupsInput.classList.remove('uk-form-danger') - } -} - -function addIngrediant(event){ - if (!updated.hasOwnProperty('food_info')){ - updated['food_info'] = {} - } - let ingrediantsInput = document.getElementById('ingrediantsInput'); - tagText = ingrediantsInput.value; - if((event.code=="Enter" || event.type=="click") && !ingrediants.has(tagText)){ - ingrediants.add(tagText) - updated['food_info']['ingrediants'] = Array.from(ingrediants) - let chipZoneTags = document.getElementById('ingrediantsRow') - - let tag = document.createElement('div') - tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") - tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") - tag.setAttribute("id", `ingr_${tagText}`) - tag.innerHTML = tagText - tag.ondblclick = function(){ - removeIngrediant(tagText, tag.id) - } - chipZoneTags.append(tag) - ingrediantsInput.classList.remove('uk-form-danger') - } else if((event.code=="Enter" || event.type=="click") && ingrediants.has(tagText)){ - ingrediantsInput.classList.add('uk-form-danger') - UIkit.notification({ - message: 'Duplicate ingrediants are not Allowed!', - status: 'danger', - pos: 'top-right', - timeout: 2000 - }); - - } else { - ingrediantsInput.classList.remove('uk-form-danger') - } -} - -function removeTag(tagText, elementID) { - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - let childElement = document.getElementById(elementID) - let tempTags = Array.from(tags); - tempTags = tempTags.filter(item => item !== tagText); - updated['item']['tags'] = tempTags; - tags = new Set(tempTags); - childElement.parentNode.removeChild(childElement) -} - -function removeFoodGroup(tagText, elementID) { - if (!updated.hasOwnProperty('food_info')){ - updated['food_info'] = {} - } - let childElement = document.getElementById(elementID) - let tempTags = Array.from(food_groups); - tempTags = tempTags.filter(item => item !== tagText); - updated['food_info']['food_groups'] = tempTags; - food_groups = new Set(tempTags); - childElement.parentNode.removeChild(childElement) -} - -function removeIngrediant(tagText, elementID) { - if (!updated.hasOwnProperty('food_info')){ - updated['food_info'] = {} - } - console.log(tagText) - console.log(elementID) - let childElement = document.getElementById(elementID) - let tempTags = Array.from(ingrediants); - tempTags = tempTags.filter(item => item !== tagText); - updated['food_info']['ingrediants'] = tempTags - ingrediants = new Set(tempTags); - childElement.parentNode.removeChild(childElement) -} - -function deleteLink(linkKey){ - console.log(linkKey) -} - -async function updateLocationsSelectTable(logis) { - let fetchedLocations; - let selectlocationsTableBody = document.getElementById('selectlocationsTableBody') - selectlocationsTableBody.innerHTML = "" - - if (logis=='primary_location'){ - data = await fetchLocations('primary_location'); - fetchedLocations = data.locations; - end_page = data.endpage; - } else if (logis=='auto_issue_location'){ - data = await fetchLocations('auto_issue_location'); - fetchedLocations = data.locations; - end_page = data.endpage; - } - - console.log(fetchedLocations) - for(let i = 0; i < fetchedLocations.length; i++){ - - let tableRow = document.createElement('tr') - tableRow.classList.add("selectableRow") - - let nameCell = document.createElement('td') - nameCell.innerHTML = `${fetchedLocations[i].name}` - - tableRow.id = fetchedLocations[i].id - - tableRow.append(nameCell) - tableRow.onclick = function(){ - closeZoneLocationBrandModal(fetchedLocations[i].name, fetchedLocations[i].id, logis) - } - selectlocationsTableBody.append(tableRow) - } -} - -async function openLocationsModal(logis, elementID){ - let LocationsModal = document.getElementById("LocationsModal") - current_page = 1; - search_string = ''; - await updateLocationsSelectTable(logis) - await updatePaginationElement(logis, elementID) - UIkit.modal(LocationsModal).show(); -} - -async function updateZonesTable(logis) { - let zonesTableBody = document.getElementById('zonesTableBody') - zonesTableBody.innerHTML = "" - data = await fetchZones() - zones = data.zones - end_page = data.endpage - for(let i = 0; i < zones.length; i++){ - let tableRow = document.createElement('tr') - - let nameCell = document.createElement('td') - nameCell.innerHTML = `${zones[i].name}` - - tableRow.id = zones[i].id - - tableRow.append(nameCell) - tableRow.onclick = function(){ - closeZoneLocationBrandModal(zones[i].name, zones[i].id, logis) - } - zonesTableBody.append(tableRow) - } -} - -async function updateLinkedItemsTable() { - let linkedItemsTableBody = document.getElementById('linkedItemsTableBody') - linkedItemsTableBody.innerHTML = "" - - let linked_items = item.linked_items - for(let i = 0; i < linked_items.length; i++){ - - let tableRow = document.createElement('tr') - - let barcodeCell = document.createElement('td') - barcodeCell.innerHTML = linked_items[i].barcode - let nameCell = document.createElement('td') - nameCell.innerHTML = linked_items[i].data.item_name - let opCell = document.createElement('td') - - let editOp = document.createElement('a') - editOp.setAttribute('class', 'uk-button uk-button-default') - editOp.setAttribute('uk-icon', 'icon: pencil') - editOp.setAttribute('href', `/items/${item['id']}/itemLink/${linked_items[i].id}`) - - opCell.append(editOp) - - tableRow.append(barcodeCell, nameCell, opCell) - linkedItemsTableBody.append(tableRow) - } -} - - -async function openZonesModal(logis, elementID){ - let zonesModal = document.getElementById("zonesModal") - current_page = 1; - search_string = ''; - await updateZonesTable(logis) - await updatePaginationElement(logis, elementID) - UIkit.modal(zonesModal).show(); -} - -function closeZoneLocationBrandModal(selectName, selectID, key){ - if (!updated.hasOwnProperty('logistics_info')){ - updated['logistics_info'] = {} - } - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - - if(key=='primary_zone'){ - primary_zone = selectName; - primary_zone_id = selectID; - document.getElementById('primaryZone').value = selectName; - updated['logistics_info']['primary_zone'] = selectID - document.getElementById('primaryLocation').classList.add('uk-form-danger') - document.getElementById('primaryLocation').value = ""; - UIkit.modal(document.getElementById('zonesModal')).hide(); - } - if(key=='auto_issue_zone'){ - auto_zone = selectName; - auto_zone_id = selectID; - document.getElementById('autoZone').value = selectName; - updated['logistics_info']['auto_issue_zone'] = selectID; - document.getElementById('autoLocation').classList.add('uk-form-danger') - document.getElementById('autoLocation').value = ""; - UIkit.modal(document.getElementById('zonesModal')).hide(); - } - if(key=='primary_location'){ - primary_location = selectName; - document.getElementById('primaryLocation').value = selectName; - updated['logistics_info']['primary_location'] = selectID; - document.getElementById('primaryLocation').classList.remove('uk-form-danger') - UIkit.modal(document.getElementById('LocationsModal')).hide(); - } - if(key=='auto_issue_location'){ - auto_location = selectName; - document.getElementById('autoLocation').value = selectName; - updated['logistics_info']['auto_issue_location'] = selectID; - document.getElementById('autoLocation').classList.remove('uk-form-danger') - UIkit.modal(document.getElementById('LocationsModal')).hide(); - } - if(key=='brand'){ - brand = selectName; - document.getElementById('itemBrand').value = selectName; - updated['item']['brand'] = selectID; - UIkit.modal(document.getElementById('brandsModal')).hide(); - } - if(key=='items'){ - barcode = selectName[0]; - document.getElementById('linked_item').value = barcode; - document.getElementById('conversion_factor_uom').value = selectName[1]; - document.getElementById('linked_item_id').value = selectID; - document.getElementById('linkAdd').onclick = async function () { - await addLinkedItem(item_id, selectID) - } - UIkit.modal(document.getElementById('itemsModal')).hide(); - } -} - -async function updateBrandsModalTable(logis) { - let brandsTableBody = document.getElementById('brandsTableBody'); - brandsTableBody.innerHTML = ""; - data = await fetchBrands(); - end_page = data.endpage; - let fetchedBrands = data.brands; - - for(let i=0; i < fetchedBrands.length; i++){ - let tableRow = document.createElement('tr') - - let nameCell = document.createElement('td') - nameCell.innerHTML = `${fetchedBrands[i].name}` - - tableRow.id = fetchedBrands[i].id - tableRow.onclick = function(){ - closeZoneLocationBrandModal(fetchedBrands[i].name, fetchedBrands[i].id, logis) - } - tableRow.append(nameCell) - brandsTableBody.append(tableRow) - } -} - -async function updateItemsModalTable(logis) { - let itemsTableBody = document.getElementById('itemsTableBody'); - itemsTableBody.innerHTML = ""; - data = await fetchItems(); - end_page = data.end; - let fetchedItems = data.items; - - - for(let i=0; i < fetchedItems.length; i++){ - let tableRow = document.createElement('tr') - - let idCell = document.createElement('td') - idCell.innerHTML = `${fetchedItems[i].id}` - - let barcodeCell = document.createElement('td') - barcodeCell.innerHTML = `${fetchedItems[i].barcode}` - - let nameCell = document.createElement('td') - nameCell.innerHTML = `${fetchedItems[i].item_name}` - - tableRow.id = fetchedItems[i].id - tableRow.onclick = async function(){ - closeZoneLocationBrandModal([fetchedItems[i].barcode, fetchedItems[i].uom], fetchedItems[i].id, logis) - } - tableRow.append(idCell, barcodeCell, nameCell) - itemsTableBody.append(tableRow) - console.log(tableRow.onclick) - } -} - -async function openBrandsModal(logis, elementID) { - let brandsModal = document.getElementById('brandsModal') - current_page = 1; - search_string = ''; - await updateBrandsModalTable(logis) - await updatePaginationElement(logis, elementID) - UIkit.modal(brandsModal).show(); - -} - -async function openItemsModal(logis, elementID) { - let itemsModal = document.getElementById('itemsModal') - current_page = 1; - search_string = ''; - document.getElementById('searchItemsInput').value = ''; - await updateItemsModalTable(logis) - await updatePaginationElement(logis, elementID) - UIkit.modal(itemsModal).show(); -} - -async function openAddConversionsModal() { - let conversionsModal = document.getElementById('conversionsModal') - document.getElementById('parent_uom').value = `${item.item_info.uom.fullname}` - document.getElementById('conversionSubmitButton').innerHTML = "Add" - document.getElementById('conversionSubmitButton').onclick = async function() { - await postConversion() - } - UIkit.modal(conversionsModal).show() -} - -async function openEditConversionsModal(conversion) { - let conversionsModal = document.getElementById('conversionsModal') - document.getElementById('parent_uom').value = `${item.item_info.uom.fullname}` - document.getElementById('conversion_factor_modal').value = `${conversion.conv_factor}` - document.getElementById('conversion_uom').value = `${conversion.id}` - document.getElementById('conversionSubmitButton').innerHTML = "Save" - document.getElementById('conversionSubmitButton').onclick = async function() { - let update = {'conv_factor': document.getElementById('conversion_factor_modal').value} - await postConversionUpdate(conversion.conv_id, update) - } - UIkit.modal(conversionsModal).show() -} - -async function postConversion() { - const response = await fetch(`/items/addConversion`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - parent_id: parseInt(item.id), - uom_id: parseInt(document.getElementById('conversion_uom').value), - conv_factor: parseFloat(document.getElementById('conversion_factor_modal').value) - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - await fetchItem() - await setBasicInfo() - await updateConversionsTableBody() - - UIkit.modal(conversionsModal).hide() -} - -async function postConversionUpdate(id, update) { - const response = await fetch(`/items/updateConversion`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - conversion_id: id, - update: update - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - await fetchItem() - await setBasicInfo() - await updateConversionsTableBody() - - UIkit.modal(conversionsModal).hide() -} - -async function deleteConversion(conversion_id) { - const response = await fetch(`/items/deleteConversion`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - conversion_id: conversion_id - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - - await fetchItem() - await setBasicInfo() - await updateConversionsTableBody() - - UIkit.modal(conversionsModal).hide() - -} - -async function openAddPrefixesModal() { - let prefixesModal = document.getElementById('prefixesModal') - current_page = 1; - let data = await fetchPrefixes() - let prefixes = data.prefixes - end_page = data.end; - await updatePrefixModalTableBody(prefixes) - await updatePrefixPaginationElement() - UIkit.modal(prefixesModal).show() -} - -async function postPrefix(id) { - const response = await fetch(`/items/addPrefix`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - parent_id: parseInt(item.item_info_id), - prefix_id: parseInt(id) - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - await fetchItem() - await setBasicInfo() - await updatePrefixTableBody() - UIkit.modal(document.getElementById('prefixesModal')).hide() -} - -async function deletePrefix(prefix_id) { - const response = await fetch(`/items/deletePrefix`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_info_id: item.item_info_id, - prefix_id: prefix_id - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - - await fetchItem() - await setBasicInfo() - await updatePrefixTableBody() - - UIkit.modal(document.getElementById('prefixesModal')).hide() - -} - -let prefix_limit = 2; -async function fetchPrefixes() { - const url = new URL('/items/getPrefixes', window.location.origin); - url.searchParams.append('page', current_page); - url.searchParams.append('limit', prefix_limit); - const response = await fetch(url); - data = await response.json(); - return data; -} - -let brands_limit = 25; -async function fetchBrands() { - const url = new URL('/items/getBrands', window.location.origin); - url.searchParams.append('page', current_page); - url.searchParams.append('limit', brands_limit); - const response = await fetch(url); - data = await response.json(); - return data; -} - -let items_limit = 25; -async function fetchItems() { - const url = new URL('/items/getModalItems', window.location.origin); - url.searchParams.append('page', current_page); - url.searchParams.append('limit', items_limit); - url.searchParams.append('search_string', search_string); - const response = await fetch(url); - data = await response.json(); - return data; -} - -let zones_limit = 20; -async function fetchZones(){ - const url = new URL('/items/getZonesBySku', window.location.origin); - url.searchParams.append('page', current_page); - url.searchParams.append('limit', zones_limit); - url.searchParams.append('item_id', item.id); - const response = await fetch(url); - data = await response.json(); - return data; -} - -let locations_limit = 10; -async function fetchLocations(logis) { - const url = new URL('/items/getLocationsBySkuZone', window.location.origin); - url.searchParams.append('page', current_page); - url.searchParams.append('limit', locations_limit); - url.searchParams.append('part_id', item.id); - if(logis=="primary_location"){ - url.searchParams.append('zone_id', primary_zone_id); - } else if (logis=="auto_issue_location"){ - url.searchParams.append('zone_id', auto_zone_id); - } - const response = await fetch(url); - data = await response.json(); - return data; -} - +// fetch functions async function fetchItem() { const url = new URL('/items/api/getItem', window.location.origin); url.searchParams.append('item_uuid', item_uuid); const response = await fetch(url); - data = await response.json(); - item = data.item; - tags = new Set(item.tags); - weblinks = item.links; - shopping_lists = item.item_shopping_lists; - food_groups = new Set(item.food_info.food_groups); - ingrediants = new Set(item.food_info.ingrediants); - - primary_zone = item.logistics_info.primary_zone.name - primary_zone_id = item.logistics_info.primary_zone.id - primary_location = item.logistics_info.primary_location.name - - auto_zone = item.logistics_info.auto_issue_zone.name - auto_zone_id = item.logistics_info.auto_issue_zone.id - auto_location = item.logistics_info.auto_issue_location.name - locations = item.item_locations - - brand = item.brand.name - return item; -}; - -async function searchTable(event, logis, elementID) { - if(event.key==='Enter' && logis==='items'){ - search_string = event.srcElement.value - await updateItemsModalTable(logis) - } - await updatePaginationElement(logis, elementID) -} - -async function setPage(pageNumber, logis, elementID){ - current_page = pageNumber; - - if(elementID=="zonesPage"){ - await updateZonesTable(logis) - } else if(elementID=="locationsPage"){ - await updateLocationsSelectTable(logis) - }else if (elementID=="brandsPage"){ - await updateBrandsModalTable(logis) - } else if (elementID=="itemsPage"){ - await updateItemsModalTable(logis) - } - await updatePaginationElement(logis, elementID) - console.log(current_page) -} - -async function updatePaginationElement(logis, elementID) { - let paginationElement = document.getElementById(elementID); - paginationElement.innerHTML = ""; - // previous - let previousElement = document.createElement('li') - if(current_page<=1){ - previousElement.innerHTML = ``; - previousElement.classList.add('uk-disabled'); - }else { - previousElement.innerHTML = ``; - } - paginationElement.append(previousElement) - - //first - let firstElement = document.createElement('li') - if(current_page<=1){ - firstElement.innerHTML = `1`; - firstElement.classList.add('uk-disabled'); - }else { - firstElement.innerHTML = `1`; - } - paginationElement.append(firstElement) - - // ... - if(current_page-2>1){ - let firstDotElement = document.createElement('li') - firstDotElement.classList.add('uk-disabled') - firstDotElement.innerHTML = ``; - paginationElement.append(firstDotElement) - } - // last - if(current_page-2>0){ - let lastElement = document.createElement('li') - lastElement.innerHTML = `${current_page-1}` - paginationElement.append(lastElement) - } - // current - if(current_page!=1 && current_page != end_page){ - let currentElement = document.createElement('li') - currentElement.innerHTML = `
  • ${current_page}
  • ` - paginationElement.append(currentElement) - } - // next - if(current_page+2${current_page+1}` - paginationElement.append(nextElement) - } - // ... - if(current_page+2<=end_page){ - let secondDotElement = document.createElement('li') - secondDotElement.classList.add('uk-disabled') - secondDotElement.innerHTML = ``; - paginationElement.append(secondDotElement) - } - //end - let endElement = document.createElement('li') - if(current_page>=end_page){ - endElement.innerHTML = `${end_page}`; - endElement.classList.add('uk-disabled'); - }else { - endElement.innerHTML = `${end_page}`; - } - paginationElement.append(endElement) - //next button - let nextElement = document.createElement('li') - if(current_page>=end_page){ - nextElement.innerHTML = ``; - nextElement.classList.add('uk-disabled'); - }else { - nextElement.innerHTML = ``; - console.log(nextElement.innerHTML) - } - paginationElement.append(nextElement) -} - -async function addLinkedItem(parent_id, child_id) { - let conversion_factor = parseFloat(document.getElementById('conversion_factor').value) - - if(Number.isInteger(conversion_factor)){ - document.getElementById('conversion_factor').classList.remove('uk-form-danger') - const response = await fetch(`/items/addLinkedItem`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - parent_id: parseInt(parent_id), - child_id: parseInt(child_id), - conv_factor: conversion_factor - }), - }); - data = await response.json(); - response_status = 'primary' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - - document.getElementById('linked_item').value = "" - document.getElementById('conversion_factor').value = "" - document.getElementById('linked_item_id').value = "" - document.getElementById('linkAdd').onclick = null - - await fetchItem() - await setBasicInfo() - await updateLinkedItemsTable() - - } else { - document.getElementById('conversion_factor').classList.add('uk-form-danger') - } -} - -async function saveUpdated() { - const response = await fetch(`/items/updateItem`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - id: parseInt(item_id), - data: updated - }), - }); - - data = await response.json(); - response_status = 'success' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - - updated = {} - await fetchItem() - await setBasicInfo() -}; - -async function inactivateItem() { - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - - updated['item']['inactive'] = !item.inactive - - const response = await fetch(`/items/api/inactivateItem`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_id: parseInt(item_id), - data: updated - }), - }); - location.href = "/items" -} - -async function refreshSearchString() { - const response = await fetch(`/items/refreshSearchString`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_id: parseInt(item.id) - }), - }); - - data = await response.json(); - response_status = 'success' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - - await fetchItem() - await setBasicInfo() -}; - - -async function descriptionChanged() { - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - - updated['item']['description'] = document.getElementById('itemDescription').value -} - -async function nameChanged() { - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - - updated['item']['item_name'] = document.getElementById('itemName').value -} - -async function selectChanged(logis) { - if (!updated.hasOwnProperty('item')){ - updated['item'] = {} - } - if(logis=='row_type'){ - updated['item'][logis] = document.getElementById('itemTypeSelect').value - } - if(logis == 'item_type'){ - updated['item'][logis] = document.getElementById('itemSubTypeSelect').value - } -} - -async function itemInfoChanged(logis) { - if (!updated.hasOwnProperty('item_info')){ - updated['item_info'] = {} - } - if (logis == 'safety_stock'){ - let value = document.getElementById('safetyStock').value - updated['item_info']['safety_stock'] = parseFloat(value) - } - if (logis == 'lead_time_days'){ - let value = document.getElementById('leadTimeInDays').value - updated['item_info']['lead_time_days'] = parseFloat(value) - } - if (logis == 'cost'){ - let value = document.getElementById('skuCost').value - value = parseFloat(value.replace(/[^0-9.-]+/g,"")); - updated['item_info']['cost'] = value - } - if (logis == 'uom_quantity'){ - let value = document.getElementById('uom_quantity').value - updated['item_info']['uom_quantity'] = value - } - if (logis == 'uom'){ - let value = document.getElementById('uom').value - updated['item_info']['uom'] = value - } - if (logis == 'packaging'){ - let value = document.getElementById('packaging').value - updated['item_info']['packaging'] = value - } - if (logis == 'ai_pick'){ - let value = document.getElementById('aiPickableCheckbox').checked - console.log(value) - updated['item_info']['ai_pick'] = value - } -} - -async function foodInfoChanged(logis) { - if (!updated.hasOwnProperty('food_info')){ - updated['food_info'] = {} - } - if (logis === "expires"){ - let value = document.getElementById('expiresCheckbox').checked - updated['food_info']['expires'] = value - } - if (logis === "default_expiration"){ - let value = document.getElementById('expirePeriod').value - updated['food_info']['default_expiration'] = value - } -} - -async function setPrefixPage(pageNumber){ - current_page = pageNumber; - let data = await fetchPrefixes() - end_page = data.end; - await updatePrefixModalTableBody(data.prefixes) - await updatePrefixPaginationElement() -} - -async function updatePrefixPaginationElement() { - let paginationElement = document.getElementById('prefixesModalPage'); - paginationElement.innerHTML = ""; - // previous - let previousElement = document.createElement('li') - if(current_page<=1){ - previousElement.innerHTML = ``; - previousElement.classList.add('uk-disabled'); - }else { - previousElement.innerHTML = ``; - } - paginationElement.append(previousElement) - - //first - let firstElement = document.createElement('li') - if(current_page<=1){ - firstElement.innerHTML = `1`; - firstElement.classList.add('uk-disabled'); - }else { - firstElement.innerHTML = `1`; - } - paginationElement.append(firstElement) - - // ... - if(current_page-2>1){ - let firstDotElement = document.createElement('li') - firstDotElement.classList.add('uk-disabled') - firstDotElement.innerHTML = ``; - paginationElement.append(firstDotElement) - } - // last - if(current_page-2>0){ - let lastElement = document.createElement('li') - lastElement.innerHTML = `${current_page-1}` - paginationElement.append(lastElement) - } - // current - if(current_page!=1 && current_page != end_page){ - let currentElement = document.createElement('li') - currentElement.innerHTML = `
  • ${current_page}
  • ` - paginationElement.append(currentElement) - } - // next - if(current_page+2${current_page+1}` - paginationElement.append(nextElement) - } - // ... - if(current_page+2<=end_page){ - let secondDotElement = document.createElement('li') - secondDotElement.classList.add('uk-disabled') - secondDotElement.innerHTML = ``; - paginationElement.append(secondDotElement) - } - //end - let endElement = document.createElement('li') - if(current_page>=end_page){ - endElement.innerHTML = `${end_page}`; - endElement.classList.add('uk-disabled'); - }else { - endElement.innerHTML = `${end_page}`; - } - paginationElement.append(endElement) - //next button - let nextElement = document.createElement('li') - if(current_page>=end_page){ - nextElement.innerHTML = ``; - nextElement.classList.add('uk-disabled'); - }else { - nextElement.innerHTML = ``; - console.log(nextElement.innerHTML) - } - paginationElement.append(nextElement) -} - -// Possible Locations functions -var new_locations_current_page = 1 -var new_locations_end_page = 1 -var new_locations_limit = 25 -async function fetch_new_locations() { - const url = new URL('/items/getPossibleLocations', window.location.origin); - url.searchParams.append('page', new_locations_current_page); - url.searchParams.append('limit', new_locations_limit); - const response = await fetch(url); - data = await response.json(); - new_locations_end_page = data.end; - return data.locations -}; - -async function postNewItemLocation(location_id) { - const response = await fetch(`/items/postNewItemLocation`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - item_id: parseInt(item_id), - location_id: parseInt(location_id) - }), - }); - - data = await response.json(); - response_status = 'success' - if (data.error){ - response_status = 'danger' - } - - UIkit.notification({ - message: data.message, - status: response_status, - pos: 'top-right', - timeout: 5000 - }); - await fetchItem() - await updateLocationsTable() -} - -async function replenishPossibleLocationsTableBody(locations){ - let NewLocationsModalTableBody = document.getElementById('NewLocationsModalTableBody') - NewLocationsModalTableBody.innerHTML = "" - - for(let i =0; i `; - previousElement.classList.add('uk-disabled'); - }else { - previousElement.innerHTML = ``; - } - paginationElement.append(previousElement) - - //first - let firstElement = document.createElement('li') - if(new_locations_current_page<=1){ - firstElement.innerHTML = `1`; - firstElement.classList.add('uk-disabled'); - }else { - firstElement.innerHTML = `1`; - } - paginationElement.append(firstElement) - - // ... - if(new_locations_current_page-2>1){ - let firstDotElement = document.createElement('li') - firstDotElement.classList.add('uk-disabled') - firstDotElement.innerHTML = ``; - paginationElement.append(firstDotElement) - } - // last - if(new_locations_current_page-2>0){ - let lastElement = document.createElement('li') - lastElement.innerHTML = `${new_locations_current_page-1}` - paginationElement.append(lastElement) - } - // current - if(new_locations_current_page!=1 && new_locations_current_page != new_locations_end_page){ - let currentElement = document.createElement('li') - currentElement.innerHTML = `
  • ${new_locations_current_page}
  • ` - paginationElement.append(currentElement) - } - // next - if(new_locations_current_page+2${new_locations_current_page+1}` - paginationElement.append(nextElement) - } - // ... - if(new_locations_current_page+2<=new_locations_end_page){ - let secondDotElement = document.createElement('li') - secondDotElement.classList.add('uk-disabled') - secondDotElement.innerHTML = ``; - paginationElement.append(secondDotElement) - } - //end - let endElement = document.createElement('li') - if(new_locations_current_page>=new_locations_end_page){ - endElement.innerHTML = `${new_locations_end_page}`; - endElement.classList.add('uk-disabled'); - }else { - endElement.innerHTML = `${new_locations_end_page}`; - } - paginationElement.append(endElement) - //next button - let nextElement = document.createElement('li') - if(new_locations_current_page>=new_locations_end_page){ - nextElement.innerHTML = ``; - nextElement.classList.add('uk-disabled'); - }else { - nextElement.innerHTML = ``; - } - paginationElement.append(nextElement) -} \ No newline at end of file + let data = await response.json(); + item = new InventoryItem(data.item); + item_info = new ItemInfo(data.item.item_info) + food_info = new FoodInfo(data.item.food_info) + logistics_info = new LogisticsInfo(data.item.logistics_info) +}; \ No newline at end of file diff --git a/application/items/static/itemEditHandler_old.js b/application/items/static/itemEditHandler_old.js new file mode 100644 index 0000000..868c8d8 --- /dev/null +++ b/application/items/static/itemEditHandler_old.js @@ -0,0 +1,1685 @@ +import { InventoryItem, ItemInfo } from './inventoryClasses.js'; + + +var item; +var linked_items; +var tags = new Set(); +var weblinks; +var shopping_lists; +var food_groups = new Set(); +var ingrediants = new Set(); +var primary_zone; +var primary_zone_id; +var primary_location; +var auto_zone; +var auto_zone_id; +var auto_location; +var brand; +var locations; + +var current_page = 1; +var limit = 2; +var end_page = 1; +var search_string = ''; + +var updated = {}; + +// form defaults, make this editable. +var item_types = [['Single', 'single'], ['Linked List', 'list'], ['Linked Item', 'link']]; +var item_subtypes = [['Food', 'FOOD'], ['Food PLU', 'FOOD_PLU'], ['Other', 'OTHER'], ['Medicinal', 'MEDICINE'], ['Hygenic', 'HYGENIC']]; + +document.addEventListener('DOMContentLoaded', async function() { + await setupFormDefaults() + await refreshForm() +}) + + +async function refreshForm(){ + await fetchItem() + document.getElementById('title').innerHTML = item.item_name; + await setBasicInfo() + await updateWebLinksTable() + await updateReferenceTable() + await updateLocationsTable() + await updateLinkedItemsTable() + await updateConversionsTableBody() + await updatePrefixTableBody() + await updateTags() + await updateBarcodes() +} + +async function setupFormDefaults() { + let itemTypeSelect = document.getElementById('itemTypeSelect') + for(let i=0; i${weblinks[key]}` + let buttonCell = document.createElement('td') + buttonCell.classList.add('uk-width-1-4') + + let deleteButton = document.createElement('button') + deleteButton.setAttribute('class', 'uk-flex uk-flex-middle uk-flex-center uk-button uk-button-small uk-align-right delete_button') + deleteButton.onclick = function (){ + deleteLink(key) + } + deleteButton.innerHTML = `` + + buttonCell.append(deleteButton) + + tableRow.append(nameCell) + tableRow.append(linkCell) + tableRow.append(buttonCell) + weblinksTableBody.append(tableRow) + } +} + +async function updateTags() { + let chipZoneTags = document.getElementById('tagsRow') + chipZoneTags.innerHTML = ""; + tags.forEach(tagText => { + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `tag_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeTag(tagText, tag.id) + } + chipZoneTags.append(tag) + }); + let foodGroupsTags = document.getElementById('foodGroupsTagsRow') + foodGroupsTags.innerHTML = ""; + food_groups.forEach(tagText => { + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `tag_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeFoodGroup(tagText, tag.id) + } + foodGroupsTags.append(tag) + }); + let ingrediantsRow = document.getElementById('ingrediantsRow') + ingrediantsRow.innerHTML = ""; + ingrediants.forEach(tagText => { + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `ingr_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeIngrediant(tagText, tag.id) + } + ingrediantsRow.append(tag) + }); +} + +async function updateLocationsTable() { + let locationsTableBody = document.getElementById('locationsTableBody') + locationsTableBody.innerHTML = ""; + for(let i=0; i < locations.length; i++){ + console.log(locations[i]) + let tableRow = document.createElement('tr') + + let locationCell = document.createElement('td') + locationCell.innerHTML = `${locations[i].uuid}` + let QOHCell = document.createElement('td') + QOHCell.innerHTML = `${locations[i].quantity_on_hand}` + + tableRow.append(locationCell) + tableRow.append(QOHCell) + locationsTableBody.append(tableRow) + } +} + +async function setBasicInfo() { + document.getElementById('itemName').value = item.item_name + document.getElementById('itemBarcode').innerHTML = item.barcode + document.getElementById('itemBrand').value = brand; + document.getElementById('itemDescription').value = item.description + document.getElementById('itemTypeSelect').value = item.row_type + if(item.row_type === "list"){ + document.getElementById("linkedListLink").classList.remove("uk-disabled") + } else if (item.row_type === "link"){ + document.getElementById('itemTypeSelect').classList.add("uk-disabled") + } else { + document.getElementById("linkedListLink").classList.add("uk-disabled") + document.getElementById('itemTypeSelect').classList.remove("uk-disabled") + } + document.getElementById('itemSubTypeSelect').value = item.item_type + document.getElementById('aiPickableCheckbox').checked = item.item_info.ai_pick + document.getElementById('expiresCheckbox').checked = item.food_info.expires + document.getElementById('expirePeriod').value = item.food_info.default_expiration + document.getElementById('safetyStock').value = item.item_info.safety_stock + document.getElementById('leadTimeInDays').value = item.item_info.lead_time_days + document.getElementById('skuCost').value = item.item_info.cost.toLocaleString('en-US', {style: 'currency', currency: 'USD'}) + document.getElementById('uom_quantity').value = item.item_info.uom_quantity + document.getElementById('uom').value = item.item_info.uom.id + document.getElementById('packaging').value = item.item_info.packaging + document.getElementById('primaryZone').value = primary_zone + document.getElementById('primaryLocation').value = primary_location + document.getElementById('autoZone').value = auto_zone + document.getElementById('autoLocation').value = auto_location + + document.getElementById('main_qty_uom').value = `${item.item_info.uom_quantity} ${item.item_info.uom}` + document.getElementById('main_barcode').value = item.barcode + document.getElementById('search_string_main').value = item.search_string + + console.log(item) + let referenceCount = 0 + referenceCount += item.item_shopping_lists.length + referenceCount += item.item_recipes.length + + if (referenceCount> 0){ + document.getElementById('inactiveButton').classList.add('uk-disabled') + } + + +} + +function addTag(event){ + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + let tagInput = document.getElementById('tagInput'); + tagText = tagInput.value; + if((event.code=="Enter" || event.type=="click") && !tags.has(tagText)){ + console.log(tagText) + tags.add(tagText) + updated['item']['tags'] = Array.from(tags) + let chipZoneTags = document.getElementById('tagsRow') + + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `tag_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeTag(tagText, tag.id) + } + chipZoneTags.append(tag) + tagInput.classList.remove('uk-form-danger') + } else if((event.code=="Enter" || event.type=="click") && tags.has(tagText)){ + tagInput.classList.add('uk-form-danger') + UIkit.notification({ + message: 'Duplicate Tags are not Allowed!', + status: 'danger', + pos: 'top-right', + timeout: 2000 + }); + + } else { + tagInput.classList.remove('uk-form-danger') + } +} + +function addFoodGroup(event){ + if (!updated.hasOwnProperty('food_info')){ + updated['food_info'] = {} + } + let foodGroupsInput = document.getElementById('foodGroupsInput'); + tagText = foodGroupsInput.value; + if((event.code=="Enter" || event.type=="click") && !food_groups.has(tagText)){ + food_groups.add(tagText) + updated['food_info']['food_groups'] = Array.from(food_groups) + let chipZoneTags = document.getElementById('foodGroupsTagsRow') + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `food_group_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeFoodGroup(tagText, tag.id) + } + chipZoneTags.append(tag) + foodGroupsInput.classList.remove('uk-form-danger') + } else if((event.code=="Enter" || event.type=="click") && food_groups.has(tagText)){ + foodGroupsInput.classList.add('uk-form-danger') + UIkit.notification({ + message: 'Duplicate Food Groups are not Allowed!', + status: 'danger', + pos: 'top-right', + timeout: 2000 + }); + + } else { + foodGroupsInput.classList.remove('uk-form-danger') + } +} + +function addIngrediant(event){ + if (!updated.hasOwnProperty('food_info')){ + updated['food_info'] = {} + } + let ingrediantsInput = document.getElementById('ingrediantsInput'); + tagText = ingrediantsInput.value; + if((event.code=="Enter" || event.type=="click") && !ingrediants.has(tagText)){ + ingrediants.add(tagText) + updated['food_info']['ingrediants'] = Array.from(ingrediants) + let chipZoneTags = document.getElementById('ingrediantsRow') + + let tag = document.createElement('div') + tag.setAttribute("uk-tooltip", "title: Double click to Remove; pos: bottom") + tag.setAttribute("class", "chip uk-border-pill uk-label uk-margin-xsmall-right") + tag.setAttribute("id", `ingr_${tagText}`) + tag.innerHTML = tagText + tag.ondblclick = function(){ + removeIngrediant(tagText, tag.id) + } + chipZoneTags.append(tag) + ingrediantsInput.classList.remove('uk-form-danger') + } else if((event.code=="Enter" || event.type=="click") && ingrediants.has(tagText)){ + ingrediantsInput.classList.add('uk-form-danger') + UIkit.notification({ + message: 'Duplicate ingrediants are not Allowed!', + status: 'danger', + pos: 'top-right', + timeout: 2000 + }); + + } else { + ingrediantsInput.classList.remove('uk-form-danger') + } +} + +function removeTag(tagText, elementID) { + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + let childElement = document.getElementById(elementID) + let tempTags = Array.from(tags); + tempTags = tempTags.filter(item => item !== tagText); + updated['item']['tags'] = tempTags; + tags = new Set(tempTags); + childElement.parentNode.removeChild(childElement) +} + +function removeFoodGroup(tagText, elementID) { + if (!updated.hasOwnProperty('food_info')){ + updated['food_info'] = {} + } + let childElement = document.getElementById(elementID) + let tempTags = Array.from(food_groups); + tempTags = tempTags.filter(item => item !== tagText); + updated['food_info']['food_groups'] = tempTags; + food_groups = new Set(tempTags); + childElement.parentNode.removeChild(childElement) +} + +function removeIngrediant(tagText, elementID) { + if (!updated.hasOwnProperty('food_info')){ + updated['food_info'] = {} + } + console.log(tagText) + console.log(elementID) + let childElement = document.getElementById(elementID) + let tempTags = Array.from(ingrediants); + tempTags = tempTags.filter(item => item !== tagText); + updated['food_info']['ingrediants'] = tempTags + ingrediants = new Set(tempTags); + childElement.parentNode.removeChild(childElement) +} + +function deleteLink(linkKey){ + console.log(linkKey) +} + +async function updateLocationsSelectTable(logis) { + let fetchedLocations; + let selectlocationsTableBody = document.getElementById('selectlocationsTableBody') + selectlocationsTableBody.innerHTML = "" + + if (logis=='primary_location'){ + data = await fetchLocations('primary_location'); + fetchedLocations = data.locations; + end_page = data.endpage; + } else if (logis=='auto_issue_location'){ + data = await fetchLocations('auto_issue_location'); + fetchedLocations = data.locations; + end_page = data.endpage; + } + + console.log(fetchedLocations) + for(let i = 0; i < fetchedLocations.length; i++){ + + let tableRow = document.createElement('tr') + tableRow.classList.add("selectableRow") + + let nameCell = document.createElement('td') + nameCell.innerHTML = `${fetchedLocations[i].name}` + + tableRow.id = fetchedLocations[i].id + + tableRow.append(nameCell) + tableRow.onclick = function(){ + closeZoneLocationBrandModal(fetchedLocations[i].name, fetchedLocations[i].id, logis) + } + selectlocationsTableBody.append(tableRow) + } +} + +async function openLocationsModal(logis, elementID){ + let LocationsModal = document.getElementById("LocationsModal") + current_page = 1; + search_string = ''; + await updateLocationsSelectTable(logis) + await updatePaginationElement(logis, elementID) + UIkit.modal(LocationsModal).show(); +} + +async function updateZonesTable(logis) { + let zonesTableBody = document.getElementById('zonesTableBody') + zonesTableBody.innerHTML = "" + data = await fetchZones() + zones = data.zones + end_page = data.endpage + for(let i = 0; i < zones.length; i++){ + let tableRow = document.createElement('tr') + + let nameCell = document.createElement('td') + nameCell.innerHTML = `${zones[i].name}` + + tableRow.id = zones[i].id + + tableRow.append(nameCell) + tableRow.onclick = function(){ + closeZoneLocationBrandModal(zones[i].name, zones[i].id, logis) + } + zonesTableBody.append(tableRow) + } +} + +async function updateLinkedItemsTable() { + let linkedItemsTableBody = document.getElementById('linkedItemsTableBody') + linkedItemsTableBody.innerHTML = "" + + let linked_items = item.linked_items + for(let i = 0; i < linked_items.length; i++){ + + let tableRow = document.createElement('tr') + + let barcodeCell = document.createElement('td') + barcodeCell.innerHTML = linked_items[i].barcode + let nameCell = document.createElement('td') + nameCell.innerHTML = linked_items[i].data.item_name + let opCell = document.createElement('td') + + let editOp = document.createElement('a') + editOp.setAttribute('class', 'uk-button uk-button-default') + editOp.setAttribute('uk-icon', 'icon: pencil') + editOp.setAttribute('href', `/items/${item['id']}/itemLink/${linked_items[i].id}`) + + opCell.append(editOp) + + tableRow.append(barcodeCell, nameCell, opCell) + linkedItemsTableBody.append(tableRow) + } +} + + +async function openZonesModal(logis, elementID){ + let zonesModal = document.getElementById("zonesModal") + current_page = 1; + search_string = ''; + await updateZonesTable(logis) + await updatePaginationElement(logis, elementID) + UIkit.modal(zonesModal).show(); +} + +function closeZoneLocationBrandModal(selectName, selectID, key){ + if (!updated.hasOwnProperty('logistics_info')){ + updated['logistics_info'] = {} + } + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + + if(key=='primary_zone'){ + primary_zone = selectName; + primary_zone_id = selectID; + document.getElementById('primaryZone').value = selectName; + updated['logistics_info']['primary_zone'] = selectID + document.getElementById('primaryLocation').classList.add('uk-form-danger') + document.getElementById('primaryLocation').value = ""; + UIkit.modal(document.getElementById('zonesModal')).hide(); + } + if(key=='auto_issue_zone'){ + auto_zone = selectName; + auto_zone_id = selectID; + document.getElementById('autoZone').value = selectName; + updated['logistics_info']['auto_issue_zone'] = selectID; + document.getElementById('autoLocation').classList.add('uk-form-danger') + document.getElementById('autoLocation').value = ""; + UIkit.modal(document.getElementById('zonesModal')).hide(); + } + if(key=='primary_location'){ + primary_location = selectName; + document.getElementById('primaryLocation').value = selectName; + updated['logistics_info']['primary_location'] = selectID; + document.getElementById('primaryLocation').classList.remove('uk-form-danger') + UIkit.modal(document.getElementById('LocationsModal')).hide(); + } + if(key=='auto_issue_location'){ + auto_location = selectName; + document.getElementById('autoLocation').value = selectName; + updated['logistics_info']['auto_issue_location'] = selectID; + document.getElementById('autoLocation').classList.remove('uk-form-danger') + UIkit.modal(document.getElementById('LocationsModal')).hide(); + } + if(key=='brand'){ + brand = selectName; + document.getElementById('itemBrand').value = selectName; + updated['item']['brand'] = selectID; + UIkit.modal(document.getElementById('brandsModal')).hide(); + } + if(key=='items'){ + barcode = selectName[0]; + document.getElementById('linked_item').value = barcode; + document.getElementById('conversion_factor_uom').value = selectName[1]; + document.getElementById('linked_item_id').value = selectID; + document.getElementById('linkAdd').onclick = async function () { + await addLinkedItem(item_id, selectID) + } + UIkit.modal(document.getElementById('itemsModal')).hide(); + } +} + +async function updateBrandsModalTable(logis) { + let brandsTableBody = document.getElementById('brandsTableBody'); + brandsTableBody.innerHTML = ""; + data = await fetchBrands(); + end_page = data.endpage; + let fetchedBrands = data.brands; + + for(let i=0; i < fetchedBrands.length; i++){ + let tableRow = document.createElement('tr') + + let nameCell = document.createElement('td') + nameCell.innerHTML = `${fetchedBrands[i].name}` + + tableRow.id = fetchedBrands[i].id + tableRow.onclick = function(){ + closeZoneLocationBrandModal(fetchedBrands[i].name, fetchedBrands[i].id, logis) + } + tableRow.append(nameCell) + brandsTableBody.append(tableRow) + } +} + +async function updateItemsModalTable(logis) { + let itemsTableBody = document.getElementById('itemsTableBody'); + itemsTableBody.innerHTML = ""; + data = await fetchItems(); + end_page = data.end; + let fetchedItems = data.items; + + + for(let i=0; i < fetchedItems.length; i++){ + let tableRow = document.createElement('tr') + + let idCell = document.createElement('td') + idCell.innerHTML = `${fetchedItems[i].id}` + + let barcodeCell = document.createElement('td') + barcodeCell.innerHTML = `${fetchedItems[i].barcode}` + + let nameCell = document.createElement('td') + nameCell.innerHTML = `${fetchedItems[i].item_name}` + + tableRow.id = fetchedItems[i].id + tableRow.onclick = async function(){ + closeZoneLocationBrandModal([fetchedItems[i].barcode, fetchedItems[i].uom], fetchedItems[i].id, logis) + } + tableRow.append(idCell, barcodeCell, nameCell) + itemsTableBody.append(tableRow) + console.log(tableRow.onclick) + } +} + +async function openBrandsModal(logis, elementID) { + let brandsModal = document.getElementById('brandsModal') + current_page = 1; + search_string = ''; + await updateBrandsModalTable(logis) + await updatePaginationElement(logis, elementID) + UIkit.modal(brandsModal).show(); + +} + +async function openItemsModal(logis, elementID) { + let itemsModal = document.getElementById('itemsModal') + current_page = 1; + search_string = ''; + document.getElementById('searchItemsInput').value = ''; + await updateItemsModalTable(logis) + await updatePaginationElement(logis, elementID) + UIkit.modal(itemsModal).show(); +} + +async function openAddConversionsModal() { + let conversionsModal = document.getElementById('conversionsModal') + document.getElementById('parent_uom').value = `${item.item_info.uom.fullname}` + document.getElementById('conversionSubmitButton').innerHTML = "Add" + document.getElementById('conversionSubmitButton').onclick = async function() { + await postConversion() + } + UIkit.modal(conversionsModal).show() +} + +async function openEditConversionsModal(conversion) { + let conversionsModal = document.getElementById('conversionsModal') + document.getElementById('parent_uom').value = `${item.item_info.uom.fullname}` + document.getElementById('conversion_factor_modal').value = `${conversion.conv_factor}` + document.getElementById('conversion_uom').value = `${conversion.id}` + document.getElementById('conversionSubmitButton').innerHTML = "Save" + document.getElementById('conversionSubmitButton').onclick = async function() { + let update = {'conv_factor': document.getElementById('conversion_factor_modal').value} + await postConversionUpdate(conversion.conv_id, update) + } + UIkit.modal(conversionsModal).show() +} + +async function postConversion() { + const response = await fetch(`/items/addConversion`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + parent_id: parseInt(item.id), + uom_id: parseInt(document.getElementById('conversion_uom').value), + conv_factor: parseFloat(document.getElementById('conversion_factor_modal').value) + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + await fetchItem() + await setBasicInfo() + await updateConversionsTableBody() + + UIkit.modal(conversionsModal).hide() +} + +async function postConversionUpdate(id, update) { + const response = await fetch(`/items/updateConversion`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + conversion_id: id, + update: update + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + await fetchItem() + await setBasicInfo() + await updateConversionsTableBody() + + UIkit.modal(conversionsModal).hide() +} + +async function deleteConversion(conversion_id) { + const response = await fetch(`/items/deleteConversion`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + conversion_id: conversion_id + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await fetchItem() + await setBasicInfo() + await updateConversionsTableBody() + + UIkit.modal(conversionsModal).hide() + +} + +async function openAddPrefixesModal() { + let prefixesModal = document.getElementById('prefixesModal') + current_page = 1; + let data = await fetchPrefixes() + let prefixes = data.prefixes + end_page = data.end; + await updatePrefixModalTableBody(prefixes) + await updatePrefixPaginationElement() + UIkit.modal(prefixesModal).show() +} + +async function postPrefix(id) { + const response = await fetch(`/items/addPrefix`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + parent_id: parseInt(item.item_info_id), + prefix_id: parseInt(id) + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + await fetchItem() + await setBasicInfo() + await updatePrefixTableBody() + UIkit.modal(document.getElementById('prefixesModal')).hide() +} + +async function deletePrefix(prefix_id) { + const response = await fetch(`/items/deletePrefix`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + item_info_id: item.item_info_id, + prefix_id: prefix_id + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await fetchItem() + await setBasicInfo() + await updatePrefixTableBody() + + UIkit.modal(document.getElementById('prefixesModal')).hide() + +} + +let prefix_limit = 2; +async function fetchPrefixes() { + const url = new URL('/items/getPrefixes', window.location.origin); + url.searchParams.append('page', current_page); + url.searchParams.append('limit', prefix_limit); + const response = await fetch(url); + data = await response.json(); + return data; +} + +let brands_limit = 25; +async function fetchBrands() { + const url = new URL('/items/getBrands', window.location.origin); + url.searchParams.append('page', current_page); + url.searchParams.append('limit', brands_limit); + const response = await fetch(url); + data = await response.json(); + return data; +} + +let items_limit = 25; +async function fetchItems() { + const url = new URL('/items/getModalItems', window.location.origin); + url.searchParams.append('page', current_page); + url.searchParams.append('limit', items_limit); + url.searchParams.append('search_string', search_string); + const response = await fetch(url); + data = await response.json(); + return data; +} + +let zones_limit = 20; +async function fetchZones(){ + const url = new URL('/items/getZonesBySku', window.location.origin); + url.searchParams.append('page', current_page); + url.searchParams.append('limit', zones_limit); + url.searchParams.append('item_id', item.id); + const response = await fetch(url); + data = await response.json(); + return data; +} + +let locations_limit = 10; +async function fetchLocations(logis) { + const url = new URL('/items/getLocationsBySkuZone', window.location.origin); + url.searchParams.append('page', current_page); + url.searchParams.append('limit', locations_limit); + url.searchParams.append('part_id', item.id); + if(logis=="primary_location"){ + url.searchParams.append('zone_id', primary_zone_id); + } else if (logis=="auto_issue_location"){ + url.searchParams.append('zone_id', auto_zone_id); + } + const response = await fetch(url); + data = await response.json(); + return data; +} + +async function fetchItem() { + const url = new URL('/items/api/getItem', window.location.origin); + url.searchParams.append('item_uuid', item_uuid); + const response = await fetch(url); + // console.log(await response.json()) + let data = await response.json(); + item = new InventoryItem(data.item); + item_info = new ItemInfo(data.item_info) + + + shopping_lists = item.item_shopping_lists; + food_groups = new Set(item.food_info.food_groups); + ingrediants = new Set(item.food_info.ingrediants); + + primary_zone = item.logistics_info.primary_zone.name + primary_zone_id = item.logistics_info.primary_zone.id + primary_location = item.logistics_info.primary_location.name + + auto_zone = item.logistics_info.auto_issue_zone.name + auto_zone_id = item.logistics_info.auto_issue_zone.id + auto_location = item.logistics_info.auto_issue_location.name + locations = item.item_locations + + brand = item.brand.name + return item; +}; + +async function searchTable(event, logis, elementID) { + if(event.key==='Enter' && logis==='items'){ + search_string = event.srcElement.value + await updateItemsModalTable(logis) + } + await updatePaginationElement(logis, elementID) +} + +async function setPage(pageNumber, logis, elementID){ + current_page = pageNumber; + + if(elementID=="zonesPage"){ + await updateZonesTable(logis) + } else if(elementID=="locationsPage"){ + await updateLocationsSelectTable(logis) + }else if (elementID=="brandsPage"){ + await updateBrandsModalTable(logis) + } else if (elementID=="itemsPage"){ + await updateItemsModalTable(logis) + } + await updatePaginationElement(logis, elementID) + console.log(current_page) +} + +async function updatePaginationElement(logis, elementID) { + let paginationElement = document.getElementById(elementID); + paginationElement.innerHTML = ""; + // previous + let previousElement = document.createElement('li') + if(current_page<=1){ + previousElement.innerHTML = ``; + previousElement.classList.add('uk-disabled'); + }else { + previousElement.innerHTML = ``; + } + paginationElement.append(previousElement) + + //first + let firstElement = document.createElement('li') + if(current_page<=1){ + firstElement.innerHTML = `1`; + firstElement.classList.add('uk-disabled'); + }else { + firstElement.innerHTML = `1`; + } + paginationElement.append(firstElement) + + // ... + if(current_page-2>1){ + let firstDotElement = document.createElement('li') + firstDotElement.classList.add('uk-disabled') + firstDotElement.innerHTML = ``; + paginationElement.append(firstDotElement) + } + // last + if(current_page-2>0){ + let lastElement = document.createElement('li') + lastElement.innerHTML = `${current_page-1}` + paginationElement.append(lastElement) + } + // current + if(current_page!=1 && current_page != end_page){ + let currentElement = document.createElement('li') + currentElement.innerHTML = `
  • ${current_page}
  • ` + paginationElement.append(currentElement) + } + // next + if(current_page+2${current_page+1}` + paginationElement.append(nextElement) + } + // ... + if(current_page+2<=end_page){ + let secondDotElement = document.createElement('li') + secondDotElement.classList.add('uk-disabled') + secondDotElement.innerHTML = ``; + paginationElement.append(secondDotElement) + } + //end + let endElement = document.createElement('li') + if(current_page>=end_page){ + endElement.innerHTML = `${end_page}`; + endElement.classList.add('uk-disabled'); + }else { + endElement.innerHTML = `${end_page}`; + } + paginationElement.append(endElement) + //next button + let nextElement = document.createElement('li') + if(current_page>=end_page){ + nextElement.innerHTML = ``; + nextElement.classList.add('uk-disabled'); + }else { + nextElement.innerHTML = ``; + console.log(nextElement.innerHTML) + } + paginationElement.append(nextElement) +} + +async function addLinkedItem(parent_id, child_id) { + let conversion_factor = parseFloat(document.getElementById('conversion_factor').value) + + if(Number.isInteger(conversion_factor)){ + document.getElementById('conversion_factor').classList.remove('uk-form-danger') + const response = await fetch(`/items/addLinkedItem`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + parent_id: parseInt(parent_id), + child_id: parseInt(child_id), + conv_factor: conversion_factor + }), + }); + data = await response.json(); + response_status = 'primary' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + document.getElementById('linked_item').value = "" + document.getElementById('conversion_factor').value = "" + document.getElementById('linked_item_id').value = "" + document.getElementById('linkAdd').onclick = null + + await fetchItem() + await setBasicInfo() + await updateLinkedItemsTable() + + } else { + document.getElementById('conversion_factor').classList.add('uk-form-danger') + } +} + +async function saveUpdated() { + const response = await fetch(`/items/updateItem`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: parseInt(item_id), + data: updated + }), + }); + + data = await response.json(); + response_status = 'success' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + updated = {} + await fetchItem() + await setBasicInfo() +}; + +async function inactivateItem() { + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + + updated['item']['inactive'] = !item.inactive + + const response = await fetch(`/items/api/inactivateItem`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + item_id: parseInt(item_id), + data: updated + }), + }); + location.href = "/items" +} + +async function refreshSearchString() { + const response = await fetch(`/items/refreshSearchString`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + item_id: parseInt(item.id) + }), + }); + + data = await response.json(); + response_status = 'success' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + + await fetchItem() + await setBasicInfo() +}; + + +async function descriptionChanged() { + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + + updated['item']['description'] = document.getElementById('itemDescription').value +} + +async function nameChanged() { + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + + updated['item']['item_name'] = document.getElementById('itemName').value +} + +async function selectChanged(logis) { + if (!updated.hasOwnProperty('item')){ + updated['item'] = {} + } + if(logis=='row_type'){ + updated['item'][logis] = document.getElementById('itemTypeSelect').value + } + if(logis == 'item_type'){ + updated['item'][logis] = document.getElementById('itemSubTypeSelect').value + } +} + +async function itemInfoChanged(logis) { + if (!updated.hasOwnProperty('item_info')){ + updated['item_info'] = {} + } + if (logis == 'safety_stock'){ + let value = document.getElementById('safetyStock').value + updated['item_info']['safety_stock'] = parseFloat(value) + } + if (logis == 'lead_time_days'){ + let value = document.getElementById('leadTimeInDays').value + updated['item_info']['lead_time_days'] = parseFloat(value) + } + if (logis == 'cost'){ + let value = document.getElementById('skuCost').value + value = parseFloat(value.replace(/[^0-9.-]+/g,"")); + updated['item_info']['cost'] = value + } + if (logis == 'uom_quantity'){ + let value = document.getElementById('uom_quantity').value + updated['item_info']['uom_quantity'] = value + } + if (logis == 'uom'){ + let value = document.getElementById('uom').value + updated['item_info']['uom'] = value + } + if (logis == 'packaging'){ + let value = document.getElementById('packaging').value + updated['item_info']['packaging'] = value + } + if (logis == 'ai_pick'){ + let value = document.getElementById('aiPickableCheckbox').checked + console.log(value) + updated['item_info']['ai_pick'] = value + } +} + +async function foodInfoChanged(logis) { + if (!updated.hasOwnProperty('food_info')){ + updated['food_info'] = {} + } + if (logis === "expires"){ + let value = document.getElementById('expiresCheckbox').checked + updated['food_info']['expires'] = value + } + if (logis === "default_expiration"){ + let value = document.getElementById('expirePeriod').value + updated['food_info']['default_expiration'] = value + } +} + +async function setPrefixPage(pageNumber){ + current_page = pageNumber; + let data = await fetchPrefixes() + end_page = data.end; + await updatePrefixModalTableBody(data.prefixes) + await updatePrefixPaginationElement() +} + +async function updatePrefixPaginationElement() { + let paginationElement = document.getElementById('prefixesModalPage'); + paginationElement.innerHTML = ""; + // previous + let previousElement = document.createElement('li') + if(current_page<=1){ + previousElement.innerHTML = ``; + previousElement.classList.add('uk-disabled'); + }else { + previousElement.innerHTML = ``; + } + paginationElement.append(previousElement) + + //first + let firstElement = document.createElement('li') + if(current_page<=1){ + firstElement.innerHTML = `1`; + firstElement.classList.add('uk-disabled'); + }else { + firstElement.innerHTML = `1`; + } + paginationElement.append(firstElement) + + // ... + if(current_page-2>1){ + let firstDotElement = document.createElement('li') + firstDotElement.classList.add('uk-disabled') + firstDotElement.innerHTML = ``; + paginationElement.append(firstDotElement) + } + // last + if(current_page-2>0){ + let lastElement = document.createElement('li') + lastElement.innerHTML = `${current_page-1}` + paginationElement.append(lastElement) + } + // current + if(current_page!=1 && current_page != end_page){ + let currentElement = document.createElement('li') + currentElement.innerHTML = `
  • ${current_page}
  • ` + paginationElement.append(currentElement) + } + // next + if(current_page+2${current_page+1}` + paginationElement.append(nextElement) + } + // ... + if(current_page+2<=end_page){ + let secondDotElement = document.createElement('li') + secondDotElement.classList.add('uk-disabled') + secondDotElement.innerHTML = ``; + paginationElement.append(secondDotElement) + } + //end + let endElement = document.createElement('li') + if(current_page>=end_page){ + endElement.innerHTML = `${end_page}`; + endElement.classList.add('uk-disabled'); + }else { + endElement.innerHTML = `${end_page}`; + } + paginationElement.append(endElement) + //next button + let nextElement = document.createElement('li') + if(current_page>=end_page){ + nextElement.innerHTML = ``; + nextElement.classList.add('uk-disabled'); + }else { + nextElement.innerHTML = ``; + console.log(nextElement.innerHTML) + } + paginationElement.append(nextElement) +} + +// Possible Locations functions +var new_locations_current_page = 1 +var new_locations_end_page = 1 +var new_locations_limit = 25 +async function fetch_new_locations() { + const url = new URL('/items/getPossibleLocations', window.location.origin); + url.searchParams.append('page', new_locations_current_page); + url.searchParams.append('limit', new_locations_limit); + const response = await fetch(url); + data = await response.json(); + new_locations_end_page = data.end; + return data.locations +}; + +async function postNewItemLocation(location_id) { + const response = await fetch(`/items/postNewItemLocation`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + item_id: parseInt(item_id), + location_id: parseInt(location_id) + }), + }); + + data = await response.json(); + response_status = 'success' + if (data.error){ + response_status = 'danger' + } + + UIkit.notification({ + message: data.message, + status: response_status, + pos: 'top-right', + timeout: 5000 + }); + await fetchItem() + await updateLocationsTable() +} + +async function replenishPossibleLocationsTableBody(locations){ + let NewLocationsModalTableBody = document.getElementById('NewLocationsModalTableBody') + NewLocationsModalTableBody.innerHTML = "" + + for(let i =0; i `; + previousElement.classList.add('uk-disabled'); + }else { + previousElement.innerHTML = ``; + } + paginationElement.append(previousElement) + + //first + let firstElement = document.createElement('li') + if(new_locations_current_page<=1){ + firstElement.innerHTML = `1`; + firstElement.classList.add('uk-disabled'); + }else { + firstElement.innerHTML = `1`; + } + paginationElement.append(firstElement) + + // ... + if(new_locations_current_page-2>1){ + let firstDotElement = document.createElement('li') + firstDotElement.classList.add('uk-disabled') + firstDotElement.innerHTML = ``; + paginationElement.append(firstDotElement) + } + // last + if(new_locations_current_page-2>0){ + let lastElement = document.createElement('li') + lastElement.innerHTML = `${new_locations_current_page-1}` + paginationElement.append(lastElement) + } + // current + if(new_locations_current_page!=1 && new_locations_current_page != new_locations_end_page){ + let currentElement = document.createElement('li') + currentElement.innerHTML = `
  • ${new_locations_current_page}
  • ` + paginationElement.append(currentElement) + } + // next + if(new_locations_current_page+2${new_locations_current_page+1}` + paginationElement.append(nextElement) + } + // ... + if(new_locations_current_page+2<=new_locations_end_page){ + let secondDotElement = document.createElement('li') + secondDotElement.classList.add('uk-disabled') + secondDotElement.innerHTML = ``; + paginationElement.append(secondDotElement) + } + //end + let endElement = document.createElement('li') + if(new_locations_current_page>=new_locations_end_page){ + endElement.innerHTML = `${new_locations_end_page}`; + endElement.classList.add('uk-disabled'); + }else { + endElement.innerHTML = `${new_locations_end_page}`; + } + paginationElement.append(endElement) + //next button + let nextElement = document.createElement('li') + if(new_locations_current_page>=new_locations_end_page){ + nextElement.innerHTML = ``; + nextElement.classList.add('uk-disabled'); + }else { + nextElement.innerHTML = ``; + } + paginationElement.append(nextElement) +} \ No newline at end of file diff --git a/application/items/templates/itemEdit.html b/application/items/templates/itemEdit.html new file mode 100644 index 0000000..87e253b --- /dev/null +++ b/application/items/templates/itemEdit.html @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + {% if session['user']['user_flags']['darkmode'] %} + + {% endif %} + + + + + + + + {% if session['user']['user_flags']['darkmode'] %} + + {% else %} + + {% endif %} + +
    +
    +
    +
    +

    The following information can be edited for the selected item. While editing your changes are not saved, you MUST press the save button in order + for the changes to be saved. +

    +
    +
    + + +
    +
    +

    Item UUID: {{item['item_uuid']}}

    +
    +
    +

    Created At: {{item['item_created_at']}}

    +
    +
    +

    Last Updated: {{item['item_updated_at']}}

    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/application/items/templates/item_new.html b/application/items/templates/item_new.html index d0a1beb..6506bb1 100644 --- a/application/items/templates/item_new.html +++ b/application/items/templates/item_new.html @@ -153,12 +153,18 @@
    Item Type - + {% for type in item_types %} + + {% endfor %}
    Item Subtype - + {% for type in item_subtypes %} + + {% endfor %}
    @@ -166,8 +172,9 @@
    - +
    +

    Tags are currently hidden on smaller screens for development reasons...

    @@ -176,13 +183,13 @@ Tags - + - + @@ -790,6 +797,6 @@ - + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..409ed51 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +flask +flask_assets +authlib +psycopg2 +pywebpush +pymupdf +openfoodfacts +flasgger \ No newline at end of file