merchantData.js 11 KB

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