renderer.js 9.3 KB

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