orderData.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. const Order = require("../models/order.js");
  2. const Merchant = require("../models/merchant.js");
  3. const ObjectId = require("mongoose").Types.ObjectId;
  4. const Validator = require("./validator.js");
  5. const helper = require("./helper.js");
  6. const xlsx = require("xlsx");
  7. const fs = require("fs");
  8. module.exports = {
  9. /*
  10. GET - get the 25 most recent orders
  11. return = [
  12. _id: id of order,
  13. name: user created id for order,
  14. date: date order was created,
  15. ingredients: [{
  16. _id: unused id of this object,
  17. ingredient: id of the ingredient,
  18. price: price per unit of the ingredient,
  19. quantity: quantity of ingredient in this order
  20. }]
  21. ]
  22. */
  23. getOrders: function(req, res){
  24. if(!req.session.user){
  25. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  26. return res.redirect("/");
  27. }
  28. Order.aggregate([
  29. {$match: {merchant: ObjectId(req.session.user)}},
  30. {$sort: {date: -1}},
  31. {$limit: 25},
  32. {$project: {
  33. name: 1,
  34. date: 1,
  35. taxes: 1,
  36. fees: 1,
  37. ingredients: 1
  38. }}
  39. ])
  40. .then((orders)=>{
  41. return res.json(orders);
  42. })
  43. .catch((err)=>{
  44. return res.json("ERROR: UNABLE TO RETRIEVE YOUR ORDERS");
  45. });
  46. },
  47. /*
  48. POST - retrieves a list of transactions based on the filter
  49. req.body = {
  50. startDate: starting date to filter on,
  51. endDate: ending date to filter on,
  52. ingredients: list of recipes.to filter on
  53. }
  54. */
  55. orderFilter: function(req, res){
  56. if(!req.session.user){
  57. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  58. return res.redirect("/");
  59. }
  60. let objectifiedIngredients = [];
  61. for(let i = 0; i < req.body.ingredients.length; i++){
  62. objectifiedIngredients.push(new ObjectId(req.body.ingredients[i]));
  63. }
  64. let startDate = new Date(req.body.startDate);
  65. let endDate = new Date(req.body.endDate);
  66. endDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate() + 1);
  67. Order.aggregate([
  68. {$match: {
  69. merchant: new ObjectId(req.session.user),
  70. date: {
  71. $gte: startDate,
  72. $lt: endDate
  73. },
  74. ingredients: {
  75. $elemMatch: {
  76. ingredient: {
  77. $in: objectifiedIngredients
  78. }
  79. }
  80. }
  81. }},
  82. {$sort: {date: -1}}
  83. ])
  84. .then((orders)=>{
  85. return res.json(orders);
  86. })
  87. .catch((err)=>{
  88. return res.json("ERROR: UNABLE TO RETRIEVE YOUR TRANSACTIONS");
  89. });
  90. },
  91. /*
  92. POST - Creates a new order from the site
  93. req.body = {
  94. name: user created order id
  95. date: creation date
  96. ingredients: [{
  97. ingredient: id of the ingredient
  98. quantity: amount of the ingredient purchased
  99. pricePerUnit: price per gram
  100. }]
  101. }
  102. */
  103. createOrder: function(req, res){
  104. if(!req.session.user){
  105. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  106. return res.redirect("/");
  107. }
  108. let validation = Validator.order(req.body);
  109. if(validation !== true){
  110. return res.json(validation);
  111. }
  112. let newOrder = new Order(req.body);
  113. newOrder.merchant = req.session.user;
  114. newOrder.save()
  115. .then((response)=>{
  116. res.json(response);
  117. })
  118. .catch((err)=>{
  119. return res.json("ERROR: UNABLE TO SAVE ORDER");
  120. });
  121. Merchant.findOne({_id: req.session.user})
  122. .then((merchant)=>{
  123. for(let i = 0; i < req.body.ingredients.length; i++){
  124. for(let j = 0; j < merchant.inventory.length; j++){
  125. if(req.body.ingredients[i].ingredient === merchant.inventory[j].ingredient.toString()){
  126. merchant.inventory[j].quantity += parseFloat(req.body.ingredients[i].quantity);
  127. }
  128. }
  129. }
  130. return merchant.save();
  131. })
  132. .then((merchant)=>{
  133. return;
  134. })
  135. .catch(()=>{});
  136. },
  137. /*
  138. DELETE - Remove an order from the database
  139. */
  140. removeOrder: function(req, res){
  141. if(!req.session.user){
  142. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  143. return res.redirect("/");
  144. }
  145. let merchant = {};
  146. let order = {}
  147. Merchant.findOne({_id: req.session.user})
  148. .then((response)=>{
  149. merchant = response;
  150. return Order.findOne({_id: req.params.id});
  151. })
  152. .then((response)=>{
  153. order = response;
  154. return Order.deleteOne({_id: req.params.id})
  155. })
  156. .then((response)=>{
  157. res.json({});
  158. for(let i = 0; i < order.ingredients.length; i++){
  159. for(let j = 0; j < merchant.inventory.length; j++){
  160. if(order.ingredients[i].ingredient.toString() === merchant.inventory[j].ingredient.toString()){
  161. merchant.inventory[j].quantity -= order.ingredients[i].quantity;
  162. break;
  163. }
  164. }
  165. }
  166. return merchant.save();
  167. })
  168. .catch((err)=>{
  169. return res.json("ERROR: UNABLE TO REMOVE ORDER");
  170. });
  171. },
  172. createFromSpreadsheet: function(req, res){
  173. if(!req.session.user){
  174. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  175. return res.redirect("/");
  176. }
  177. //read file, get the correct sheet, create array from sheet
  178. let workbook = xlsx.readFile(req.file.path);
  179. fs.unlink(req.file.path, ()=>{});
  180. let sheets = Object.keys(workbook.Sheets);
  181. let sheet = {};
  182. for(let i = 0; i < sheets.length; i++){
  183. let str = sheets[i].toLowerCase();
  184. if(str === "order" || str === "orders"){
  185. sheet = workbook.Sheets[sheets[i]];
  186. }
  187. }
  188. const array = xlsx.utils.sheet_to_json(sheet, {
  189. header: 1
  190. });
  191. //get property locations
  192. let locations = {};
  193. for(let i = 0; i < array[0].length; i++){
  194. switch(array[0][i].toLowerCase()){
  195. case "name": locations.name = i; break;
  196. case "date": locations.date = i; break;
  197. case "taxes": locations.taxes = i; break;
  198. case "fees": locations.fees = i; break;
  199. case "ingredients": locations.ingredients = i; break;
  200. case "quantity": locations.quantity = i; break;
  201. case "price": locations.price = i; break;
  202. }
  203. }
  204. let merchant = {};
  205. Merchant.findOne({_id: req.session.user})
  206. .populate("inventory.ingredient")
  207. .then((response)=>{
  208. merchant = response;
  209. let orders = [];
  210. let currentOrder = {};
  211. for(let i = 1; i < array.length; i++){
  212. if(array[i].length === 0){
  213. continue;
  214. }
  215. if(array[i][locations.name] !== undefined){
  216. currentOrder = {
  217. merchant: req.session.user,
  218. name: array[i][locations.name],
  219. taxes: parseInt(array[i][locations.taxes] * 100),
  220. fees: parseInt(array[i][locations.fees] * 100),
  221. ingredients: []
  222. }
  223. if(array[i][locations.date] === undefined){
  224. currentOrder.date = new Date();
  225. }else{
  226. currentOrder.date = new Date(array[i][locations.date]);
  227. }
  228. orders.push(currentOrder);
  229. }
  230. let exists = false;
  231. for(let j = 0; j < merchant.inventory.length; j++){
  232. if(merchant.inventory[j].ingredient.name.toLowerCase() === array[i][locations.ingredients]){
  233. const baseQuantity = helper.convertQuantityToBaseUnit(array[i][locations.quantity], merchant.inventory[j].defaultUnit);
  234. currentOrder.ingredients.push({
  235. ingredient: merchant.inventory[j].ingredient._id,
  236. quantity: baseQuantity,
  237. pricePerUnit: helper.convertPrice(array[i][locations.price] * 100, merchant.inventory[j].defaultUnit)
  238. });
  239. merchant.inventory[j].quantity += baseQuantity;
  240. exists = true;
  241. break;
  242. }
  243. }
  244. if(exists === false){
  245. throw `CANNOT FIND INGREDIENT ${array[i][locations.ingredients]} FROM ORDER ${array[i][locations.name]}`;
  246. }
  247. }
  248. return Promise.all([Order.create(orders), merchant.save()]);
  249. })
  250. .then((response)=>{
  251. return res.json(response[0]);
  252. })
  253. .catch((err)=>{
  254. if(typeof(err) === "string"){
  255. return res.json(err);
  256. }
  257. return res.json("ERROR: UNABLE TO CREATE YOUR ORDERS");
  258. });
  259. },
  260. /*
  261. GET - Creates and sends a template xlsx for uploading orders
  262. */
  263. spreadsheetTemplate: function(req, res){
  264. if(!req.session.user){
  265. req.session.error = "MUST BE LOGGED IN TO DO THAT";
  266. return res.redirect("/");
  267. }
  268. Merchant.findOne({_id: req.session.user})
  269. .populate("inventory.ingredient")
  270. .then((merchant)=>{
  271. let workbook = xlsx.utils.book_new();
  272. workbook.SheetNames.push("Order");
  273. let workbookData = [];
  274. workbookData.push(["Name", "Date", "Taxes", "Fees", "Ingredients", "Quantity", "Price", "<- Price Per Unit", "Ingredient Reference"]);
  275. for(let i = 0; i < merchant.inventory.length; i++){
  276. let data = ["", "", "", "", "", "", "", "", merchant.inventory[i].ingredient.name];
  277. workbookData.push(data);
  278. }
  279. workbookData[1][0] = "My Order Name";
  280. workbookData[1][1] = "2020-02-29";
  281. workbookData[1][2] = 10.99;
  282. workbookData[1][3] = 5.98;
  283. workbookData[1][4] = "Example ingredient 1";
  284. workbookData[1][5] = 100;
  285. workbookData[1][6] = 1.99;
  286. workbookData[2][4] = "Example ingredient 2";
  287. workbookData[2][5] = 55;
  288. workbookData[2][6] = 0.95;
  289. workbook.Sheets.Order = xlsx.utils.aoa_to_sheet(workbookData);
  290. xlsx.writeFile(workbook, "SublineOrder.xlsx");
  291. return res.download("SublineOrder.xlsx", (err)=>{
  292. fs.unlink("SublineOrder.xlsx", ()=>{});
  293. });
  294. })
  295. .catch((err)=>{});
  296. }
  297. }