Merchant.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. class Merchant{
  2. constructor(oldMerchant, transactions, modules){
  3. this._modules = modules;
  4. this._name = oldMerchant.name;
  5. this._pos = oldMerchant.pos;
  6. this._ingredients = [];
  7. this._recipes = [];
  8. this._transactions = [];
  9. this._orders = [];
  10. this._units = {
  11. mass: ["g", "kg", "oz", "lb"],
  12. volume: ["ml", "l", "tsp", "tbsp", "ozfl", "cup", "pt", "qt", "gal"],
  13. length: ["mm", "cm", "m", "in", "ft"],
  14. other: ["each", "bottle"]
  15. }
  16. for(let i = 0; i < oldMerchant.inventory.length; i++){
  17. this.ingredients.push({
  18. ingredient: new modules.Ingredient(
  19. oldMerchant.inventory[i].ingredient._id,
  20. oldMerchant.inventory[i].ingredient.name,
  21. oldMerchant.inventory[i].ingredient.category,
  22. oldMerchant.inventory[i].ingredient.unitType,
  23. oldMerchant.inventory[i].defaultUnit,
  24. this,
  25. oldMerchant.inventory[i].ingredient.specialUnit,
  26. oldMerchant.inventory[i].ingredient.unitSize
  27. ),
  28. quantity: oldMerchant.inventory[i].quantity
  29. });
  30. }
  31. for(let i = 0; i < oldMerchant.recipes.length; i++){
  32. this.recipes.push(new modules.Recipe(
  33. oldMerchant.recipes[i]._id,
  34. oldMerchant.recipes[i].name,
  35. oldMerchant.recipes[i].price,
  36. oldMerchant.recipes[i].ingredients,
  37. this
  38. ));
  39. }
  40. for(let i = 0; i < transactions.length; i++){
  41. this.transactions.push(new modules.Transaction(
  42. transactions[i]._id,
  43. transactions[i].date,
  44. transactions[i].recipes,
  45. this
  46. ));
  47. }
  48. }
  49. get name(){
  50. return this._name;
  51. }
  52. set name(name){
  53. if(sanitaryString(name)){
  54. this._name = name;
  55. }
  56. return false;
  57. }
  58. get pos(){
  59. return this._pos;
  60. }
  61. get ingredients(){
  62. return this._ingredients;
  63. }
  64. addIngredient(ingredient){
  65. if(ingredient.quantity < 0 || ingredient.quantity === undefined){
  66. return false;
  67. }
  68. this.ingredients.push(ingredient);
  69. this._modules.home.isPopulated = false;
  70. this._modules.ingredients.isPopulated = false;
  71. }
  72. removeIngredient(ingredient){
  73. const index = this._ingredients.indexOf(ingredient);
  74. if(index === undefined){
  75. return false;
  76. }
  77. this._ingredients.splice(index, 1);
  78. this._modules.home.isPopulated = false;
  79. this._modules.ingredients.isPopulated = false;
  80. }
  81. get recipes(){
  82. return this._recipes;
  83. }
  84. addRecipe(recipe){
  85. this._recipes.push(recipe);
  86. this._modules.transactions.isPopulated = false;
  87. this._modules.recipeBook.isPopulated = false;
  88. }
  89. removeRecipe(recipe){
  90. const index = this._recipes.indexOf(recipe);
  91. if(index === undefined){
  92. return false;
  93. }
  94. this._recipes.splice(index, 1);
  95. this._modules.transactions.isPopulated = false;
  96. this._modules.recipeBook.isPopulated = false;
  97. }
  98. get transactions(){
  99. return this._transactions;
  100. }
  101. addTransaction(transaction){
  102. this._transactions.push(transaction);
  103. this._modules.home.isPopulated = false;
  104. this._modules.ingredients.isPopulated = false;
  105. this._modules.transactions.isPopulated = false;
  106. this._modules.analytics.newData = true;
  107. }
  108. removeTransaction(transaction){
  109. const index = this._transactions.indexOf(transaction);
  110. if(index === undefined){
  111. return false;
  112. }
  113. this._transactions.splice(index, 1);
  114. this._modules.home.isPopulated = false;
  115. this._modules.ingredients.isPopulated = false;
  116. this._modules.transactions.isPopulated = false;
  117. this._modules.analytics.newData = true;
  118. }
  119. get orders(){
  120. return this._orders;
  121. }
  122. addOrder(order){
  123. this._orders.push(order);
  124. this._modules.orders.isPopulated = false;
  125. }
  126. removeOrder(order){
  127. const index = this._orders.indexOf(order);
  128. if(index === undefined){
  129. return false;
  130. }
  131. this._orders.splice(index, 1);
  132. this._modules.orders.isPopulated = false;
  133. }
  134. get units(){
  135. return this._units;
  136. }
  137. revenue(indices){
  138. let total = 0;
  139. for(let i = indices[0]; i <= indices[1]; i++){
  140. for(let j = 0; j < this.transactions[i].recipes.length; j++){
  141. for(let k = 0; k < this.recipes.length; k++){
  142. if(this.transactions[i].recipes[j].recipe === this.recipes[k]){
  143. total += this.transactions[i].recipes[j].quantity * this.recipes[k].price;
  144. }
  145. }
  146. }
  147. }
  148. return total / 100;
  149. }
  150. /*
  151. Gets the quantity of each ingredient sold between two dates (dateRange)
  152. Inputs
  153. dateRange: list containing a start date and an end date
  154. Return:
  155. [{
  156. ingredient: Ingredient object,
  157. quantity: quantity of ingredient sold
  158. }]
  159. */
  160. ingredientsSold(dateRange){
  161. if(!dateRange){
  162. return false;
  163. }
  164. let recipes = this.recipesSold(dateRange);
  165. let ingredientList = [];
  166. for(let i = 0; i < recipes.length; i++){
  167. for(let j = 0; j < recipes[i].recipe.ingredients.length; j++){
  168. let exists = false;
  169. for(let k = 0; k < ingredientList.length; k++){
  170. if(ingredientList[k].ingredient === recipes[i].recipe.ingredients[j].ingredient){
  171. exists = true;
  172. ingredientList[k].quantity += recipes[i].quantity * recipes[i].recipe.ingredients[j].quantity;
  173. break;
  174. }
  175. }
  176. if(!exists){
  177. ingredientList.push({
  178. ingredient: recipes[i].recipe.ingredients[j].ingredient,
  179. quantity: recipes[i].quantity * recipes[i].recipe.ingredients[j].quantity
  180. });
  181. }
  182. }
  183. }
  184. return ingredientList;
  185. }
  186. singleIngredientSold(dateRange, ingredient){
  187. let total = 0;
  188. for(let i = dateRange[0]; i < dateRange[1]; i++){
  189. for(let j = 0; j < this.transactions[i].recipes.length; j++){
  190. for(let k = 0; k < this.transactions[i].recipes[j].recipe.ingredients.length; k++){
  191. if(this.transactions[i].recipes[j].recipe.ingredients[k].ingredient === ingredient.ingredient){
  192. total += this.transactions[i].recipes[j].recipe.ingredients[k].quantity;
  193. break;
  194. }
  195. }
  196. }
  197. }
  198. return total;
  199. }
  200. /*
  201. Gets the number of recipes sold between two dates (dateRange)
  202. Inputs:
  203. dateRange: array containing a start date and an end date
  204. Return:
  205. [{
  206. recipe: a recipe object
  207. quantity: quantity of the recipe sold
  208. }]
  209. */
  210. recipesSold(dateRange){
  211. let recipeList = [];
  212. for(let i = dateRange[0]; i <= dateRange[1]; i++){
  213. for(let j = 0; j < this.transactions[i].recipes.length; j++){
  214. let exists = false;
  215. for(let k = 0; k < recipeList.length; k++){
  216. if(recipeList[k].recipe === this.transactions[i].recipes[j].recipe){
  217. exists = true;
  218. recipeList[k].quantity += this.transactions[i].recipes[j].quantity;
  219. break;
  220. }
  221. }
  222. if(!exists){
  223. recipeList.push({
  224. recipe: this.transactions[i].recipes[j].recipe,
  225. quantity: this.transactions[i].recipes[j].quantity
  226. });
  227. }
  228. }
  229. }
  230. return recipeList;
  231. }
  232. /*
  233. Groups all of the merchant's ingredients by their category
  234. Return: [{
  235. name: category name,
  236. ingredients: [Ingredient Object]
  237. }]
  238. */
  239. categorizeIngredients(){
  240. let ingredientsByCategory = [];
  241. for(let i = 0; i < this.ingredients.length; i++){
  242. let categoryExists = false;
  243. for(let j = 0; j < ingredientsByCategory.length; j++){
  244. if(this.ingredients[i].ingredient.category === ingredientsByCategory[j].name){
  245. ingredientsByCategory[j].ingredients.push(this.ingredients[i]);
  246. categoryExists = true;
  247. break;
  248. }
  249. }
  250. if(!categoryExists){
  251. ingredientsByCategory.push({
  252. name: this.ingredients[i].ingredient.category,
  253. ingredients: [this.ingredients[i]]
  254. });
  255. }
  256. }
  257. return ingredientsByCategory;
  258. }
  259. unitizeIngredients(){
  260. let ingredientsByUnit = [];
  261. for(let i = 0; i < this.ingredients.length; i++){
  262. let unitExists = false;
  263. const innerIngredient = this.ingredients[i].ingredient;
  264. for(let j = 0; j < ingredientsByUnit.length; j++){
  265. if(innerIngredient.unit === ingredientsByUnit[j].name || innerIngredient.specialUnit === ingredientsByUnit[j].name){
  266. ingredientsByUnit[j].ingredients.push(this.ingredients[i]);
  267. unitExists = true;
  268. break;
  269. }
  270. }
  271. if(!unitExists){
  272. let unit = "";
  273. if(innerIngredient.specialUnit === "bottle"){
  274. unit = "bottle";
  275. }else{
  276. unit = innerIngredient.unit;
  277. }
  278. ingredientsByUnit.push({
  279. name: unit,
  280. ingredients: [this.ingredients[i]]
  281. });
  282. }
  283. }
  284. return ingredientsByUnit;
  285. }
  286. getRecipesForIngredient(ingredient){
  287. let recipes = [];
  288. for(let i = 0; i < this.recipes.length; i++){
  289. for(let j = 0; j < this.recipes[i].ingredients.length; j++){
  290. if(this.recipes[i].ingredients[j].ingredient === ingredient){
  291. recipes.push(this.recipes[i]);
  292. }
  293. }
  294. }
  295. return recipes;
  296. }
  297. }
  298. module.exports = Merchant;