renderer.js 9.1 KB

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