home.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. let home = {
  2. isPopulated: false,
  3. graph: {},
  4. display: function(){
  5. if(!this.isPopulated){
  6. this.drawRevenueCard();
  7. this.drawRevenueGraph();
  8. this.drawInventoryCheckCard();
  9. this.drawPopularCard();
  10. this.isPopulated = true;
  11. }
  12. },
  13. drawRevenueCard: function(){
  14. let today = new Date();
  15. let firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
  16. let firstOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
  17. let lastMonthToDay = new Date(new Date().setMonth(today.getMonth() - 1));
  18. let revenueThisMonth = merchant.revenue(controller.transactionIndices(merchant.transactions, firstOfMonth));
  19. let revenueLastmonthToDay = merchant.revenue(controller.transactionIndices(merchant.transactions, firstOfLastMonth, lastMonthToDay));
  20. document.getElementById("revenue").innerText = `$${revenueThisMonth.toLocaleString("en")}`;
  21. let revenueChange = ((revenueThisMonth - revenueLastmonthToDay) / revenueLastmonthToDay) * 100;
  22. let img = "";
  23. if(revenueChange >= 0){
  24. img = "/shared/images/upArrow.png";
  25. }else{
  26. img = "/shared/images/downArrow.png";
  27. }
  28. document.querySelector("#revenueChange p").innerText = `${Math.abs(revenueChange).toFixed(2)}% vs last month`;
  29. document.querySelector("#revenueChange img").src = img;
  30. },
  31. drawRevenueGraph: function(){
  32. let monthAgo = new Date();
  33. monthAgo.setMonth(monthAgo.getMonth() - 1);
  34. let dateIndices = controller.transactionIndices(merchant.transactions, monthAgo);
  35. let revenue = [];
  36. let dates = [];
  37. let dayRevenue = 0;
  38. let currentDate = merchant.transactions[dateIndices[0]].date;
  39. for(let i = dateIndices[0]; i < dateIndices[1]; i++){
  40. if(merchant.transactions[i].date.getDate() !== currentDate.getDate()){
  41. revenue.push(dayRevenue / 100);
  42. dayRevenue = 0;
  43. dates.push(currentDate);
  44. currentDate = merchant.transactions[i].date;
  45. }
  46. for(let j = 0; j < merchant.transactions[i].recipes.length; j++){
  47. const recipe = merchant.transactions[i].recipes[j];
  48. dayRevenue += recipe.recipe.price * recipe.quantity;
  49. }
  50. }
  51. const trace = {
  52. x: dates,
  53. y: revenue,
  54. mode: "lines+markers"
  55. }
  56. const layout = {
  57. title: "REVENUE",
  58. xaxis: {
  59. title: "DATE"
  60. },
  61. yaxis: {
  62. title: "$"
  63. }
  64. }
  65. Plotly.newPlot("graphCard", [trace], layout);
  66. },
  67. drawInventoryCheckCard: function(){
  68. let num;
  69. if(merchant.ingredients.length < 5){
  70. num = merchant.ingredients.length;
  71. }else{
  72. num = 5;
  73. }
  74. let rands = [];
  75. for(let i = 0; i < num; i++){
  76. let rand = Math.floor(Math.random() * merchant.ingredients.length);
  77. if(rands.includes(rand)){
  78. i--;
  79. }else{
  80. rands[i] = rand;
  81. }
  82. }
  83. let ul = document.querySelector("#inventoryCheckCard ul");
  84. let template = document.getElementById("ingredientCheck").content.children[0];
  85. while(ul.children.length > 0){
  86. ul.removeChild(ul.firstChild);
  87. }
  88. for(let i = 0; i < rands.length; i++){
  89. let ingredientCheck = template.cloneNode(true);
  90. let input = ingredientCheck.children[1].children[1];
  91. const ingredient = merchant.ingredients[rands[i]];
  92. ingredientCheck.ingredient = ingredient;
  93. ingredientCheck.children[0].innerText = ingredient.ingredient.name;
  94. ingredientCheck.children[1].children[0].onclick = ()=>{input.value--};
  95. input.value = ingredient.ingredient.convert(ingredient.quantity).toFixed(2);
  96. ingredientCheck.children[1].children[2].onclick = ()=>{input.value++}
  97. ingredientCheck.children[2].innerText = ingredient.ingredient.unit.toUpperCase();
  98. ul.appendChild(ingredientCheck);
  99. }
  100. document.getElementById("inventoryCheck").onclick = ()=>{this.submitInventoryCheck()};
  101. },
  102. drawPopularCard: function(){
  103. let dataArray = [];
  104. let now = new Date();
  105. let thisMonth = new Date(now.getFullYear(), now.getMonth(), 1);
  106. let ingredientList = merchant.ingredientsSold(controller.transactionIndices(merchant.transactions, thisMonth));
  107. if(ingredientList !== false){
  108. window.ingredientList = [...ingredientList];
  109. let iterations = (ingredientList.length < 5) ? ingredientList.length : 5;
  110. for(let i = 0; i < iterations; i++){
  111. try{
  112. let max = ingredientList[0].quantity;
  113. let index = 0;
  114. for(let j = 0; j < ingredientList.length; j++){
  115. if(ingredientList[j].quantity > max){
  116. max = ingredientList[j].quantity;
  117. index = j;
  118. }
  119. }
  120. dataArray.push({
  121. num: max,
  122. label: ingredientList[index].ingredient.name + ": " +
  123. ingredientList[index].ingredient.convert(ingredientList[index].quantity).toFixed(2) +
  124. " " + ingredientList[index].ingredient.unit
  125. });
  126. ingredientList.splice(index, 1);
  127. }catch(err){
  128. break;
  129. }
  130. }
  131. let thisCanvas = document.getElementById("popularCanvas");
  132. thisCanvas.width = thisCanvas.parentElement.offsetWidth * 0.8;
  133. thisCanvas.height = thisCanvas.parentElement.offsetHeight * 0.8;
  134. let HorizontalBarGraph = require("../../shared/graphs.js").HorizontalBarGraph;
  135. let popularGraph = new HorizontalBarGraph(thisCanvas);
  136. popularGraph.addData(dataArray);
  137. }else{
  138. document.getElementById("popularCanvas").style.display = "none";
  139. let notice = document.createElement("p");
  140. notice.innerText = "N/A";
  141. notice.classList = "notice";
  142. document.getElementById("popularIngredientsCard").appendChild(notice);
  143. }
  144. },
  145. submitInventoryCheck: function(){
  146. let lis = document.querySelectorAll("#inventoryCheckCard li");
  147. let changes = [];
  148. let fetchData = [];
  149. for(let i = 0; i < lis.length; i++){
  150. if(lis[i].children[1].children[1].value >= 0){
  151. let merchIngredient = lis[i].ingredient;
  152. let value = parseFloat(lis[i].children[1].children[1].value);
  153. if(value !== merchIngredient.quantity){
  154. changes.push({
  155. id: merchIngredient.ingredient.id,
  156. ingredient: merchIngredient.ingredient,
  157. quantity: value
  158. });
  159. fetchData.push({
  160. id: merchIngredient.ingredient.id,
  161. quantity: value
  162. });
  163. }
  164. }else{
  165. banner.createError("CANNOT HAVE NEGATIVE INGREDIENTS");
  166. return;
  167. }
  168. }
  169. let loader = document.getElementById("loaderContainer");
  170. loader.style.display = "flex";
  171. if(fetchData.length > 0){
  172. fetch("/merchant/ingredients/update", {
  173. method: "PUT",
  174. headers: {
  175. "Content-Type": "application/json;charset=utf-8"
  176. },
  177. body: JSON.stringify(fetchData)
  178. })
  179. .then((response) => response.json())
  180. .then((response)=>{
  181. if(typeof(response) === "string"){
  182. banner.createError(response);
  183. }else{
  184. merchant.editIngredients(changes);
  185. banner.createNotification("INGREDIENTS UPDATED");
  186. }
  187. })
  188. .catch((err)=>{})
  189. .finally(()=>{
  190. loader.style.display = "none";
  191. });
  192. }
  193. }
  194. }
  195. module.exports = home;