renderer.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. const axios = require("axios");
  2. const ObjectId = require("mongoose").Types.ObjectId;
  3. const Merchant = require("../models/merchant");
  4. const Transaction = require("../models/transaction");
  5. const transaction = require("../models/transaction");
  6. const ingredient = require("../models/ingredient");
  7. module.exports = {
  8. /*
  9. GET - Shows the public landing page
  10. Return = a single error message (only if there is an error)
  11. Renders landingPage
  12. */
  13. landingPage: function(req, res){
  14. let error = {};
  15. let isLoggedIn = req.session.isLoggedIn || false;
  16. if(req.session.error){
  17. error = req.session.error;
  18. req.session.error = undefined;
  19. }else{
  20. error = null;
  21. }
  22. return res.render("landingPage/landing", {error: error, isLoggedIn: isLoggedIn});
  23. },
  24. /*
  25. GET - Displays the main inventory page for merchants
  26. Returns = the logged in merchant and his/her data
  27. Renders inventoryPage
  28. */
  29. displayDashboard: function(req, res){
  30. if(!req.session.user){
  31. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  32. return res.redirect("/");
  33. }
  34. Merchant.findOne({_id: req.session.user}, {password: 0, createdAt: 0})
  35. .populate("inventory.ingredient")
  36. .populate("recipes")
  37. .then(async (merchant)=>{
  38. let promiseArray = [];
  39. if(merchant.pos === "clover"){
  40. const subscriptionCheck = axios.get(`${process.env.CLOVER_ADDRESS}/v3/apps/${process.env.SUBLINE_CLOVER_APPID}/merchants/${merchant.posId}/billing_info?access_token=${merchant.posAccessToken}`);
  41. const transactionRetrieval = axios.get(`${process.env.CLOVER_ADDRESS}/v3/merchants/${merchant.posId}/orders?filter=clientCreatedTime>=${merchant.lastUpdatedTime}&expand=lineItems&access_token=${merchant.posAccessToken}`);
  42. await Promise.all([subscriptionCheck, transactionRetrieval])
  43. .then((response)=>{
  44. if(response[0].data.status !== "ACTIVE"){
  45. req.session.error = "SUBSCRIPTION EXPIRED. PLEASE RENEW ON CLOVER";
  46. return res.redirect("/");
  47. }
  48. const updatedTime = Date.now();
  49. //Create Subline transactions from Clover Transactions
  50. let transactions = [];
  51. for(let i = 0; i < response[1].data.elements.length; i++){
  52. let order = response[1].data.elements[i];
  53. let newTransaction = new Transaction({
  54. merchant: merchant._id,
  55. date: new Date(order.createdTime),
  56. device: order.device.id
  57. });
  58. //Go through lineItems from Clover
  59. //Get the appropriate recipe from Subline
  60. //Add it to the transaction or increment if existing
  61. for(let j = 0; j < order.lineItems.elements.length; j++){
  62. let recipe = {}
  63. for(let k = 0; k < merchant.recipes.length; k++){
  64. if(merchant.recipes[k].posId === order.lineItems.elements[j].item.id){
  65. recipe = merchant.recipes[k];
  66. break;
  67. }
  68. }
  69. if(recipe){
  70. let isNewRecipe = true;
  71. for(let k = 0; k < newTransaction.recipes.length; k++){
  72. if(newTransaction.recipes[k].recipe === recipe._id){
  73. newTransaction.recipes[k].quantity++;
  74. isNewRecipe = false;
  75. break;
  76. }
  77. }
  78. if(isNewRecipe){
  79. newTransaction.recipes.push({
  80. recipe: recipe._id,
  81. quantity: 1
  82. });
  83. }
  84. //Subtract ingredients from merchants total for each ingredient in a recipe
  85. for(let k = 0; k < recipe.ingredients.length; k++){
  86. let inventoryIngredient = {};
  87. for(let l = 0; l < merchant.inventory.length; l++){
  88. if(merchant.inventory[l].ingredient._id.toString() === recipe.ingredients[k].ingredient._id.toString()){
  89. inventoryIngredient = merchant.inventory[l];
  90. break;
  91. }
  92. }
  93. inventoryIngredient.quantity = inventoryIngredient.quantity - ingredient.quantity;
  94. }
  95. }
  96. }
  97. transactions.push(newTransaction);
  98. }
  99. merchant.lastUpdatedTime = updatedTime;
  100. promiseArray.push(Transaction.create(transactions));
  101. })
  102. .catch((err)=>{
  103. req.session.error = "ERROR: UNABLE TO RETRIEVE DATA FROM CLOVER";
  104. return res.redirect("/");
  105. });
  106. }
  107. return Promise.all([merchant.save()].concat(promiseArray));
  108. })
  109. .then((response)=>{
  110. let date = new Date();
  111. let firstDay = new Date(date.getFullYear(), date.getMonth() - 1, 1);
  112. Transaction.aggregate([
  113. {$match: {
  114. merchant: new ObjectId(req.session.user),
  115. date: {$gte: firstDay},
  116. }},
  117. {$sort: {date: 1}},
  118. {$project: {
  119. date: 1,
  120. recipes: 1
  121. }}
  122. ])
  123. .then((transactions)=>{
  124. return res.render("dashboardPage/dashboard", {merchant: response[0], transactions: transactions})
  125. })
  126. .catch((err)=>{});
  127. })
  128. .catch((err)=>{
  129. req.session.error = "ERROR: UNABLE TO RETRIEVE USER DATA";
  130. return res.redirect("/");
  131. });
  132. },
  133. //GET - Renders the information page
  134. displayLegal: function(req, res){
  135. return res.render("informationPage/information");
  136. },
  137. //GET - Renders the page to reset your password
  138. displayPassReset: function(req, res){
  139. return res.render("passResetPage/passReset");
  140. }
  141. }