controller.js 13 KB

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