renderer.js 7.9 KB

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