recipeData.js 13 KB

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