merchantData.js 13 KB

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