controller.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. Switches to a different strand
  3. Input:
  4. name: name of the strand. Must end with "Strand"
  5. */
  6. let changeStrand = (name)=>{
  7. closeSidebar();
  8. for(let strand of document.querySelectorAll(".strand")){
  9. strand.style.display = "none";
  10. }
  11. for(let button of document.querySelectorAll(".menu > button")){
  12. button.classList = "";
  13. button.onclick = ()=>{changeStrand(`${button.id.slice(0, button.id.indexOf("Btn"))}Strand`)};
  14. }
  15. let activeButton = document.querySelector(`#${name.slice(0, name.indexOf("Strand"))}Btn`);
  16. activeButton.classList = "active";
  17. activeButton.onclick = undefined;
  18. document.querySelector(`#${name}`).style.display = "flex";
  19. window[`${name}Obj`].display();
  20. }
  21. /*
  22. Updates all specified item in the merchant's inventory and updates the page
  23. If ingredient doesn't exist, add it
  24. Inputs:
  25. Array of objects
  26. id: id of ingredient
  27. quantityChange: change in quantity (if not removing)
  28. name: name of ingredient (only for new ingredient)
  29. category: category of ingredient (only for new ingredient)
  30. unit: unit of measurement (only for new ingredient)
  31. remove: if true, remove ingredient from inventory
  32. */
  33. let updateInventory = (ingredients, remove = false)=>{
  34. for(let i = 0; i < ingredients.length; i++){
  35. let isNew = true;
  36. for(let j = 0; j < merchant.inventory.length; j++){
  37. if(merchant.inventory[j].ingredient._id === ingredients[i].id){
  38. if(remove){
  39. merchant.inventory.splice(j, 1);
  40. }else{
  41. merchant.inventory[j].quantity += ingredients[i].quantity;
  42. }
  43. isNew = false;
  44. break;
  45. }
  46. }
  47. if(isNew){
  48. merchant.inventory.push(ingredients[i]);
  49. }
  50. }
  51. console.log("updating");
  52. homeStrandObj.drawInventoryCheckCard();
  53. console.log("still updating?");
  54. ingredientsStrandObj.populateByProperty("category");
  55. addIngredientsComp.isPopulated = false;
  56. closeSidebar();
  57. }
  58. /*
  59. Updates a recipe in the merchants list of recipes
  60. Can create, edit or remove
  61. Inputs:
  62. recipe: object
  63. _id: id of recipe
  64. name: name of recipe
  65. price: price of recipe
  66. ingredients: list of ingredients
  67. ingredient: id of ingredient
  68. quantity: quantity of ingredient
  69. remove: if true, remove ingredient from inventory
  70. */
  71. let updateRecipes = (recipe, remove = false)=>{
  72. let isNew = true;
  73. let index = 0;
  74. for(let i = 0; i < recipe.ingredients.length; i++){
  75. for(let j = 0; j < merchant.inventory.length; j++){
  76. if(merchant.inventory[j].ingredient._id === recipe.ingredients[i].ingredient){
  77. recipe.ingredients[i].ingredient = merchant.inventory[j].ingredient;
  78. break;
  79. }
  80. }
  81. }
  82. for(let i = 0; i < merchant.recipes.length; i++){
  83. if(recipe._id === merchant.recipes[i]._id){
  84. if(remove){
  85. merchant.recipes.splice(i, 1);
  86. }else{
  87. merchant.recipes[i] = recipe;
  88. index = i;
  89. }
  90. isNew = false;
  91. break;
  92. }
  93. }
  94. if(isNew){
  95. merchant.recipes.push(recipe);
  96. index = merchant.recipes.length - 1;
  97. }
  98. recipeBookStrandObj.populateRecipes();
  99. closeSidebar();
  100. }
  101. /*
  102. Updates an order in the front end
  103. Can create, edit or remove
  104. Inputs:
  105. recipe: object
  106. _id: id of recipe
  107. name: name of recipe
  108. price: price of recipe
  109. ingredients: list of ingredients
  110. ingredient: id of ingredient
  111. quantity: quantity of ingredient
  112. remove: if true, remove ingredient from inventory
  113. */
  114. let updateOrders = (order, remove = false)=>{
  115. let isNew = true;
  116. for(let i = 0; i < orders.length; i++){
  117. if(orders[i]._id === order._id){
  118. if(remove){
  119. orders.splice(i, 1);
  120. }else{
  121. orders[i] = order;
  122. }
  123. isNew = false;
  124. }
  125. }
  126. if(isNew){
  127. orders.push(order);
  128. }
  129. ordersStrandObj.isPopulated = false;
  130. ordersStrandObj.display();
  131. }
  132. //Close any open sidebar
  133. let closeSidebar = ()=>{
  134. let sidebar = document.querySelector("#sidebarDiv");
  135. for(let i = 0; i < sidebar.children.length; i++){
  136. sidebar.children[i].style.display = "none";
  137. }
  138. sidebar.classList = "sidebarHide";
  139. }
  140. /*
  141. Open a specific sidebar
  142. Input:
  143. sidebar: the outermost element of the sidebar (must contain class sidebar)
  144. */
  145. let openSidebar = (sidebar)=>{
  146. document.querySelector("#sidebarDiv").classList = "sidebar";
  147. let sideBars = document.querySelector("#sidebarDiv").children;
  148. for(let i = 0; i < sideBars.length; i++){
  149. sideBars[i].style.display = "none";
  150. }
  151. sidebar.style.display = "flex";
  152. }
  153. /*
  154. Gets the indices of two dates from transactions
  155. Inputs
  156. from: starting date
  157. to: ending date (default to now)
  158. Output
  159. Array containing starting index and ending index
  160. Note: Will return false if it cannot find both necessary dates
  161. */
  162. let dateIndices = (from, to = new Date())=>{
  163. let indices = [];
  164. for(let i = 0; i < transactions.length; i++){
  165. if(transactions[i].date > from){
  166. indices.push(i);
  167. break;
  168. }
  169. }
  170. for(let i = transactions.length - 1; i >=0; i--){
  171. if(transactions[i].date < to){
  172. indices.push(i);
  173. break;
  174. }
  175. }
  176. if(indices.length < 2){
  177. return false;
  178. }
  179. return indices;
  180. }
  181. /*
  182. Gets the quantity of each ingredient sold between two dates (dateRange)
  183. Inputs
  184. dateRange: list containing a start date and an end date
  185. Output
  186. List of objects
  187. id: id of specific ingredient
  188. quantity: quantity sold of that ingredient
  189. name: name of the ingredient
  190. */
  191. let ingredientsSold = (dateRange)=>{
  192. if(!dateRange){
  193. return false;
  194. }
  195. let recipes = recipesSold(dateRange);
  196. let ingredientList = [];
  197. for(let i = 0; i < recipes.length; i++){
  198. for(let j = 0; j < merchant.recipes.length; j++){
  199. for(let k = 0; k < merchant.recipes[j].ingredients.length; k++){
  200. let exists = false;
  201. for(let l = 0; l < ingredientList.length; l++){
  202. if(ingredientList[l].id === merchant.recipes[j].ingredients[k].ingredient._id){
  203. exists = true;
  204. ingredientList[l].quantity += merchant.recipes[j].ingredients[k].quantity * recipes[i].quantity;
  205. break;
  206. }
  207. }
  208. if(!exists){
  209. ingredientList.push({
  210. id: merchant.recipes[j].ingredients[k].ingredient._id,
  211. quantity: merchant.recipes[j].ingredients[k].quantity * recipes[i].quantity,
  212. name: merchant.recipes[j].ingredients[k].ingredient.name,
  213. unit: merchant.recipes[j].ingredients[k].ingredient.unit
  214. })
  215. }
  216. }
  217. }
  218. }
  219. return ingredientList;
  220. }
  221. /*
  222. Gets the quantity of a single ingredient sold between two dates (dateRange)
  223. Input:
  224. dateRange: array containing two elements, start and end indices
  225. id: id of the ingredient to calculate
  226. Return: (int) Quantity of recipes sold
  227. */
  228. let ingredientSold = (dateRange, id)=>{
  229. let recipes = recipesSold(dateRange);
  230. let total = 0;
  231. let checkRecipes = [];
  232. let quantities = [];
  233. for(let i = 0; i < merchant.recipes.length; i++){
  234. for(let j = 0; j < merchant.recipes[i].ingredients.length; j++){
  235. if(merchant.recipes[i].ingredients[j].ingredient._id === id){
  236. checkRecipes.push(merchant.recipes[i]._id);
  237. quantities.push(merchant.recipes[i].ingredients[j].quantity);
  238. break;
  239. }
  240. }
  241. }
  242. for(let i = 0; i < recipes.length; i++){
  243. for(let i = 0; i < checkRecipes.length; i++){
  244. if(checkRecipes[i] === recipes[i].id){
  245. total += recipes[i].quantity * quantities[i];
  246. break;
  247. }
  248. }
  249. }
  250. return total;
  251. }
  252. /*
  253. Gets the number of recipes sold between two dates (dateRange)
  254. Inputs:
  255. dateRange: array containing a start date and an end date
  256. Return:
  257. List of objects
  258. id: id of specific recipe
  259. quantity: quantity sold of that recipe
  260. */
  261. let recipesSold = (dateRange)=>{
  262. let recipeList = [];
  263. for(let i = dateRange[0]; i <= dateRange[1]; i++){
  264. for(let j = 0; j < transactions[i].recipes.length; j++){
  265. let exists = false;
  266. for(let k = 0; k < recipeList.length; k++){
  267. if(recipeList[k].id === transactions[i].recipes[j].recipe){
  268. exists = true;
  269. recipeList[k].quantity += transactions[i].recipes[j].quantity;
  270. break;
  271. }
  272. }
  273. if(!exists){
  274. recipeList.push({
  275. id: transactions[i].recipes[j].recipe,
  276. quantity: transactions[i].recipes[j].quantity
  277. })
  278. }
  279. }
  280. }
  281. return recipeList;
  282. }
  283. /*
  284. Groups all of the merchant's ingredients by their category
  285. Return:
  286. Array of objects
  287. name: Category name
  288. ingredients: Array of objects
  289. id: Id of ingredient
  290. name: Name of ingredient
  291. quantity: Merchant's quantity of this ingredient
  292. unit: Measurement unit
  293. */
  294. let categorizeIngredients = (ingredients)=>{
  295. let ingredientsByCategory = [];
  296. for(let i = 0; i < ingredients.length; i++){
  297. let categoryExists = false;
  298. for(let j = 0; j < ingredientsByCategory.length; j++){
  299. if(ingredients[i].ingredient.category === ingredientsByCategory[j].name){
  300. ingredientsByCategory[j].ingredients.push({
  301. id: ingredients[i].ingredient._id,
  302. name: ingredients[i].ingredient.name,
  303. quantity: ingredients[i].quantity,
  304. unit: ingredients[i].ingredient.unit
  305. });
  306. categoryExists = true;
  307. break;
  308. }
  309. }
  310. if(!categoryExists){
  311. ingredientsByCategory.push({
  312. name: ingredients[i].ingredient.category,
  313. ingredients: [{
  314. id: ingredients[i].ingredient._id,
  315. name: ingredients[i].ingredient.name,
  316. quantity: ingredients[i].quantity,
  317. unit: ingredients[i].ingredient.unit
  318. }]
  319. });
  320. }
  321. }
  322. return ingredientsByCategory;
  323. }
  324. let unitizeIngredients = (ingredients)=>{
  325. let ingredientsByUnit = [];
  326. for(let i = 0; i < ingredients.length; i++){
  327. let unitExists = false;
  328. for(let j = 0; j < ingredientsByUnit.length; j++){
  329. if(ingredients[i].ingredient.unit === ingredientsByUnit[j].name){
  330. ingredientsByUnit[j].ingredients.push({
  331. id: ingredients[i].ingredient._id,
  332. name: ingredients[i].ingredient.name,
  333. quantity: ingredients[i].quantity,
  334. unit: ingredients[i].ingredient.unit
  335. });
  336. unitExists = true;
  337. break;
  338. }
  339. }
  340. if(!unitExists){
  341. ingredientsByUnit.push({
  342. name: ingredients[i].ingredient.unit,
  343. ingredients: [{
  344. id: ingredients[i].ingredient._id,
  345. name: ingredients[i].ingredient.name,
  346. quantity: ingredients[i].quantity,
  347. unit: ingredients[i].ingredient.unit
  348. }]
  349. })
  350. }
  351. }
  352. return ingredientsByUnit;
  353. }
  354. let categorizeIngredientsFromDB = (ingredients)=>{
  355. let ingredientsByCategory = [];
  356. for(let i = 0; i < ingredients.length; i++){
  357. let categoryExists = false;
  358. for(let j = 0; j < ingredientsByCategory.length; j++){
  359. if(ingredients[i].category === ingredientsByCategory[j].name){
  360. ingredientsByCategory[j].ingredients.push({
  361. id: ingredients[i]._id,
  362. name: ingredients[i].name,
  363. unit: ingredients[i].unit
  364. });
  365. categoryExists = true;
  366. break;
  367. }
  368. }
  369. if(!categoryExists){
  370. ingredientsByCategory.push({
  371. name: ingredients[i].category,
  372. ingredients: [{
  373. id: ingredients[i]._id,
  374. name: ingredients[i].name,
  375. unit: ingredients[i].unit
  376. }]
  377. });
  378. }
  379. }
  380. return ingredientsByCategory;
  381. }
  382. for(let transaction of transactions){
  383. transaction.date = new Date(transaction.date);
  384. }
  385. homeStrandObj.display();