|
@@ -1,51 +1,152 @@
|
|
|
-const Ingredient = require("./Ingredient.js");
|
|
|
|
|
-const Recipe = require("./Recipe.js");
|
|
|
|
|
-const Transaction = require("./Transaction.js");
|
|
|
|
|
|
|
+class MerchantIngredient{
|
|
|
|
|
+ constructor(ingredient, quantity){
|
|
|
|
|
+ if(quantity < 0){
|
|
|
|
|
+ banner.createError("QUANTITY CANNOT BE A NEGATIVE NUMBER");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._quantity = quantity;
|
|
|
|
|
+ this._ingredient = ingredient;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get ingredient(){
|
|
|
|
|
+ return this._ingredient;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get quantity(){
|
|
|
|
|
+ if(this._ingredient.specialUnit === "bottle"){
|
|
|
|
|
+ return this._quantity / this._ingredient._unitSize;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switch(this._ingredient.unit){
|
|
|
|
|
+ case "g":return this._quantity;
|
|
|
|
|
+ case "kg": return this._quantity / 1000;
|
|
|
|
|
+ case "oz": return this._quantity / 28.3495;
|
|
|
|
|
+ case "lb": return this._quantity / 453.5924;
|
|
|
|
|
+ case "ml": return this._quantity * 1000;
|
|
|
|
|
+ case "l": return this._quantity;
|
|
|
|
|
+ case "tsp": return this._quantity * 202.8842;
|
|
|
|
|
+ case "tbsp": return this._quantity * 67.6278;
|
|
|
|
|
+ case "ozfl": return this._quantity * 33.8141;
|
|
|
|
|
+ case "cup": return this._quantity * 4.1667;
|
|
|
|
|
+ case "pt": return this._quantity * 2.1134;
|
|
|
|
|
+ case "qt": return this._quantity * 1.0567;
|
|
|
|
|
+ case "gal": return this._quantity / 3.7854;
|
|
|
|
|
+ case "mm": return this._quantity * 1000;
|
|
|
|
|
+ case "cm": return this._quantity * 100;
|
|
|
|
|
+ case "m": return this._quantity;
|
|
|
|
|
+ case "in": return this._quantity * 39.3701;
|
|
|
|
|
+ case "ft": return this._quantity * 3.2808;
|
|
|
|
|
+ default: return this._quantity;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ set quantity(quantity){
|
|
|
|
|
+ if(quantity < 0){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._quantity = quantity;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ convertToBase(quantity){
|
|
|
|
|
+ switch(this._ingredient.unit){
|
|
|
|
|
+ case "g": return quantity;
|
|
|
|
|
+ case "kg": return quantity * 1000;
|
|
|
|
|
+ case "oz": return quantity * 28.3495;
|
|
|
|
|
+ case "lb": return quantity * 453.5924;
|
|
|
|
|
+ case "ml": return quantity / 1000;
|
|
|
|
|
+ case "l": return quantity;
|
|
|
|
|
+ case "tsp": return quantity / 202.8842;
|
|
|
|
|
+ case "tbsp": return quantity / 67.6278;
|
|
|
|
|
+ case "ozfl": return quantity / 33.8141;
|
|
|
|
|
+ case "cup": return quantity / 4.1667;
|
|
|
|
|
+ case "pt": return quantity / 2.1134;
|
|
|
|
|
+ case "qt": return quantity / 1.0567;
|
|
|
|
|
+ case "gal": return quantity * 3.7854;
|
|
|
|
|
+ case "mm": return quantity / 1000;
|
|
|
|
|
+ case "cm": return quantity / 100;
|
|
|
|
|
+ case "m": return quantity;
|
|
|
|
|
+ case "in": return quantity / 39.3701;
|
|
|
|
|
+ case "ft": return quantity / 3.2808;
|
|
|
|
|
+ default: return quantity;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ getQuantityDisplay(){
|
|
|
|
|
+ if(this._ingredient.specialUnit === "bottle"){
|
|
|
|
|
+ return `${this.quantity.toFixed(2)} BOTTLES`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return `${this.quantity.toFixed(2)} ${this._ingredient.unit.toUpperCase()}`;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
class Merchant{
|
|
class Merchant{
|
|
|
- constructor(oldMerchant, transactions){
|
|
|
|
|
- this.name = oldMerchant.name;
|
|
|
|
|
- this.pos = oldMerchant.pos;
|
|
|
|
|
- this.ingredients = [];
|
|
|
|
|
- this.recipes = [];
|
|
|
|
|
- this.transactions = [];
|
|
|
|
|
- this.orders = [];
|
|
|
|
|
- this.units = {
|
|
|
|
|
|
|
+ constructor(oldMerchant, transactions, modules){
|
|
|
|
|
+ this._modules = modules;
|
|
|
|
|
+ this._name = oldMerchant.name;
|
|
|
|
|
+ this._pos = oldMerchant.pos;
|
|
|
|
|
+ this._ingredients = [];
|
|
|
|
|
+ this._recipes = [];
|
|
|
|
|
+ this._transactions = [];
|
|
|
|
|
+ this._orders = [];
|
|
|
|
|
+ this._units = {
|
|
|
mass: ["g", "kg", "oz", "lb"],
|
|
mass: ["g", "kg", "oz", "lb"],
|
|
|
volume: ["ml", "l", "tsp", "tbsp", "ozfl", "cup", "pt", "qt", "gal"],
|
|
volume: ["ml", "l", "tsp", "tbsp", "ozfl", "cup", "pt", "qt", "gal"],
|
|
|
length: ["mm", "cm", "m", "in", "ft"],
|
|
length: ["mm", "cm", "m", "in", "ft"],
|
|
|
other: ["each", "bottle"]
|
|
other: ["each", "bottle"]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //populate ingredients
|
|
|
for(let i = 0; i < oldMerchant.inventory.length; i++){
|
|
for(let i = 0; i < oldMerchant.inventory.length; i++){
|
|
|
-
|
|
|
|
|
- this.ingredients.push({
|
|
|
|
|
- ingredient: new Ingredient(
|
|
|
|
|
- oldMerchant.inventory[i].ingredient._id,
|
|
|
|
|
- oldMerchant.inventory[i].ingredient.name,
|
|
|
|
|
- oldMerchant.inventory[i].ingredient.category,
|
|
|
|
|
- oldMerchant.inventory[i].ingredient.unitType,
|
|
|
|
|
- oldMerchant.inventory[i].defaultUnit,
|
|
|
|
|
- this,
|
|
|
|
|
- oldMerchant.inventory[i].ingredient.specialUnit,
|
|
|
|
|
- oldMerchant.inventory[i].ingredient.unitSize
|
|
|
|
|
- ),
|
|
|
|
|
- quantity: oldMerchant.inventory[i].quantity
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const ingredient = new modules.Ingredient(
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient._id,
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient.name,
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient.category,
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient.unitType,
|
|
|
|
|
+ oldMerchant.inventory[i].defaultUnit,
|
|
|
|
|
+ this,
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient.specialUnit,
|
|
|
|
|
+ oldMerchant.inventory[i].ingredient.unitSize
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ const merchantIngredient = new MerchantIngredient(
|
|
|
|
|
+ ingredient,
|
|
|
|
|
+ oldMerchant.inventory[i].quantity,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ this._ingredients.push(merchantIngredient);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //populate recipes
|
|
|
for(let i = 0; i < oldMerchant.recipes.length; i++){
|
|
for(let i = 0; i < oldMerchant.recipes.length; i++){
|
|
|
- this.recipes.push(new Recipe(
|
|
|
|
|
|
|
+ let ingredients = [];
|
|
|
|
|
+ for(let j = 0; j < oldMerchant.recipes[i].ingredients.length; j++){
|
|
|
|
|
+ const ingredient = oldMerchant.recipes[i].ingredients[j];
|
|
|
|
|
+ for(let k = 0; k < this._ingredients.length; k++){
|
|
|
|
|
+ if(ingredient.ingredient === this._ingredients[k].ingredient.id){
|
|
|
|
|
+ ingredients.push({
|
|
|
|
|
+ ingredient: this._ingredients[k].ingredient,
|
|
|
|
|
+ quantity: ingredient.quantity
|
|
|
|
|
+ });
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._recipes.push(new this._modules.Recipe(
|
|
|
oldMerchant.recipes[i]._id,
|
|
oldMerchant.recipes[i]._id,
|
|
|
oldMerchant.recipes[i].name,
|
|
oldMerchant.recipes[i].name,
|
|
|
oldMerchant.recipes[i].price,
|
|
oldMerchant.recipes[i].price,
|
|
|
- oldMerchant.recipes[i].ingredients,
|
|
|
|
|
|
|
+ ingredients,
|
|
|
this
|
|
this
|
|
|
));
|
|
));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //populate transactions
|
|
|
for(let i = 0; i < transactions.length; i++){
|
|
for(let i = 0; i < transactions.length; i++){
|
|
|
- this.transactions.push(new Transaction(
|
|
|
|
|
|
|
+ this._transactions.push(new modules.Transaction(
|
|
|
transactions[i]._id,
|
|
transactions[i]._id,
|
|
|
transactions[i].date,
|
|
transactions[i].date,
|
|
|
transactions[i].recipes,
|
|
transactions[i].recipes,
|
|
@@ -54,162 +155,275 @@ class Merchant{
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ get modules(){
|
|
|
|
|
+ return this._modules;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get name(){
|
|
|
|
|
+ return this._name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ set name(name){
|
|
|
|
|
+ if(this.isSanitaryString(name)){
|
|
|
|
|
+ this._name = name;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get pos(){
|
|
|
|
|
+ return this._pos;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get ingredients(){
|
|
|
|
|
+ return this._ingredients;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addIngredient(ingredient, quantity){
|
|
|
|
|
+ const merchantIngredient = new MerchantIngredient(ingredient, quantity);
|
|
|
|
|
+ this._ingredients.push(merchantIngredient);
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.home.isPopulated = false;
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ removeIngredient(ingredient){
|
|
|
|
|
+ const index = this._ingredients.indexOf(ingredient);
|
|
|
|
|
+ if(index === undefined){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._ingredients.splice(index, 1);
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.home.isPopulated = false;
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ updateIngredient(ingredient, quantity){
|
|
|
|
|
+ const index = this._ingredients.indexOf(ingredient);
|
|
|
|
|
+ if(index === undefined){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._ingredients[index].quantity = quantity;
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.home.isPopulated = false;
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ getIngredient(id){
|
|
|
|
|
+ for(let i = 0; i < this._ingredients.length; i++){
|
|
|
|
|
+ if(this._ingredients[i].ingredient.id === id){
|
|
|
|
|
+ return this._ingredients[i].ingredient;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get recipes(){
|
|
|
|
|
+ return this._recipes;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addRecipe(recipe){
|
|
|
|
|
+ this._recipes.push(recipe);
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.transactions.isPopulated = false;
|
|
|
|
|
+ this._modules.recipeBook.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ removeRecipe(recipe){
|
|
|
|
|
+ const index = this._recipes.indexOf(recipe);
|
|
|
|
|
+ if(index === undefined){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this._recipes.splice(index, 1);
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.transactions.isPopulated = false;
|
|
|
|
|
+ this._modules.recipeBook.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
- Updates all specified item in the merchant's inventory and updates the page
|
|
|
|
|
- If ingredient doesn't exist, add it
|
|
|
|
|
- ingredients = [{
|
|
|
|
|
- ingredient: Ingredient object,
|
|
|
|
|
- quantity: new quantity,
|
|
|
|
|
- }]
|
|
|
|
|
- remove = set true if removing
|
|
|
|
|
- isOrder = set true if this is coming from an order
|
|
|
|
|
|
|
+ recipe = {
|
|
|
|
|
+ name: required,
|
|
|
|
|
+ price: required,
|
|
|
|
|
+ ingredients: [{
|
|
|
|
|
+ ingredient: id of ingredient,
|
|
|
|
|
+ quantity: quantity of ingredient
|
|
|
|
|
+ }]
|
|
|
|
|
+ }
|
|
|
*/
|
|
*/
|
|
|
- editIngredients(ingredients, remove = false, isOrder = false){
|
|
|
|
|
- for(let i = 0; i < ingredients.length; i++){
|
|
|
|
|
- let isNew = true;
|
|
|
|
|
- for(let j = 0; j < this.ingredients.length; j++){
|
|
|
|
|
- if(this.ingredients[j].ingredient === ingredients[i].ingredient){
|
|
|
|
|
- if(remove && !isOrder){
|
|
|
|
|
- this.ingredients.splice(j, 1);
|
|
|
|
|
- }else if(!remove && isOrder){
|
|
|
|
|
- this.ingredients[j].quantity += ingredients[i].quantity;
|
|
|
|
|
- }else{
|
|
|
|
|
- this.ingredients[j].quantity = ingredients[i].quantity;
|
|
|
|
|
|
|
+ updateRecipe(recipe){
|
|
|
|
|
+ for(let i = 0; i < this._recipes.length; i++){
|
|
|
|
|
+ if(this._recipes[i].id === recipe._id){
|
|
|
|
|
+ this._recipes[i].name = recipe.name;
|
|
|
|
|
+ this._recipes[i].price = recipe.price;
|
|
|
|
|
+
|
|
|
|
|
+ this._recipes[i].removeIngredients();
|
|
|
|
|
+ for(let j = 0; j < recipe.ingredients.length; j++){
|
|
|
|
|
+ for(let k = 0; k < this._ingredients.length; k++){
|
|
|
|
|
+ if(this._ingredients[k].ingredient.id === recipe.ingredients[j].ingredient){
|
|
|
|
|
+ this._recipes[i].addIngredient(
|
|
|
|
|
+ this._ingredients[k].ingredient,
|
|
|
|
|
+ recipe.ingredients[j].quantity
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- isNew = false;
|
|
|
|
|
- break;
|
|
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(isNew){
|
|
|
|
|
- this.ingredients.push({
|
|
|
|
|
- ingredient: ingredients[i].ingredient,
|
|
|
|
|
- quantity: parseFloat(ingredients[i].quantity)
|
|
|
|
|
- });
|
|
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- controller.updateData("ingredient");
|
|
|
|
|
- controller.closeSidebar();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ this._modules.transactions.isPopulated = false;
|
|
|
|
|
+ this._modules.recipeBook.isPopulated = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /*
|
|
|
|
|
- Updates a recipe in the merchants list of recipes
|
|
|
|
|
- Can create, edit or remove
|
|
|
|
|
- recipe = [Recipe object]
|
|
|
|
|
- remove = will remove recipe when true
|
|
|
|
|
- */
|
|
|
|
|
- editRecipes(recipes, remove = false){
|
|
|
|
|
- let isNew = true;
|
|
|
|
|
|
|
+ getTransactions(from = 0, to = new Date()){
|
|
|
|
|
+ if(merchant._transactions.length <= 0){
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for(let i = 0; i < recipes.length; i++){
|
|
|
|
|
- for(let j = 0; j < this.recipes.length; j++){
|
|
|
|
|
- if(recipes[i] === this.recipes[j]){
|
|
|
|
|
- if(remove){
|
|
|
|
|
- this.recipes.splice(j, 1);
|
|
|
|
|
- }else{
|
|
|
|
|
- this.recipes[j] = recipes[i];
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(from === 0){
|
|
|
|
|
+ from = this._transactions[this._transactions.length-1].date;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- isNew = false;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const {start, end} = this.getTransactionIndices(from, to);
|
|
|
|
|
+
|
|
|
|
|
+ return this._transactions.slice(start, end + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ addTransaction(transaction){
|
|
|
|
|
+ this._transactions.push(transaction);
|
|
|
|
|
+ this._transactions.sort((a, b)=>{
|
|
|
|
|
+ if(a.date > b.date){
|
|
|
|
|
+ return -1;
|
|
|
}
|
|
}
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ let ingredients = {};
|
|
|
|
|
+ for(let i = 0; i < transaction.recipes.length; i++){
|
|
|
|
|
+ const recipe = transaction.recipes[i];
|
|
|
|
|
+ for(let j = 0; j < recipe.recipe.ingredients.length; j++){
|
|
|
|
|
+ const ingredient = recipe.recipe.ingredients[i];
|
|
|
|
|
+ if(ingredients[ingredient.ingredient.id]){
|
|
|
|
|
+ ingredients[ingredient.ingredient.id] += recipe.quantity * ingredient.quantity;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ ingredients[ingredient.ingredient.id] = recipe.quantity * ingredient.quantity;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(isNew){
|
|
|
|
|
- this.recipes.push(recipes[i]);
|
|
|
|
|
|
|
+ const keys = Object.keys(ingredients);
|
|
|
|
|
+ for(let i = 0; i < keys.length; i++){
|
|
|
|
|
+ for(let j = 0; j < this._ingredients.length; j++){
|
|
|
|
|
+ if(keys[i] === this._ingredients[j].ingredient.id){
|
|
|
|
|
+ this._ingredients.quantity -= ingredients[keys[i]];
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- controller.updateData("recipe");
|
|
|
|
|
- controller.closeSidebar();
|
|
|
|
|
|
|
+ this._modules.home.isPopulated = false;
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ this._modules.transactions.isPopulated = false;
|
|
|
|
|
+ this._modules.analytics.newData = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /*
|
|
|
|
|
- Updates a list of orders in the merchants list of orders
|
|
|
|
|
- Create/edit/remove
|
|
|
|
|
- orders = [Order object]
|
|
|
|
|
- remove = will remove order when true
|
|
|
|
|
- */
|
|
|
|
|
- editOrders(orders, remove = false){
|
|
|
|
|
- for(let i = 0; i < orders.length; i++){
|
|
|
|
|
- let isNew = true;
|
|
|
|
|
- for(let j = 0; j < this.orders.length; j++){
|
|
|
|
|
- if(orders[i] === this.orders[j]){
|
|
|
|
|
- if(remove){
|
|
|
|
|
- this.orders.splice(j, 1);
|
|
|
|
|
- }else{
|
|
|
|
|
- this.orders[j] = orders[i];
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ removeTransaction(transaction){
|
|
|
|
|
+ const index = this._transactions.indexOf(transaction);
|
|
|
|
|
+ if(index === undefined){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- isNew = false;
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ this._transactions.splice(index, 1);
|
|
|
|
|
+
|
|
|
|
|
+ let ingredients = {};
|
|
|
|
|
+ for(let i = 0; i < transaction.recipes.length; i++){
|
|
|
|
|
+ const recipe = transaction.recipes[i];
|
|
|
|
|
+ for(let j = 0; j < recipe.recipe.ingredients.length; j++){
|
|
|
|
|
+ const ingredient = recipe.recipe.ingredients[i];
|
|
|
|
|
+ if(ingredients[ingredient.ingredient.id]){
|
|
|
|
|
+ ingredients[ingredient.ingredient.id] += ingredient.quantity * recipe.quantity;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ ingredients[ingredient.ingredient.id] = ingredient.quantity * recipe.quantity;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(isNew){
|
|
|
|
|
- this.orders.push(orders[i]);
|
|
|
|
|
|
|
+ const keys = Object.keys(ingredients);
|
|
|
|
|
+ for(let i = 0; i < keys.length; i++){
|
|
|
|
|
+ for(let j = 0; j < this._ingredients.length; j++){
|
|
|
|
|
+ if(keys[i] === this._ingredients[j].ingredient.id){
|
|
|
|
|
+ this._ingredients.quantity += ingredients[keys[i]];
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- controller.updateData("order");
|
|
|
|
|
- controller.closeSidebar();
|
|
|
|
|
|
|
+ this._modules.home.isPopulated = false;
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ this._modules.transactions.isPopulated = false;
|
|
|
|
|
+ this._modules.analytics.newData = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /*
|
|
|
|
|
- transaction = Transaction Object to add
|
|
|
|
|
- ingredients = The ingredients that need to be updated
|
|
|
|
|
- keys = ingredient ids
|
|
|
|
|
- values = quantity to change in grams
|
|
|
|
|
- remove = If true, removes transaction
|
|
|
|
|
- */
|
|
|
|
|
- editTransactions(transaction, ingredients, remove = false, ){
|
|
|
|
|
- let isNew = true;
|
|
|
|
|
- for(let i = 0; i < this.transactions.length; i++){
|
|
|
|
|
- if(this.transactions[i] === transaction){
|
|
|
|
|
- if(remove){
|
|
|
|
|
- this.transactions.splice(i, 1);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ get orders(){
|
|
|
|
|
+ return this._orders;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- isNew = false;
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ addOrder(order, isNew = false){
|
|
|
|
|
+ this._orders.push(order);
|
|
|
|
|
+
|
|
|
|
|
+ if(isNew){
|
|
|
|
|
+ for(let i = 0; i < order.ingredients.length; i++){
|
|
|
|
|
+ for(let j = 0; j < this._ingredients.length; j++){
|
|
|
|
|
+ if(order.ingredients[i] === this._ingredients[j].ingredient){
|
|
|
|
|
+ this._ingredients[j].quantity += order.ingredients[i].quantity;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if(isNew){
|
|
|
|
|
- this.transactions.push(transaction);
|
|
|
|
|
- this.transactions.sort((a, b) => a.date > b.date ? -1 : 1);
|
|
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ this._modules.orders.isPopulated = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ removeOrder(order){
|
|
|
|
|
+ const index = this._orders.indexOf(order);
|
|
|
|
|
+ if(index === undefined){
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let keys = Object.keys(ingredients);
|
|
|
|
|
- for(let i = 0; i < keys.length; i++){
|
|
|
|
|
- for(let j = 0; j < this.ingredients.length; j++){
|
|
|
|
|
- if(this.ingredients[j].ingredient.id === keys[i]){
|
|
|
|
|
- if(remove === false){
|
|
|
|
|
- this.ingredients[j].quantity -= ingredients[keys[i]];
|
|
|
|
|
- }else{
|
|
|
|
|
- this.ingredients[j].quantity += ingredients[keys[i]];
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ this._orders.splice(index, 1);
|
|
|
|
|
|
|
|
- break;
|
|
|
|
|
|
|
+ for(let i = 0; i < order.ingredients.length; i++){
|
|
|
|
|
+ for(let j = 0; j < this._ingredients.length; j++){
|
|
|
|
|
+ if(order.ingredients[i].ingredient === this._ingredients[j].ingredient){
|
|
|
|
|
+ this._ingredients[j].quantity -= order.ingredients[i].quantity;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- controller.updateData("ingredient");
|
|
|
|
|
- controller.updateData("transaction");
|
|
|
|
|
- controller.closeSidebar();
|
|
|
|
|
|
|
+ this._modules.ingredients.isPopulated = false;
|
|
|
|
|
+ this._modules.orders.isPopulated = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- revenue(indices){
|
|
|
|
|
- let total = 0;
|
|
|
|
|
|
|
+ get units(){
|
|
|
|
|
+ return this._units;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for(let i = indices[0]; i <= indices[1]; i++){
|
|
|
|
|
- for(let j = 0; j < this.transactions[i].recipes.length; j++){
|
|
|
|
|
|
|
+ getRevenue(from, to = new Date()){
|
|
|
|
|
+ if(from === 0){
|
|
|
|
|
+ from = this._transactions[0].date;
|
|
|
|
|
+ }
|
|
|
|
|
+ const {start, end} = this.getTransactionIndices(from, to);
|
|
|
|
|
+
|
|
|
|
|
+ let total = 0;
|
|
|
|
|
+ for(let i = start; i <= end; i++){
|
|
|
|
|
+ for(let j = 0; j < this._transactions[i].recipes.length; j++){
|
|
|
for(let k = 0; k < this.recipes.length; k++){
|
|
for(let k = 0; k < this.recipes.length; k++){
|
|
|
- if(this.transactions[i].recipes[j].recipe === this.recipes[k]){
|
|
|
|
|
- total += this.transactions[i].recipes[j].quantity * this.recipes[k].price;
|
|
|
|
|
|
|
+ if(this._transactions[i].recipes[j].recipe === this.recipes[k]){
|
|
|
|
|
+ total += this._transactions[i].recipes[j].quantity * this.recipes[k].price;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -220,20 +434,20 @@ class Merchant{
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
Gets the quantity of each ingredient sold between two dates (dateRange)
|
|
Gets the quantity of each ingredient sold between two dates (dateRange)
|
|
|
- Inputs
|
|
|
|
|
- dateRange: list containing a start date and an end date
|
|
|
|
|
|
|
+ Inputs:
|
|
|
|
|
+ dateRange: list containing a start date and an end date
|
|
|
Return:
|
|
Return:
|
|
|
[{
|
|
[{
|
|
|
ingredient: Ingredient object,
|
|
ingredient: Ingredient object,
|
|
|
- quantity: quantity of ingredient sold
|
|
|
|
|
|
|
+ quantity: quantity of ingredient sold in default unit
|
|
|
}]
|
|
}]
|
|
|
*/
|
|
*/
|
|
|
- ingredientsSold(dateRange){
|
|
|
|
|
- if(!dateRange){
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ getIngredientsSold(from = 0, to = new Date()){
|
|
|
|
|
+ if(from = 0){
|
|
|
|
|
+ from = this._ingredients[0].date;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let recipes = this.recipesSold(dateRange);
|
|
|
|
|
|
|
+ let recipes = this.getRecipesSold(from, to);
|
|
|
let ingredientList = [];
|
|
let ingredientList = [];
|
|
|
|
|
|
|
|
for(let i = 0; i < recipes.length; i++){
|
|
for(let i = 0; i < recipes.length; i++){
|
|
@@ -244,7 +458,6 @@ class Merchant{
|
|
|
if(ingredientList[k].ingredient === recipes[i].recipe.ingredients[j].ingredient){
|
|
if(ingredientList[k].ingredient === recipes[i].recipe.ingredients[j].ingredient){
|
|
|
exists = true;
|
|
exists = true;
|
|
|
ingredientList[k].quantity += recipes[i].quantity * recipes[i].recipe.ingredients[j].quantity;
|
|
ingredientList[k].quantity += recipes[i].quantity * recipes[i].recipe.ingredients[j].quantity;
|
|
|
- break;
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -260,14 +473,27 @@ class Merchant{
|
|
|
return ingredientList;
|
|
return ingredientList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- singleIngredientSold(dateRange, ingredient){
|
|
|
|
|
- let total = 0;
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ Gets the quantity of a single ingredient sold between two dates
|
|
|
|
|
+ Inputs:
|
|
|
|
|
+ ingredient = MerchantIngredient object to find
|
|
|
|
|
+ from = start Date
|
|
|
|
|
+ to = end Date
|
|
|
|
|
+ return: quantity sold in default unit
|
|
|
|
|
+ */
|
|
|
|
|
+ getSingleIngredientSold(ingredient, from = 0, to = new Date()){
|
|
|
|
|
+ if(from === 0){
|
|
|
|
|
+ from = this._transactions[0].date;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for(let i = dateRange[0]; i < dateRange[1]; i++){
|
|
|
|
|
- for(let j = 0; j < this.transactions[i].recipes.length; j++){
|
|
|
|
|
- for(let k = 0; k < this.transactions[i].recipes[j].recipe.ingredients.length; k++){
|
|
|
|
|
- if(this.transactions[i].recipes[j].recipe.ingredients[k].ingredient === ingredient.ingredient){
|
|
|
|
|
- total += this.transactions[i].recipes[j].recipe.ingredients[k].quantity;
|
|
|
|
|
|
|
+ const {start, end} = this.getTransactionIndices(from, to);
|
|
|
|
|
+
|
|
|
|
|
+ let total = 0;
|
|
|
|
|
+ for(let i = start; i < end; i++){
|
|
|
|
|
+ for(let j = 0; j < this._transactions[i].recipes.length; j++){
|
|
|
|
|
+ for(let k = 0; k < this._transactions[i].recipes[j].recipe.ingredients.length; k++){
|
|
|
|
|
+ if(this._transactions[i].recipes[j].recipe.ingredients[k].ingredient === ingredient.ingredient){
|
|
|
|
|
+ total += this._transactions[i].recipes[j].recipe.ingredients[k].quantity;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -287,24 +513,29 @@ class Merchant{
|
|
|
quantity: quantity of the recipe sold
|
|
quantity: quantity of the recipe sold
|
|
|
}]
|
|
}]
|
|
|
*/
|
|
*/
|
|
|
- recipesSold(dateRange){
|
|
|
|
|
- let recipeList = [];
|
|
|
|
|
|
|
+ getRecipesSold(from = 0, to = new Date()){
|
|
|
|
|
+ if(from = 0){
|
|
|
|
|
+ from = this._transactions[0].date;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const {start, end} = this.getTransactionIndices(from, to);
|
|
|
|
|
|
|
|
- for(let i = dateRange[0]; i <= dateRange[1]; i++){
|
|
|
|
|
- for(let j = 0; j < this.transactions[i].recipes.length; j++){
|
|
|
|
|
|
|
+ let recipeList = [];
|
|
|
|
|
+ for(let i = start; i <= end; i++){
|
|
|
|
|
+ for(let j = 0; j < this._transactions[i].recipes.length; j++){
|
|
|
let exists = false;
|
|
let exists = false;
|
|
|
for(let k = 0; k < recipeList.length; k++){
|
|
for(let k = 0; k < recipeList.length; k++){
|
|
|
- if(recipeList[k].recipe === this.transactions[i].recipes[j].recipe){
|
|
|
|
|
|
|
+ if(recipeList[k].recipe === this._transactions[i].recipes[j].recipe){
|
|
|
exists = true;
|
|
exists = true;
|
|
|
- recipeList[k].quantity += this.transactions[i].recipes[j].quantity;
|
|
|
|
|
|
|
+ recipeList[k].quantity += this._transactions[i].recipes[j].quantity;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(!exists){
|
|
if(!exists){
|
|
|
recipeList.push({
|
|
recipeList.push({
|
|
|
- recipe: this.transactions[i].recipes[j].recipe,
|
|
|
|
|
- quantity: this.transactions[i].recipes[j].quantity
|
|
|
|
|
|
|
+ recipe: this._transactions[i].recipes[j].recipe,
|
|
|
|
|
+ quantity: this._transactions[i].recipes[j].quantity
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -317,7 +548,7 @@ class Merchant{
|
|
|
Groups all of the merchant's ingredients by their category
|
|
Groups all of the merchant's ingredients by their category
|
|
|
Return: [{
|
|
Return: [{
|
|
|
name: category name,
|
|
name: category name,
|
|
|
- ingredients: [Ingredient Object]
|
|
|
|
|
|
|
+ ingredients: [MerchantIngredient Object]
|
|
|
}]
|
|
}]
|
|
|
*/
|
|
*/
|
|
|
categorizeIngredients(){
|
|
categorizeIngredients(){
|
|
@@ -381,16 +612,55 @@ class Merchant{
|
|
|
getRecipesForIngredient(ingredient){
|
|
getRecipesForIngredient(ingredient){
|
|
|
let recipes = [];
|
|
let recipes = [];
|
|
|
|
|
|
|
|
- for(let i = 0; i < this.recipes.length; i++){
|
|
|
|
|
- for(let j = 0; j < this.recipes[i].ingredients.length; j++){
|
|
|
|
|
- if(this.recipes[i].ingredients[j].ingredient === ingredient){
|
|
|
|
|
- recipes.push(this.recipes[i]);
|
|
|
|
|
|
|
+ for(let i = 0; i < this._recipes.length; i++){
|
|
|
|
|
+ for(let j = 0; j < this._recipes[i].ingredients.length; j++){
|
|
|
|
|
+ if(this._recipes[i].ingredients[j].ingredient === ingredient){
|
|
|
|
|
+ recipes.push(this._recipes[i]);
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return recipes;
|
|
return recipes;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ getTransactionIndices(from, to){
|
|
|
|
|
+ let start, end;
|
|
|
|
|
+ to.setDate(to.getDate() + 1);
|
|
|
|
|
+
|
|
|
|
|
+ for(let i = this._transactions.length - 1; i >= 0; i--){
|
|
|
|
|
+ if(this._transactions[i].date >= from){
|
|
|
|
|
+ start = i;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for(let i = 0; i < this._transactions.length; i++){
|
|
|
|
|
+ if(this._transactions[i].date < to){
|
|
|
|
|
+ end = i;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(start === undefined){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //these are switched due to the order of the transactions in the merchant
|
|
|
|
|
+ return {start: end, end: start};
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ isSanitaryString(str){
|
|
|
|
|
+ let disallowed = ["\\", "<", ">", "$", "{", "}", "(", ")"];
|
|
|
|
|
+
|
|
|
|
|
+ for(let i = 0; i < disallowed.length; i++){
|
|
|
|
|
+ if(str.includes(disallowed[i])){
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
module.exports = Merchant;
|
|
module.exports = Merchant;
|