home.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. const axios = require("axios");
  2. const bcrypt = require("bcryptjs");
  3. const Merchant = require("../models/merchant");
  4. const Ingredient = require("../models/ingredient");
  5. const Recipe = require("../models/recipe");
  6. const token = "b48068eb-411a-918e-ea64-52007147e42c";
  7. module.exports = {
  8. landingPage: function(req, res){
  9. return res.render("landingPage/landing");
  10. },
  11. displayInventory: function(req, res){
  12. if(!req.session.user){
  13. return res.redirect("/");
  14. }
  15. Merchant.findOne({_id: req.session.user})
  16. .populate("inventory.ingredient")
  17. .populate("recipes")
  18. .then((merchant)=>{
  19. if(merchant.pos === "clover"){
  20. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${merchant.posId}/orders?filter=clientCreatedTime>=${merchant.lastUpdatedTime}&expand=lineItems&access_token=${token}`)
  21. .then((result)=>{
  22. for(let order of result.data.elements){
  23. for(let item of order.lineItems.elements){
  24. let recipe = merchant.recipes.find(r => r.posId === item.item.id);
  25. if(recipe){
  26. for(let ingredient of recipe.ingredients){
  27. let inventoryIngredient = {};
  28. for(let invItem of merchant.inventory){
  29. if(invItem.ingredient._id.toString() === ingredient.ingredient.toString()){
  30. inventoryIngredient = invItem;
  31. }
  32. }
  33. inventoryIngredient.quantity -= ingredient.quantity;
  34. }
  35. }
  36. }
  37. }
  38. merchant.lastUpdatedTime = Date.now();
  39. merchant.save()
  40. .then((updatedMerchant)=>{
  41. return res.render("inventoryPage/inventory", {merchant: updatedMerchant});
  42. })
  43. .catch((err)=>{
  44. console.log(err);
  45. return res.render("error");
  46. });
  47. })
  48. .catch((err)=>{
  49. console.log(err);
  50. });
  51. }else if(merchant.pos === "none"){
  52. return res.render("inventoryPage/inventory", {merchant: merchant})
  53. }else{
  54. return res.redirect("/");
  55. }
  56. })
  57. .catch((err)=>{
  58. console.log(err);
  59. return res.render("error");
  60. });
  61. },
  62. //Display page to set up new merchant with Clover POS
  63. //TODO: This is for development, needs updating for production
  64. merchantSetupClover: function(req, res){
  65. req.session.posId = "YHVPCQMVB1P81";
  66. Ingredient.find()
  67. .then((ingredients)=>{
  68. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${req.session.posId}/items?access_token=${token}`)
  69. .then((recipes)=>{
  70. return res.render("merchantSetupPage/merchantSetup", {ingredients: ingredients, recipes: recipes.data});
  71. })
  72. .catch((err)=>{
  73. console.log(err);
  74. return res.render("error");
  75. });
  76. })
  77. .catch((err)=>{
  78. console.log(err);
  79. return res.render("error");
  80. });
  81. },
  82. //Display page to set up merchant with no POS system
  83. merchantSetupNone: function(req, res){
  84. Ingredient.find()
  85. .then((ingredients)=>{
  86. return res.render("merchantSetupPage/merchantSetup", {ingredients: ingredients, recipes: null});
  87. })
  88. .catch((err)=>{
  89. console.log(err);
  90. return res.render("error");
  91. });
  92. },
  93. displayRecipes: function(req, res){
  94. if(!req.session.user){
  95. return res.render("error");
  96. }
  97. Merchant.findOne({_id: req.session.user})
  98. .populate({
  99. path: "recipes",
  100. model: "Recipe",
  101. populate: {
  102. path: "ingredients.ingredient",
  103. model: "Ingredient"
  104. }
  105. })
  106. .populate("inventory.ingredient")
  107. .then((merchant)=>{
  108. return res.render("recipesPage/recipes", {merchant: merchant});
  109. })
  110. .catch((err)=>{
  111. console.log(err);
  112. return res.render("error");
  113. });
  114. },
  115. updateRecipes: function(req, res){
  116. if(!req.session.user){
  117. return res.render("error");
  118. }
  119. Merchant.findOne({_id: req.session.user})
  120. .populate("recipes")
  121. .then((merchant)=>{
  122. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${merchantId}/items?access_token=${token}`)
  123. .then((result)=>{
  124. let deletedRecipes = merchant.recipes.slice();
  125. for(let i = 0; i < result.data.elements.length; i++){
  126. for(let j = 0; j < deletedRecipes.length; j++){
  127. if(result.data.elements[i].id === deletedRecipes[j].posId){
  128. result.data.elements.splice(i, 1);
  129. deletedRecipes.splice(j, 1);
  130. i--;
  131. break;
  132. }
  133. }
  134. }
  135. for(let recipe of deletedRecipes){
  136. for(let i = 0; i < merchant.recipes.length; i++){
  137. if(recipe._id === merchant.recipes[i]._id){
  138. merchant.recipes.splice(i, 1);
  139. break;
  140. }
  141. }
  142. }
  143. let newRecipes = []
  144. for(let recipe of result.data.elements){
  145. let newRecipe = new Recipe({
  146. posId: recipe.id,
  147. merchant: merchant._id,
  148. name: recipe.name,
  149. ingredients: []
  150. });
  151. merchant.recipes.push(newRecipe);
  152. newRecipes.push(newRecipe);
  153. }
  154. Recipe.create(newRecipes)
  155. .catch((err)=>{
  156. console.log(err);
  157. return res.render("error");
  158. });
  159. merchant.save()
  160. .then((newMerchant)=>{
  161. newMerchant.populate("recipes.ingredients.ingredient").execPopulate()
  162. .then((newestMerchant)=>{
  163. return res.json({merchant: newestMerchant, count: result.data.elements.length});
  164. })
  165. .catch((err)=>{
  166. console.log(err);
  167. return res.render("error");
  168. });
  169. })
  170. .catch((err)=>{
  171. console.log(err);
  172. return res.render("error");
  173. });
  174. })
  175. .catch((err)=>{
  176. console.log(err);
  177. return res.render("error");
  178. });
  179. })
  180. .catch((err)=>{
  181. console.log(err);
  182. return res.render("error");
  183. });
  184. },
  185. createMerchantClover: function(req, res){
  186. let data = JSON.parse(req.body.data);
  187. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${req.session.posId}?access_token=${token}`)
  188. .then((cloverMerchant)=>{
  189. req.session.posId = undefined;
  190. let salt = bcrypt.genSaltSync(10);
  191. let hash = bcrypt.hashSync(data.password, salt);
  192. let merchant = new Merchant({
  193. name: cloverMerchant.data.name,
  194. email: data.email,
  195. password: hash,
  196. pos: "clover",
  197. posId: cloverMerchant.data.id
  198. });
  199. for(let item of data.inventory){
  200. merchant.inventory.push({
  201. ingredient: item.ingredient.id,
  202. quantity: item.quantity
  203. });
  204. }
  205. for(let recipe of data.recipes){
  206. recipe.merchant = merchant._id;
  207. }
  208. Recipe.create(data.recipes)
  209. .then((recipes)=>{
  210. for(let recipe of recipes){
  211. merchant.recipes.push(recipe._id);
  212. }
  213. merchant.save()
  214. .then((merchant)=>{
  215. req.session.user = merchant._id;
  216. return res.redirect("/inventory");
  217. })
  218. .catch((err)=>{
  219. console.log(err);
  220. return res.render("error");
  221. });
  222. })
  223. .catch((err)=>{
  224. console.log(err);
  225. return res.render("error");
  226. });
  227. Recipe.create(newRecipes)
  228. .then((recipes)=>{
  229. for(let recipe of recipes){
  230. newMerchant.recipes.push(recipe);
  231. }
  232. newMerchant.save()
  233. .then((merchant)=>{
  234. return res.redirect("/inventory");
  235. })
  236. .catch((err)=>{
  237. console.log(err);
  238. return res.render("error");
  239. });
  240. })
  241. .catch((err)=>{
  242. console.log(err);
  243. return res.render("error");
  244. });
  245. })
  246. .catch((err)=>{
  247. console.log(err);
  248. });
  249. },
  250. createMerchantNone: function(req, res){
  251. let data = JSON.parse(req.body.data);
  252. let salt = bcrypt.genSaltSync(10);
  253. let hash = bcrypt.hashSync(data.password, salt);
  254. let merchant = new Merchant({
  255. name: data.name,
  256. email: data.email,
  257. password: hash,
  258. pos: "none"
  259. });
  260. for(let item of data.inventory){
  261. merchant.inventory.push({
  262. ingredient: item.ingredient.id,
  263. quantity: item.quantity
  264. });
  265. }
  266. for(let recipe of data.recipes){
  267. recipe.merchant = merchant._id;
  268. }
  269. Recipe.create(data.recipes)
  270. .then((recipes)=>{
  271. for(let recipe of recipes){
  272. merchant.recipes.push(recipe._id);
  273. }
  274. merchant.save()
  275. .then((merchant)=>{
  276. req.session.user = merchant._id;
  277. return res.redirect("/inventory");
  278. })
  279. .catch((err)=>{
  280. console.log(err);
  281. return res.render("error");
  282. });
  283. })
  284. .catch((err)=>{
  285. console.log(err);
  286. return res.render("error");
  287. });
  288. },
  289. addMerchantIngredient: function(req, res){
  290. if(!req.session.user){
  291. return res.render("error");
  292. }
  293. Merchant.findOne({_id: req.session.user})
  294. .then((merchant)=>{
  295. merchant.inventory.push(req.body);
  296. merchant.save()
  297. .then((newMerchant)=>{
  298. Ingredient.findOne({_id: req.body.ingredient})
  299. .then((ingredient)=>{
  300. return res.json(ingredient);
  301. })
  302. .catch((err)=>{
  303. console.log(err);
  304. return res.render("error");
  305. });
  306. })
  307. .catch((err)=>{
  308. console.log(err);
  309. return res.render("error");
  310. });
  311. })
  312. .catch((err)=>{
  313. console.log(err);
  314. return res.render("error");
  315. });
  316. },
  317. removeMerchantIngredient: function(req, res){
  318. if(!req.session.user){
  319. return res.render("error");
  320. }
  321. Merchant.findOne({_id: req.session.user})
  322. .then((merchant)=>{
  323. for(let i = 0; i < merchant.inventory.length; i++){
  324. if(req.body.ingredientId === merchant.inventory[i]._id.toString()){
  325. merchant.inventory.splice(i, 1);
  326. break;
  327. }
  328. }
  329. merchant.save()
  330. .then(()=>{
  331. return res.json();
  332. })
  333. .catch((err)=>{
  334. console.log(err);
  335. return res.render("error");
  336. });
  337. })
  338. .catch((err)=>{
  339. console.log(err);
  340. return res.render("error");
  341. });
  342. },
  343. updateMerchantIngredient: function(req, res){
  344. if(!req.session.user){
  345. return res.render("error");
  346. }
  347. Merchant.findOne({_id: req.session.user})
  348. .then((merchant)=>{
  349. let updateIngredient = merchant.inventory.find(i => i._id.toString() === req.body.ingredientId);
  350. updateIngredient.quantity = req.body.quantity;
  351. merchant.save()
  352. .then((merchant)=>{
  353. return res.json();
  354. })
  355. .catch((err)=>{
  356. console.log(err);
  357. return res.render("error");
  358. })
  359. })
  360. .catch((err)=>{
  361. console.log(err);
  362. return res.render("error");
  363. });
  364. },
  365. addRecipeIngredient: function(req, res){
  366. if(!req.session.user){
  367. return res.render("error");
  368. }
  369. Recipe.findOne({_id: req.body.recipeId})
  370. .then((recipe)=>{
  371. recipe.ingredients.push({
  372. ingredient: req.body.item.ingredient,
  373. quantity: req.body.item.quantity
  374. });
  375. recipe.save()
  376. .then((recipe)=>{
  377. return res.json();
  378. })
  379. .catch((err)=>{
  380. console.log(err);
  381. return res.render("error");
  382. });
  383. })
  384. .catch((err)=>{
  385. console.log(err);
  386. return res.render("error");
  387. });
  388. },
  389. updateRecipeIngredient: function(req, res){
  390. if(!req.session.user){
  391. return res.render("error");
  392. }
  393. Recipe.findOne({_id: req.body.recipeId})
  394. .then((recipe)=>{
  395. for(let ingredient of recipe.ingredients){
  396. if(ingredient._id.toString() === req.body.ingredient._id){
  397. ingredient.quantity = req.body.ingredient.quantity;
  398. recipe.save()
  399. .then((recipe)=>{
  400. return res.json();
  401. })
  402. .catch((err)=>{
  403. console.log(err);
  404. return res.render("error");
  405. })
  406. }
  407. }
  408. })
  409. .catch((err)=>{
  410. console.log(err);
  411. return res.render("error");
  412. });
  413. },
  414. removeRecipeIngredient: function(req, res){
  415. if(!req.session.user){
  416. return res.render("error");
  417. }
  418. Recipe.findOne({_id: req.body.recipeId})
  419. .then((recipe)=>{
  420. for(let i = 0; i < recipe.ingredients.length; i++){
  421. if(recipe.ingredients[i]._id.toString() === req.body.ingredientId){
  422. recipe.ingredients.splice(i, 1);
  423. }
  424. }
  425. recipe.save()
  426. .then((recipe)=>{
  427. return res.json();
  428. })
  429. .catch((err)=>{
  430. console.log(err);
  431. return res.render("error");
  432. });
  433. })
  434. .catch((err)=>{
  435. console.log(err);
  436. return res.render("error");
  437. });
  438. },
  439. getIngredients: function(req, res){
  440. Ingredient.find()
  441. .then((ingredients)=>{
  442. return res.json(ingredients);
  443. })
  444. .catch((err)=>{
  445. console.log(err);
  446. return res.render("error");
  447. });
  448. },
  449. createNewIngredients: function(req, res){
  450. Ingredient.create(req.body)
  451. .then((ingredients)=>{
  452. return res.json(ingredients);
  453. })
  454. .catch((err)=>{
  455. console.log(err);
  456. return res.render("error");
  457. });
  458. },
  459. createIngredient: function(req, res){
  460. Ingredient.create(req.body.ingredient)
  461. .then((ingredient)=>{
  462. Merchant.findOne({_id: req.session.user})
  463. .then((merchant)=>{
  464. let item = {
  465. ingredient: ingredient,
  466. quantity: req.body.quantity
  467. }
  468. merchant.inventory.push(item);
  469. merchant.save()
  470. .then((merchant)=>{
  471. console.log("something");
  472. return res.json(item);
  473. })
  474. .catch((err)=>{
  475. console.log(err);
  476. return res.render("error");
  477. });
  478. })
  479. .catch((err)=>{
  480. console.log(err);
  481. return res.render("error");
  482. });
  483. })
  484. .catch((err)=>{
  485. console.log(err);
  486. return res.render("error");
  487. });
  488. },
  489. getCloverRecipes: function(req, res){
  490. if(!req.session.user){
  491. return res.render("error");
  492. }
  493. Merchant.findOne({_id: req.session.user})
  494. .then((merchant)=>{
  495. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${merchant.posId}/items?access_token=${token}`)
  496. .then((recipes)=>{
  497. return res.json(recipes);
  498. })
  499. .catch((err)=>{
  500. return res.json(err);
  501. });
  502. })
  503. .catch((err)=>{
  504. console.log(err);
  505. return res.render("error");
  506. });
  507. },
  508. unregistered: function(req, res){
  509. return res.redirect("/");
  510. },
  511. login: function(req, res){
  512. Merchant.findOne({email: req.body.email})
  513. .then((merchant)=>{
  514. bcrypt.compare(req.body.password, merchant.password, (err, result)=>{
  515. if(result){
  516. req.session.user = merchant._id;
  517. return res.redirect("/inventory");
  518. }
  519. console.log(err);
  520. return res.redirect("/");
  521. });
  522. })
  523. .catch((err)=>{
  524. console.log(err);
  525. return res.redirect("/");
  526. });
  527. }
  528. }