merchantData.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. const axios = require("axios");
  2. const bcrypt = require("bcryptjs");
  3. const mailgun = require("mailgun-js")({apiKey: process.env.MG_SUBLINE_APIKEY, domain: "mail.thesubline.com"});
  4. const Merchant = require("../models/merchant");
  5. const Recipe = require("../models/recipe");
  6. const InventoryAdjustment = require("../models/inventoryAdjustment");
  7. const Validator = require("./validator.js");
  8. const WelcomeEmail = require("../emails/welcomeEmail.js");
  9. module.exports = {
  10. /*
  11. POST - Create a new merchant with no POS system
  12. req.body = {
  13. name: retaurant name,
  14. email: registration email,
  15. password: password,
  16. confirmPassword: confirmation password
  17. }
  18. Redirects to /dashboard
  19. */
  20. createMerchantNone: async function(req, res){
  21. let validation = await Validator.merchant(req.body);
  22. if(validation !== true){
  23. req.session.error = validation;
  24. return res.redirect("/");
  25. }
  26. if(req.body.password === req.body.confirmPassword){
  27. let salt = bcrypt.genSaltSync(10);
  28. let hash = bcrypt.hashSync(req.body.password, salt);
  29. let merchant = new Merchant({
  30. name: req.body.name,
  31. email: req.body.email.toLowerCase(),
  32. password: hash,
  33. pos: "none",
  34. lastUpdatedTime: Date.now(),
  35. createdAt: Date.now(),
  36. accountStatus: "valid",
  37. inventory: [],
  38. recipes: []
  39. });
  40. merchant.save()
  41. .then((merchant)=>{
  42. req.session.user = merchant._id;
  43. console.log("mailgunning");
  44. const mailgunData = {
  45. from: "The Subline <clientsupport@thesubline.com>",
  46. to: merchant.email,
  47. subject: "Welcome to The Subline!",
  48. html: WelcomeEmail({name: merchant.name, email: merchant.email})
  49. }
  50. mailgun.messages().send(mailgunData, (err, body)=>{
  51. console.log(err);
  52. console.log(data);
  53. });
  54. const mailgunList = mailgun.lists("clientsupport@mail.thesubline.com");
  55. mailgunList.members.create({
  56. subscribed: true,
  57. address: merchant.email,
  58. name: merchant.name
  59. }, (err, data)=>{
  60. console.log(err);
  61. });
  62. console.log("mailgunned");
  63. return res.redirect("/dashboard");
  64. })
  65. .catch((err)=>{
  66. req.session.error = "ERROR: UNABLE TO CREATE ACCOUNT AT THIS TIME";
  67. return res.redirect("/");
  68. });
  69. }else{
  70. req.session.error = "PASSWORDS DO NOT MATCH";
  71. return res.redirect("/");
  72. }
  73. },
  74. /*
  75. POST - Creates new Clover merchant
  76. Redirects to /dashboard
  77. */
  78. createMerchantClover: async function(req, res){
  79. axios.get(`${process.env.CLOVER_ADDRESS}/v3/merchants/${req.session.merchantId}?access_token=${req.session.accessToken}`)
  80. .then((response)=>{
  81. let merchant = new Merchant({
  82. name: response.data.name,
  83. pos: "clover",
  84. posId: req.session.merchantId,
  85. posAccessToken: req.session.accessToken,
  86. lastUpdatedTime: Date.now(),
  87. createdAt: Date.now(),
  88. inventory: [],
  89. recipes: []
  90. });
  91. axios.get(`${process.env.CLOVER_ADDRESS}/v3/merchants/${req.session.merchantId}/items?access_token=${req.session.accessToken}`)
  92. .then((response)=>{
  93. let recipes = [];
  94. for(let i = 0; i < response.data.elements.length; i++){
  95. let recipe = new Recipe({
  96. posId: response.data.elements[i].id,
  97. merchant: merchant,
  98. name: response.data.elements[i].name,
  99. price: response.data.elements[i].price,
  100. ingredients: []
  101. });
  102. recipes.push(recipe);
  103. merchant.recipes.push(recipe);
  104. }
  105. Recipe.create(recipes)
  106. .catch((err)=>{
  107. req.session.error = "ERROR: UNABLE TO CREATE YOUR RECIPES FROM CLOVER."
  108. })
  109. merchant.save()
  110. .then((newMerchant)=>{
  111. req.session.accessToken = undefined;
  112. req.session.user = newMerchant._id;
  113. return res.redirect("/dashboard");
  114. })
  115. .catch((err)=>{
  116. req.session.error = "ERROR: UNABLE TO SAVE DATA FROM CLOVER";
  117. return res.redirect("/");
  118. });
  119. })
  120. .catch((err)=>{
  121. req.session.error = "ERROR: UNABLE TO RETRIEVE DATA FROM CLOVER";
  122. return res.redirect("/");
  123. })
  124. })
  125. .catch((err)=>{
  126. req.session.error = "ERROR: UNABLE TO RETRIEVE DATA FROM CLOVER";
  127. return res.redirect("/");
  128. });
  129. },
  130. createMerchantSquare: function(req, res){
  131. let merchant = {}
  132. axios.get(`${process.env.SQUARE_ADDRESS}/v2/merchants/${req.session.merchantId}`, {
  133. headers: {
  134. Authorization: `Bearer ${req.session.accessToken}`
  135. }
  136. })
  137. .then((response)=>{
  138. req.session.merchantId = undefined;
  139. return new Merchant({
  140. name: response.data.merchant.business_name,
  141. pos: "square",
  142. posId: response.data.merchant.id,
  143. posAccessToken: req.session.accessToken,
  144. lastUpdatedTime: new Date(),
  145. createdAt: new Date(),
  146. squareLocation: response.data.merchant.main_location_id,
  147. inventory: [],
  148. recipes: []
  149. });
  150. })
  151. .then((newMerchant)=>{
  152. req.session.accessToken = undefined;
  153. merchant = newMerchant;
  154. return axios.post(`${process.env.SQUARE_ADDRESS}/v2/catalog/search`, {
  155. object_types: ["ITEM"]
  156. }, {
  157. headers: {
  158. Authorization: `Bearer ${merchant.posAccessToken}`
  159. }
  160. });
  161. })
  162. .then((response)=>{
  163. let recipes = [];
  164. for(let i = 0; i < response.data.objects.length; i++){
  165. if(response.data.objects[i].item_data.variations.length > 1){
  166. for(let j = 0; j < response.data.objects[i].item_data.variations.length; j++){
  167. let recipe = new Recipe({
  168. posId: response.data.objects[i].item_data.variations[j].id,
  169. merchant: merchant._id,
  170. name: `${response.data.objects[i].item_data.name} '${response.data.objects[i].item_data.variations[j].item_variation_data.name}'`,
  171. price: response.data.objects[i].item_data.variations[j].item_variation_data.price_money.amount
  172. });
  173. recipes.push(recipe);
  174. merchant.recipes.push(recipe);
  175. }
  176. }else{
  177. let recipe = new Recipe({
  178. posId: response.data.objects[i].item_data.variations[0].id,
  179. merchant: merchant._id,
  180. name: response.data.objects[i].item_data.name,
  181. price: response.data.objects[i].item_data.variations[0].item_variation_data.price_money.amount,
  182. ingredients: []
  183. });
  184. recipes.push(recipe);
  185. merchant.recipes.push(recipe);
  186. }
  187. }
  188. return Recipe.create(recipes);
  189. })
  190. .then((recipes)=>{
  191. return merchant.save();
  192. })
  193. .then((merchant)=>{
  194. req.session.user = merchant._id;
  195. return res.redirect("/dashboard");
  196. })
  197. .catch((err)=>{
  198. banner.createError("ERROR: UNABLE TO CREATE NEW USER AT THIS TIME");
  199. });
  200. },
  201. //PUT - Update the default unit for a single ingredient
  202. ingredientDefaultUnit: function(req, res){
  203. if(!req.session.user){
  204. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  205. return res.redirect("/");
  206. }
  207. Merchant.findOne({_id: req.session.user})
  208. .then((merchant)=>{
  209. for(let i = 0; i < merchant.inventory.length; i++){
  210. if(merchant.inventory[i].ingredient.toString() === req.params.id){
  211. merchant.inventory[i].defaultUnit =req.params.unit;
  212. }
  213. }
  214. return merchant.save()
  215. })
  216. .then((merchant)=>{
  217. return res.json({});
  218. })
  219. .catch((err)=>{
  220. return res.json("ERROR: UNABLE TO UPDATE DEFAULT UNIT");
  221. });
  222. },
  223. /*
  224. POST - Update the quantity for a merchant inventory item
  225. req.body = [{
  226. id: id of ingredient to update,
  227. quantity: change in quantity
  228. }]
  229. */
  230. updateMerchantIngredient: function(req, res){
  231. if(!req.session.user){
  232. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  233. return res.redirect("/");
  234. }
  235. for(let i = 0; i < req.body.length; i++){
  236. let validation = Validator.quantity(req.body[i].quantity);
  237. if(validation !== true){
  238. return res.json(validation);
  239. }
  240. }
  241. let adjustments = [];
  242. Merchant.findOne({_id: req.session.user})
  243. .then((merchant)=>{
  244. for(let i = 0; i < req.body.length; i++){
  245. let updateIngredient;
  246. for(let j = 0; j < merchant.inventory.length; j++){
  247. if(merchant.inventory[j].ingredient.toString() === req.body[i].id){
  248. updateIngredient = merchant.inventory[j];
  249. break;
  250. }
  251. }
  252. adjustments.push(new InventoryAdjustment({
  253. date: Date.now(),
  254. merchant: req.session.user,
  255. ingredient: req.body[i].id,
  256. quantity: req.body[i].quantity - updateIngredient.quantity,
  257. }));
  258. updateIngredient.quantity = req.body[i].quantity;
  259. }
  260. return merchant.save();
  261. })
  262. .then((newMerchant)=>{
  263. res.json({});
  264. InventoryAdjustment.create(adjustments).catch(()=>{});
  265. return;
  266. })
  267. .catch((err)=>{
  268. return res.json("ERROR: UNABLE TO UPDATE DATA");
  269. });
  270. },
  271. /*
  272. POST - Changes the users password
  273. req.body = {
  274. pass: new password,
  275. confirmPass: new password confirmation,
  276. hash: hashed version of old password
  277. }
  278. */
  279. updatePassword: function(req, res){
  280. let validation = Validator.password(req.body.pass, req.body.confirmPass);
  281. if(validation !== true){
  282. return res.json(validation);
  283. }
  284. Merchant.findOne({password: req.body.hash})
  285. .then((merchant)=>{
  286. if(merchant){
  287. let salt = bcrypt.genSaltSync(10);
  288. let hash = bcrypt.hashSync(req.body.pass, salt);
  289. merchant.password = hash;
  290. return merchant.save();
  291. }else{
  292. req.session.error = "ERROR: UNABLE TO RETRIEVE USER DATA";
  293. return res.redirect("/");
  294. }
  295. })
  296. .then((merchant)=>{
  297. req.session.error = "PASSWORD SUCCESSFULLY RESET. PLEASE LOG IN";
  298. return res.redirect("/");
  299. })
  300. .catch((err)=>{});
  301. }
  302. }