recipeData.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. const axios = require("axios");
  2. const Recipe = require("../models/recipe.js");
  3. const Merchant = require("../models/merchant.js");
  4. const RecipeChange = require("../models/recipeChange.js");
  5. const Validator = require("./validator.js");
  6. const merchant = require("../models/merchant.js");
  7. module.exports = {
  8. /*
  9. POST - creates a single new recipe
  10. req.body = {
  11. name: name of recipe,
  12. price: price of the recipe,
  13. ingredients: [{
  14. id: id of ingredient,
  15. quantity: quantity of ingredient in recipe
  16. }]
  17. }
  18. Return = newly created recipe in same form as above, with _id
  19. */
  20. createRecipe: function(req, res){
  21. if(!req.session.user){
  22. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  23. return res.redirect("/");
  24. }
  25. let validation = Validator.recipe(req.body);
  26. if(validation !== true){
  27. return res.json(validation);
  28. }
  29. let recipe = new Recipe({
  30. merchant: req.session.user,
  31. name: req.body.name,
  32. price: Math.round(req.body.price * 100),
  33. ingredients: req.body.ingredients
  34. });
  35. Merchant.findOne({_id: req.session.user})
  36. .then((merchant)=>{
  37. merchant.recipes.push(recipe);
  38. merchant.save()
  39. .catch((err)=>{
  40. return res.json("ERROR: UNABLE TO SAVE RECIPE");
  41. });
  42. })
  43. .catch((err)=>{
  44. return res.json("ERROR: UNABLE TO RETRIEVE USER DATA");
  45. });
  46. recipe.save()
  47. .then((newRecipe)=>{
  48. return res.json(newRecipe);
  49. })
  50. .catch((err)=>{
  51. return res.json("ERROR: UNABLE TO SAVE INGREDIENT");
  52. });
  53. },
  54. /*
  55. PUT - Update a single recipe
  56. req.body = {
  57. id: id of recipe,
  58. name: name of recipe,
  59. price: price of recipe,
  60. ingredients: [{
  61. ingredient: id of ingredient,
  62. quantity: quantity of ingredient in recipe
  63. }]
  64. }
  65. */
  66. updateRecipe: function(req, res){
  67. if(!req.session.user){
  68. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  69. return res.redirect("/");
  70. }
  71. let validation = Validator.recipe(req.body);
  72. if(validation !== true){
  73. return res.json(validation);
  74. }
  75. let changes = [];
  76. Recipe.findOne({_id: req.body.id})
  77. .then((recipe)=>{
  78. for(let i = 0; i < req.body.ingredients.length; i++){
  79. let isMatch = false;
  80. for(let j = 0; j < recipe.ingredients.length; j++){
  81. if(req.body.ingredients[i].ingredient === recipe.ingredients[j].ingredient.toString()){
  82. let difference = parseFloat((req.body.ingredients[i].quantity - recipe.ingredients[j].quantity).toFixed(2));
  83. if(difference !== 0){
  84. changes.push({
  85. ingredient: recipe.ingredients[j].ingredient,
  86. change: difference
  87. });
  88. }
  89. isMatch = true;
  90. break;
  91. }
  92. }
  93. if(!isMatch){
  94. changes.push({
  95. ingredient: req.body.ingredients[i].ingredient,
  96. change: req.body.ingredients[i].quantity
  97. });
  98. }
  99. }
  100. for(let i = 0; i < recipe.ingredients.length; i++){
  101. let isMatch = false;
  102. for(let j = 0; j < req.body.ingredients.length; j++){
  103. if(recipe.ingredients[i].ingredient.toString() === req.body.ingredients[i].ingredient){
  104. isMatch = true;
  105. }
  106. }
  107. if(!isMatch){
  108. changes.push({
  109. ingredient: recipe.ingredients[i].ingredient,
  110. change: -recipe.ingredients[i].quantity
  111. });
  112. }
  113. }
  114. recipe.name = req.body.name;
  115. recipe.price = req.body.price;
  116. recipe.ingredients = req.body.ingredients;
  117. return recipe.save()
  118. })
  119. .then((response)=>{
  120. res.json({});
  121. let recipeChange = new RecipeChange({
  122. recipe: response._id,
  123. date: new Date(),
  124. changes: changes
  125. });
  126. return recipeChange.save()
  127. })
  128. .catch((err)=>{
  129. return res.json("ERROR: UNABLE TO UPDATE RECIPE");
  130. });
  131. },
  132. //GET - Checks clover for new or deleted recipes
  133. //Returns:
  134. // merchant: Full merchant (recipe ingredients populated)
  135. // count: Number of new recipes
  136. updateRecipesClover: function(req, res){
  137. if(!req.session.user){
  138. req.session.error = "Must be logged in to do that";
  139. return res.redirect("/");
  140. }
  141. Merchant.findOne({_id: req.session.user})
  142. .populate("recipes")
  143. .then((merchant)=>{
  144. axios.get(`https://apisandbox.dev.clover.com/v3/merchants/${merchant.posId}/items?access_token=${merchant.posAccessToken}`)
  145. .then((result)=>{
  146. let deletedRecipes = merchant.recipes.slice();
  147. for(let i = 0; i < result.data.elements.length; i++){
  148. for(let j = 0; j < deletedRecipes.length; j++){
  149. if(result.data.elements[i].id === deletedRecipes[j].posId){
  150. result.data.elements.splice(i, 1);
  151. deletedRecipes.splice(j, 1);
  152. i--;
  153. break;
  154. }
  155. }
  156. }
  157. for(let i = 0; i < deletedRecipes.length; i++){
  158. for(let j = 0; j < merchant.recipes.length; j++){
  159. if(deletedRecipes[i]._id === merchant.recipes[j]._id){
  160. merchant.recipes.splice(j, 1);
  161. break;
  162. }
  163. }
  164. }
  165. let newRecipes = []
  166. for(let i = 0; i < result.data.elements.length; i++){
  167. let newRecipe = new Recipe({
  168. posId: result.data.elements[i].id,
  169. merchant: merchant._id,
  170. name: result.data.elements[i].name,
  171. ingredients: [],
  172. price: result.data.elements[i].price
  173. });
  174. merchant.recipes.push(newRecipe);
  175. newRecipes.push(newRecipe);
  176. }
  177. Recipe.create(newRecipes)
  178. .catch((err)=>{
  179. return res.json("ERROR: UNABLE TO SAVE RECIPES");
  180. });
  181. merchant.save()
  182. .then((newMerchant)=>{
  183. newMerchant.populate("recipes.ingredients.ingredient").execPopulate()
  184. .then((newestMerchant)=>{
  185. merchant.password = undefined;
  186. return res.json({new: newRecipes, removed: deletedRecipes});
  187. })
  188. .catch((err)=>{
  189. return res.json("ERROR: UNABLE TO RETRIEVE DATA");
  190. });
  191. })
  192. .catch((err)=>{
  193. return res.json("ERROR: UNABLE TO SAVE CHANGES FROM CLOVER");
  194. });
  195. })
  196. .catch((err)=>{
  197. return res.json("ERROR: UNABLE TO RETRIEVE DATA FROM CLOVER");
  198. });
  199. })
  200. .catch((err)=>{
  201. return res.json("ERROR: UNABLE TO RETRIEVE MERCHANT DATA");
  202. });
  203. },
  204. updateRecipesSquare: function(req, res){
  205. if(!req.session.user){
  206. req.session.error = "Must be logged in to do that";
  207. return res.redirect("/");
  208. }
  209. let merchant = {};
  210. let merchantRecipes = [];
  211. let newRecipes = [];
  212. Merchant.findOne({_id: req.session.user})
  213. .populate("recipes")
  214. .then((fetchedMerchant)=>{
  215. merchant = fetchedMerchant;
  216. return axios.post(`${process.env.SQUARE_ADDRESS}/v2/catalog/search`, {
  217. object_types: ["ITEM"]
  218. }, {
  219. headers: {
  220. Authorization: `Bearer ${merchant.posAccessToken}`
  221. }
  222. });
  223. })
  224. .then((response)=>{
  225. merchantRecipes = merchant.recipes.slice();
  226. for(let i = 0; i < response.data.objects.length; i++){
  227. let itemData = response.data.objects[i].item_data;
  228. for(let j = 0; j < itemData.variations.length; j++){
  229. let isFound = false;
  230. for(let k = 0; k < merchantRecipes.length; k++){
  231. if(itemData.variations[j].id === merchantRecipes[k].posId){
  232. merchantRecipes.splice(k, 1);
  233. k--;
  234. isFound = true;
  235. break;
  236. }
  237. }
  238. if(!isFound){
  239. let newRecipe = new Recipe({
  240. posId: itemData.variations[j].id,
  241. merchant: merchant._id,
  242. name: "",
  243. price: itemData.variations[j].item_variation_data.price_money.amount,
  244. ingredients: []
  245. });
  246. if(itemData.variations.length > 1){
  247. newRecipe.name = `${itemData.name} '${itemData.variations[j].item_variation_data.name}'`;
  248. }else{
  249. newRecipe.name = itemData.name;
  250. }
  251. newRecipes.push(newRecipe);
  252. merchant.recipes.push(newRecipe);
  253. }
  254. }
  255. }
  256. let ids = [];
  257. for(let i = 0; i < merchantRecipes.length; i++){
  258. ids.push(merchantRecipes[i]._id);
  259. for(let j = 0; j < merchant.recipes.length; j++){
  260. if(merchantRecipes[i]._id.toString() === merchant.recipes[j]._id.toString()){
  261. merchant.recipes.splice(j, 1);
  262. j--;
  263. break;
  264. }
  265. }
  266. }
  267. if(newRecipes.length > 0){
  268. Recipe.create(newRecipes);
  269. }
  270. if(merchantRecipes.length > 0){
  271. Recipe.deleteMany({_id: {$in: ids}});
  272. }
  273. return merchant.save();
  274. })
  275. .then((merchant)=>{
  276. return res.json({new: newRecipes, removed: merchantRecipes});
  277. })
  278. .catch((err)=>{
  279. return "ERROR: UNABLE TO RETRIEVE RECIPE DATA FROM SQUARE";
  280. });
  281. }
  282. }