Sfoglia il codice sorgente

Merge branch 'updateUnits' into development

Lee Morgan 6 anni fa
parent
commit
cd5c2901e9

+ 5 - 3
controllers/ingredientData.js

@@ -22,9 +22,10 @@ module.exports = {
         ingredient: {
             name: name of ingredient,
             category: category of ingredient,
-            unit: unit measurement of ingredient
+            unitType: category for the unit (mass, volume, length)
         },
-        quantity: quantity of ingredient for current merchant
+        quantity: quantity of ingredient for current merchant,
+        defaultUnit: default unit of measurement to display
     }
     Returns:
         Same as above, with the _id
@@ -52,7 +53,8 @@ module.exports = {
             .then((response)=>{
                 newIngredient = {
                     ingredient: response[0],
-                    quantity: req.body.quantity
+                    quantity: req.body.quantity,
+                    defaultUnit: req.body.defaultUnit
                 }
 
                 response[1].inventory.push(newIngredient);

+ 28 - 1
controllers/merchantData.js

@@ -162,6 +162,7 @@ module.exports = {
     req.body = [{
         id: ingredient id,
         quantity: quantity of ingredient for the merchant
+        defaultUnit: default unit of measurement to display
     }]
     */
     addMerchantIngredient: function(req, res){
@@ -190,7 +191,8 @@ module.exports = {
                     
                     merchant.inventory.push({
                         ingredient: req.body[i].id,
-                        quantity: req.body[i].quantity
+                        quantity: req.body[i].quantity,
+                        defaultUnit: req.body[i].defaultUnit
                     });
                 }
 
@@ -236,6 +238,31 @@ module.exports = {
             });
     },
 
+    //PUT - Update the default unit for a single ingredient
+    ingredientDefaultUnit: function(req, res){
+        if(!req.session.user){
+            req.session.error = "MUST BE LOGGED IN TO DO THAT";
+            return res.redirect("/");
+        }
+
+        Merchant.findOne({_id: req.session.user})
+            .then((merchant)=>{
+                for(let i = 0; i < merchant.inventory.length; i++){
+                    if(merchant.inventory[i].ingredient.toString() === req.params.id){
+                        merchant.inventory[i].defaultUnit =req.params.unit;
+                    }
+                }
+
+                return merchant.save()
+            })
+            .then((merchant)=>{
+                return res.json({});
+            })
+            .catch((err)=>{
+                return res.json("ERROR: UNABLE TO UPDATE DEFAULT UNIT");
+            });
+    },
+
     /*
     POST - Update the quantity for a merchant inventory item
     req.body = [{

+ 1 - 1
controllers/validator.js

@@ -61,7 +61,7 @@ module.exports = {
     },
 
     ingredient: function(ingredient){
-        if(!this.isSanitary([ingredient.name, ingredient.category, ingredient.unit])){
+        if(!this.isSanitary([ingredient.name, ingredient.category])){
             return "Ingredient contains illegal characters";
         }
 

+ 5 - 5
models/ingredient.js

@@ -3,16 +3,16 @@ const mongoose = require("mongoose");
 const IngredientSchema = new mongoose.Schema({
     name: {
         type: String,
-        minlength: [2, "Name of ingredient is too short.  Please have at least two characters"],
-        required: [true, "Must provide a name for the ingredient"]
+        minlength: 2,
+        required: true
     },
     category: {
         type: String,
-        minlength: [3, "Category name must contain at least three characters"]
+        minlength: 3
     },
-    unit: {
+    unitType: {
         type: String,
-        required: [true, "You must provide the measurement unit for this item"]
+        required: true
     }
 });
 

+ 6 - 2
models/merchant.js

@@ -8,7 +8,7 @@ const MerchantSchema = new mongoose.Schema({
     email: String,
     password: {
         type: String,
-        minlength: [15, "Password must contain at least 15 characters"]
+        minlength: 15
     },
     pos: {
         type: String,
@@ -37,7 +37,11 @@ const MerchantSchema = new mongoose.Schema({
         quantity: {
             type: Number,
             required: true,
-            min: [0, "Quantity cannot be less than 0"]
+            min: 0
+        },
+        defaultUnit: {
+            type: String,
+            required: true
         }
     }],
     recipes: [{

+ 1 - 0
routes.js

@@ -19,6 +19,7 @@ module.exports = function(app){
     app.delete("/merchant/recipes/remove/:id", merchantData.removeRecipe);
     app.post("/merchant/ingredients/add", merchantData.addMerchantIngredient);
     app.delete("/merchant/ingredients/remove/:id", merchantData.removeMerchantIngredient);
+    app.put("/merchant/ingredients/update/:id/:unit", merchantData.ingredientDefaultUnit);
     app.put("/merchant/ingredients/update", merchantData.updateMerchantIngredient);
     app.post("/merchant/password", merchantData.updatePassword);
 

+ 118 - 4
views/dashboardPage/Merchant.js

@@ -1,9 +1,44 @@
 class Ingredient{
-    constructor(id, name, category, unit){
+    constructor(id, name, category, unitType, unit, parent){
         this.id = id;
         this.name = name;
         this.category = category;
+        this.unitType = unitType;
         this.unit = unit;
+        this.parent = parent;
+    }
+
+    convert(quantity){
+        if(this.unitType === "mass"){
+            switch(this.unit){
+                case "g": break;
+                case "kg": quantity /= 1000; break;
+                case "oz":  quantity /= 28.3495; break;
+                case "lb":  quantity /= 453.5924; break;
+            }
+        }else if(this.unitType === "volume"){
+            switch(this.unit){
+                case "ml": quantity *= 1000; break;
+                case "l": break;
+                case "tsp": quantity *= 202.8842; break;
+                case "tbsp": quantity *= 67.6278; break;
+                case "ozfl": quantity *= 33.8141; break;
+                case "cup": quantity *= 4.1667; break;
+                case "pt": quantity *= 2.1134; break;
+                case "qt": quantity *= 1.0567; break;
+                case "gal": quantity /= 3.7854; break;
+            }
+        }else if(this.unitType === "length"){
+            switch(this.unit){
+                case "mm": quantity *= 1000; break;
+                case "cm": quantity *= 100; break;
+                case "m": break;
+                case "in": quantity *= 39.3701; break;
+                case "ft": quantity *= 3.2808; break;
+            }
+        }
+
+        return quantity;
     }
 }
 
@@ -70,6 +105,39 @@ class Order{
             }
         }
     }
+
+    convertPrice(unitType, unit, price){
+        if(unitType === "mass"){
+            switch(unit){
+                case "g": break;
+                case "kg": price *= 1000; break;
+                case "oz":  price *= 28.3495; break;
+                case "lb":  price *= 453.5924; break;
+            }
+        }else if(unitType === "volume"){
+            switch(unit){
+                case "ml": price /= 1000; break;
+                case "l": break;
+                case "tsp": price /= 202.8842; break;
+                case "tbsp": price /= 67.6278; break;
+                case "ozfl": price /= 33.8141; break;
+                case "cup": price /= 4.1667; break;
+                case "pt": price /= 2.1134; break;
+                case "qt": price /= 1.0567; break;
+                case "gal": price *= 3.7854; break;
+            }
+        }else if(unitType === "length"){
+            switch(unit){
+                case "mm": price /= 1000; break;
+                case "cm": price /= 100; break;
+                case "m": break;
+                case "in": price /= 39.3701; break;
+                case "ft": price /= 3.2808; break;
+            }
+        }
+
+        return price;
+    }
 }
 
 class Merchant{
@@ -80,6 +148,11 @@ class Merchant{
         this.recipes = [];
         this.transactions = [];
         this.orders = [];
+        this.units = {
+            mass: ["g", "kg", "oz", "lb"],
+            volume: ["ml", "l", "tsp", "tbsp", "ozfl", "cup", "pt", "qt", "gal"],
+            length: ["mm", "cm", "m", "in", "foot"]
+        }
         
         for(let i = 0; i < oldMerchant.inventory.length; i++){
             this.ingredients.push({
@@ -87,7 +160,9 @@ class Merchant{
                     oldMerchant.inventory[i].ingredient._id,
                     oldMerchant.inventory[i].ingredient.name,
                     oldMerchant.inventory[i].ingredient.category,
-                    oldMerchant.inventory[i].ingredient.unit,
+                    oldMerchant.inventory[i].ingredient.unitType,
+                    oldMerchant.inventory[i].defaultUnit,
+                    this
                 ),
                 quantity: oldMerchant.inventory[i].quantity
             });
@@ -118,7 +193,8 @@ class Merchant{
     If ingredient doesn't exist, add it
     ingredients = {
         ingredient: Ingredient object,
-        quantity: new quantity
+        quantity: new quantity,
+        defaultUnit: the default unit to be displayed
     }
     remove = set true if removing
     isOrder = set true if this is coming from an order
@@ -144,7 +220,8 @@ class Merchant{
             if(isNew){
                 merchant.ingredients.push({
                     ingredient: ingredients[i].ingredient,
-                    quantity: parseFloat(ingredients[i].quantity)
+                    quantity: parseFloat(ingredients[i].quantity),
+                    defaultUnit: ingredients[i].defaultUnit
                 });
             }
         }
@@ -485,4 +562,41 @@ class Merchant{
 
         return recipes;
     }
+}
+
+let convertToMain = (unit, quantity)=>{
+    let converted = 0;
+
+    if(merchant.units.mass.includes(unit)){
+        switch(unit){
+            case "g": break;
+            case "kg": converted = quantity * 1000; break;
+            case "oz": converted = quantity * 28.3495; break;
+            case "lb": converted = quantity * 453.5924; break;
+        }
+    }else if(merchant.units.volume.includes(unit)){
+        switch(unit){
+            case "ml": converted = quantity / 1000; break;
+            case "l": break;
+            case "tsp": converted = quantity / 202.8842; break;
+            case "tbsp": converted = quantity / 67.6278; break;
+            case "ozfl": converted = quantity / 33.8141; break;
+            case "cup": converted = quantity / 4.1667; break;
+            case "pt": converted = quantity / 2.1134; break;
+            case "qt": converted = quantity / 1.0567; break;
+            case "gal": converted = quantity * 3.7854; break;
+        }
+    }else if(merchant.units.length.includes(unit)){
+        switch(unit){
+            case "mm": converted = quantity / 1000; break;
+            case "cm": converted = quantity / 100; break;
+            case "m": break;
+            case "in": converted = quantity / 39.3701; break;
+            case "ft": converted = quantity / 3.2808; break;
+        }
+    }else{
+        converted = quantity;
+    }
+
+    return converted;
 }

+ 31 - 19
views/dashboardPage/home.js

@@ -1,12 +1,16 @@
 window.homeStrandObj = {
     isPopulated: false,
     graph: {},
+    popularWidth: 0,
+    popularHeight: 0,
 
     display: function(){
         if(!this.isPopulated){
             this.drawRevenueCard();
             this.drawRevenueGraph();
             this.drawInventoryCheckCard();
+            this.popularWidth = document.getElementById("popularIngredientsCard").offsetWidth;
+            this.popularHeight = document.getElementById("popularIngredientsCard").offsetHeight;
             this.drawPopularCard();
 
             this.isPopulated = true;
@@ -96,7 +100,7 @@ window.homeStrandObj = {
             ingredientCheck.ingredient = merchant.ingredients[rands[i]];
             ingredientCheck.children[0].innerText = merchant.ingredients[rands[i]].ingredient.name;
             ingredientCheck.children[1].children[0].onclick = ()=>{input.value--};
-            input.value = merchant.ingredients[rands[i]].quantity;
+            input.value = merchant.ingredients[rands[i]].quantity.toFixed(2);
             ingredientCheck.children[1].children[2].onclick = ()=>{input.value++}
             ingredientCheck.children[2].innerText = merchant.ingredients[rands[i]].ingredient.unit.toUpperCase();
 
@@ -110,29 +114,37 @@ window.homeStrandObj = {
         let thisMonth = new Date(now.getFullYear(), now.getMonth(), 1);
 
         let ingredientList = merchant.ingredientsSold(merchant.transactionIndices(thisMonth));
-        if(ingredientList){
-            for(let i = 0; i < 5; i++){
-                let max = ingredientList[0].quantity
-                let index = 0;
-                for(let j = 0; j < ingredientList.length; j++){
-                    if(ingredientList[j].quantity > max){
-                        max = ingredientList[j].quantity;
-                        index = j;
+        window.ingredientList = [...ingredientList];
+        let iterations = (ingredientList.length < 5) ? ingredientList.length : 5;
+        if(ingredientList.length > 0){
+            for(let i = 0; i < iterations; i++){
+                try{
+                    let max = ingredientList[0].quantity;
+                    let index = 0;
+                    for(let j = 0; j < ingredientList.length; j++){
+                        if(ingredientList[j].quantity > max){
+                            max = ingredientList[j].quantity;
+                            index = j;
+                        }
                     }
-                }
 
-                dataArray.push({
-                    num: max,
-                    label: `${ingredientList[index].ingredient.name}: ${+ingredientList[index].quantity.toFixed(2)} ${ingredientList[index].ingredient.unit}`
-                });
-                ingredientList.splice(index, 1);
+                    dataArray.push({
+                        num: max,
+                        label: ingredientList[index].ingredient.name + ": " +
+                        ingredientList[index].ingredient.convert(ingredientList[index].quantity).toFixed(2) +
+                        " " + ingredientList[index].ingredient.unit
+                    });
+                    ingredientList.splice(index, 1);
+                }catch(err){
+                    break;
+                }
             }
 
-            let thisCanvas = document.querySelector("#popularCanvas");
-            thisCanvas.width = thisCanvas.parentElement.clientWidth * 0.9;
-            thisCanvas.height = thisCanvas.parentElement.clientHeight * 0.75;
+            let thisCanvas = document.getElementById("popularCanvas");
+            thisCanvas.width = this.popularWidth;
+            thisCanvas.height = this.popularHeight;
 
-            let popularGraph = new HorizontalBarGraph(document.querySelector("#popularCanvas"));
+            let popularGraph = new HorizontalBarGraph(thisCanvas);
             popularGraph.addData(dataArray);
         }else{
             document.querySelector("#popularCanvas").style.display = "none";

+ 1 - 1
views/dashboardPage/ingredients.js

@@ -39,7 +39,7 @@ window.ingredientsStrandObj = {
                 let ingredientDiv = ingredientTemplate.cloneNode(true);
 
                 ingredientDiv.children[0].innerText = ingredient.ingredient.name;
-                ingredientDiv.children[2].innerText = `${ingredient.quantity} ${ingredient.ingredient.unit}`;
+                ingredientDiv.children[2].innerText = `${ingredient.ingredient.convert(ingredient.quantity).toFixed(2)} ${ingredient.ingredient.unit.toUpperCase()}`;
                 ingredientDiv.onclick = ()=>{ingredientDetailsComp.display(ingredient)};
                 ingredientDiv._name = ingredient.ingredient.name.toLowerCase();
                 ingredientDiv._unit = ingredient.ingredient.unit.toLowerCase();

+ 34 - 0
views/dashboardPage/sidebars/addIngredients.ejs

@@ -49,6 +49,40 @@
     <template id="addIngredientsIngredient">
         <div class="addIngredientsIngredient">
             <p></p>
+
+            <select id="addUnitSelector" style="display: none;">
+                <optgroup label="MASS/WEIGHT">
+                    <option type="mass" value="g">G</option>
+                    <option type="mass" value="kg">KG</option>
+                    <option type="mass" value="oz">OZ</option>
+                    <option type="mass" value="lb">LB</option>
+                </optgroup>
+    
+                <optgroup label="VOLUME">
+                    <option type="volume" value="ml">ML</option>
+                    <option type="volume" value="l">L</option>
+                    <option type="volume" value="tsp">TSP</option>
+                    <option type="volume" value="tbsp">TBSP</option>
+                    <option type="volume" value="ozfl">OZ. FL</option>
+                    <option type="volume" value="cup">CUP</option>
+                    <option type="volume" value="pt">PT</option>
+                    <option type="volume" value="qt">QT</option>
+                    <option type="volume" value="gal">GAL</option>
+                </optgroup>
+    
+                <optgroup label="LENGTH">
+                    <option type="length" value="mm">MM</option>
+                    <option type="length" value="cm">CM</option>
+                    <option type="length" value="m">M</option>
+                    <option type="length" value="in">IN</option>
+                    <option type="length" value="ft">FT</option>
+                </optgroup>
+    
+                <optgroup label="OTHER">
+                    <option value="count">count</option>
+                </optgroup>
+            </select>
+            
             <button class="addButton">+</button>
         </div>
     </template>

+ 8 - 0
views/dashboardPage/sidebars/ingredientDetails.ejs

@@ -45,5 +45,13 @@
         <ul id="ingredientRecipeList"></ul>
     </label>
 
+    <div class="lineBorder"></div>
+
+    <label>DISPLAY UNIT:</label>
+
+    <div id="ingredientButtons" class="ingredientButtons"></div>
+
+    <button id="defaultUnit" class="button" onclick="ingredientDetailsComp.changeUnitDefault()">SET DEFAULT</button>
+
     <button id="editSubmitButton" class="button" onclick="ingredientDetailsComp.editSubmit()" style="display: none;">SAVE CHANGES</button>
 </div>

+ 32 - 1
views/dashboardPage/sidebars/newIngredient.ejs

@@ -23,7 +23,38 @@
     </label>
 
     <label>UNIT:
-        <input id="newIngUnit" type="text">
+        <select id="unitSelector">
+            <optgroup label="MASS/WEIGHT">
+                <option type="mass" value="g">G</option>
+                <option type="mass" value="kg">KG</option>
+                <option type="mass" value="oz">OZ</option>
+                <option type="mass" value="lb">LB</option>
+            </optgroup>
+
+            <optgroup label="VOLUME">
+                <option type="volume" value="ml">ML</option>
+                <option type="volume" value="l">L</option>
+                <option type="volume" value="tsp">TSP</option>
+                <option type="volume" value="tbsp">TBSP</option>
+                <option type="volume" value="ozfl">OZ. FL</option>
+                <option type="volume" value="cup">CUP</option>
+                <option type="volume" value="pt">PT</option>
+                <option type="volume" value="qt">QT</option>
+                <option type="volume" value="gal">GAL</option>
+            </optgroup>
+
+            <optgroup label="LENGTH">
+                <option type="length" value="mm">MM</option>
+                <option type="length" value="cm">CM</option>
+                <option type="length" value="m">M</option>
+                <option type="length" value="in">IN</option>
+                <option type="length" value="ft">FT</option>
+            </optgroup>
+
+            <optgroup label="OTHER">
+                <option value="count">count</option>
+            </optgroup>
+        </select>
     </label>
 
     <button class="button" onclick="newIngredientComp.submit()">CREATE</button>

+ 29 - 5
views/dashboardPage/sidebars/sidebars.css

@@ -281,19 +281,19 @@ Add Ingredients
 
             .addIngredientsIngredient{
                 display: flex;
-                justify-content: left;
+                justify-content: space-between;
                 align-items: center;
                 margin: 5px;
             }
 
-                .addIngredientsIngredient > *:nth-child(2){
-                    margin-left: auto;
-                }
-
                 .addIngredientsIngredient input[type=number]{
                     width: 100px;
                 }
 
+                .addIngredientsIngredient select{
+                    width: 60px;
+                }
+
                 .addButton{
                     display: flex;
                     align-items: center;
@@ -340,6 +340,25 @@ Ingredient Details
         padding: 10px;
     }
 
+    .unitButton{
+        margin: 5px;
+        padding: 5px;
+        background: none;
+        border: 1px solid black;
+        font-size: 25px;
+        cursor: pointer;
+        border-radius: 5px;
+    }
+
+        .unitButton:hover{
+            background: rgb(0, 27, 45);
+            color: white;
+        }
+
+        .unitActive{
+            background: rgb(255, 99, 107);
+        }
+
 /* 
 Recipe Details 
 */
@@ -463,6 +482,10 @@ Add Recipe
                 margin-bottom: 2px;
             }
 
+            #recipeInputIngredients input{
+                width: 100px;
+            }
+
             #recipeInputIngredients div h4{
                 color: rgb(255, 99, 107);
             }
@@ -491,6 +514,7 @@ Add Recipe
 
     #newOrderAdded{
         max-height: 25%;
+        width: 100%;
         overflow: auto;
     }
 

+ 135 - 51
views/dashboardPage/sidebars/sidebars.js

@@ -19,7 +19,7 @@ let recipeDetailsComp = {
             ingredientDiv = template.cloneNode(true);
 
             ingredientDiv.children[0].innerText = recipe.ingredients[i].ingredient.name;
-            ingredientDiv.children[2].innerText = `${recipe.ingredients[i].quantity} ${recipe.ingredients[i].ingredient.unit}`;
+            ingredientDiv.children[2].innerText = `${recipe.ingredients[i].ingredient.convert(recipe.ingredients[i].quantity).toFixed(2)} ${recipe.ingredients[i].ingredient.unit}`;
             ingredientDiv.ingredient = recipe.ingredients[i].ingredient;
             ingredientDiv.name = recipe.ingredients[i].ingredient.name;
 
@@ -57,15 +57,12 @@ let recipeDetailsComp = {
 
             div.children[2].innerText = this.recipe.ingredients[i].ingredient.unit;
             div.children[1].style.display = "block";
-            div.children[1].value = parseFloat(this.recipe.ingredients[i].quantity);
+            div.children[1].value = this.recipe.ingredients[i].ingredient.convert(this.recipe.ingredients[i].quantity).toFixed(2);
             div.children[3].style.display = "block";
             div.children[3].onclick = ()=>{div.parentElement.removeChild(div)};
         }
 
         document.querySelector("#addRecIng").style.display = "flex";
-
-        
-
         document.querySelector("#recipeUpdate").style.display = "flex";
     },
 
@@ -80,12 +77,12 @@ let recipeDetailsComp = {
                 let select = divs[i].children[0];
                 this.recipe.ingredients.push({
                     ingredient: select.options[select.selectedIndex].ingredient,
-                    quantity: divs[i].children[1].value
+                    quantity: convertToMain(select.options[select.selectedIndex].ingredient.unit, divs[i].children[1].value)
                 });
             }else{
                 this.recipe.ingredients.push({
                     ingredient: divs[i].ingredient,
-                    quantity: divs[i].children[1].value
+                    quantity: convertToMain(divs[i].ingredient.unit, divs[i].children[1].value)
                 });
             }
         }
@@ -196,7 +193,7 @@ let newOrderComp = {
                     let ingredientDiv = ingredientTemplate.cloneNode(true);
     
                     ingredientDiv.children[0].innerText = categories[i].ingredients[j].ingredient.name;
-                    ingredientDiv.children[1].onclick = ()=>{this.addOne(ingredientDiv, category.children[1])};
+                    ingredientDiv.children[2].onclick = ()=>{this.addOne(ingredientDiv, category.children[1])};
                     ingredientDiv.ingredient = categories[i].ingredients[j].ingredient;
     
                     this.unused.push(categories[i].ingredients[j]);
@@ -220,7 +217,7 @@ let newOrderComp = {
 
         let quantityInput = document.createElement("input");
         quantityInput.type = "number";
-        quantityInput.placeholder = ingredientDiv.ingredient.unit;
+        quantityInput.placeholder = `QUANTITY (${ingredientDiv.ingredient.unit})`;
         quantityInput.min = "0";
         quantityInput.step = "0.01";
         ingredientDiv.insertBefore(quantityInput, ingredientDiv.children[1]);
@@ -232,8 +229,8 @@ let newOrderComp = {
         priceInput.step = "0.01";
         ingredientDiv.insertBefore(priceInput, ingredientDiv.children[2]);
 
-        ingredientDiv.children[3].innerText = "-";
-        ingredientDiv.children[3].onclick = ()=>{this.removeOne(ingredientDiv, container)};
+        ingredientDiv.children[4].innerText = "-";
+        ingredientDiv.children[4].onclick = ()=>{this.removeOne(ingredientDiv, container)};
 
         container.removeChild(ingredientDiv);
         document.getElementById("newOrderAdded").appendChild(ingredientDiv);
@@ -259,11 +256,12 @@ let newOrderComp = {
             let quantity = categoriesList.children[i].children[1].value;
             let price = categoriesList.children[i].children[2].value;
 
+            let fakeOrder = new Order(undefined, undefined, new Date(), [], undefined);
             if(quantity !== ""  && price !== ""){
                 ingredients.push({
                     ingredient: categoriesList.children[i].ingredient.id,
-                    quantity: parseFloat(quantity),
-                    price: parseInt(price * 100)
+                    quantity: convertToMain(categoriesList.children[i].ingredient.unit, parseFloat(quantity)),
+                    price: categoriesList.children[i].ingredient.convert(parseInt(price * 100))
                 });
             }
         }
@@ -272,7 +270,7 @@ let newOrderComp = {
             name: document.getElementById("orderName").value,
             date: document.getElementById("orderDate").value,
             ingredients: ingredients
-        }
+        };
 
         let loader = document.getElementById("loaderContainer");
         loader.style.display = "flex";
@@ -318,17 +316,22 @@ let newIngredientComp = {
         document.querySelector("#newIngName").value = "";
         document.querySelector("#newIngCategory").value = "";
         document.querySelector("#newIngQuantity").value = 0;
-        document.querySelector("#newIngUnit").value = ""
     },
 
     submit: function(){
+        let unitSelector = document.getElementById("unitSelector");
+        let options = document.querySelectorAll("#unitSelector option");
+
+        let unit = unitSelector.value;
+
         let newIngredient = {
             ingredient: {
-                name: document.querySelector("#newIngName").value,
-                category: document.querySelector("#newIngCategory").value,
-                unit: document.querySelector("#newIngUnit").value
+                name: document.getElementById("newIngName").value,
+                category: document.getElementById("newIngCategory").value,
+                unitType: options[unitSelector.selectedIndex].getAttribute("type"),
             },
-            quantity: document.querySelector("#newIngQuantity").value
+            quantity: convertToMain(unit, document.querySelector("#newIngQuantity").value),
+            defaultUnit: unit
         }
 
         let loader = document.getElementById("loaderContainer");
@@ -351,7 +354,9 @@ let newIngredientComp = {
                             response.ingredient._id,
                             response.ingredient.name,
                             response.ingredient.category,
-                            response.ingredient.unit
+                            response.ingredient.unitType,
+                            response.defaultUnit,
+                            merchant
                         ),
                         quantity: response.quantity
                     }]);
@@ -385,15 +390,19 @@ let orderDetailsComp = {
         let template = document.querySelector("#orderIngredient").content.children[0];
         let grandTotal = 0;
         for(let i = 0; i < order.ingredients.length; i++){
-            let ingredient = template.cloneNode(true);
+            let ingredientDiv = template.cloneNode(true);
             let price = (order.ingredients[i].quantity * order.ingredients[i].price) / 100;
             grandTotal += price;
 
-            ingredient.children[0].innerText = order.ingredients[i].ingredient.name;
-            ingredient.children[1].innerText = `${order.ingredients[i].quantity} x $${(order.ingredients[i].price / 100).toFixed(2)}`;
-            ingredient.children[2].innerText = `$${price.toFixed(2)}`;
+            let ingredient = order.ingredients[i].ingredient;
+            let priceText = ingredient.convert(order.ingredients[i].quantity).toFixed(2) + " " + 
+                ingredient.unit.toUpperCase() + " x $" +
+                (order.convertPrice(ingredient.unitType, ingredient.unit, order.ingredients[i].price) / 100).toFixed(2);
+            ingredientDiv.children[0].innerText = order.ingredients[i].ingredient.name;
+            ingredientDiv.children[1].innerText = priceText;
+            ingredientDiv.children[2].innerText = `$${price.toFixed(2)}`;
 
-            ingredientList.appendChild(ingredient);
+            ingredientList.appendChild(ingredientDiv);
         }
 
         document.querySelector("#orderTotalPrice p").innerText = `$${grandTotal.toFixed(2)}`;
@@ -457,8 +466,7 @@ let addIngredientsComp = {
                         for(let i = 0; i < response.length; i++){
                             response[i] = {ingredient: response[i]}
                         }
-                        this.fakeMerchant = new Merchant(
-                            {
+                        this.fakeMerchant = new Merchant({
                                 name: "none",
                                 inventory: response,
                                 recipes: [],
@@ -504,7 +512,7 @@ let addIngredientsComp = {
             for(let j = 0; j < categories[i].ingredients.length; j++){
                 let ingredientDiv = ingredientTemplate.content.children[0].cloneNode(true);
                 ingredientDiv.children[0].innerText = categories[i].ingredients[j].ingredient.name;
-                ingredientDiv.children[1].onclick = ()=>{this.addOne(ingredientDiv)};
+                ingredientDiv.children[2].onclick = ()=>{this.addOne(ingredientDiv)};
                 ingredientDiv.ingredient = categories[i].ingredients[j].ingredient;
 
                 categoryDiv.children[1].appendChild(ingredientDiv);
@@ -546,20 +554,23 @@ let addIngredientsComp = {
         input.type = "number";
         input.min = "0";
         input.step = "0.01";
-        input.placeholder = element._unit;
+        input.placeholder = "QUANTITY";
         element.insertBefore(input, element.children[1]);
 
-        element.children[2].innerText = "-";
-        element.children[2].onclick = ()=>{this.removeOne(element)};
+        element.children[2].style.display = "block";
+
+        element.children[3].innerText = "-";
+        element.children[3].onclick = ()=>{this.removeOne(element)};
     },
 
     removeOne: function(element){
         element.parentElement.removeChild(element);
 
         element.removeChild(element.children[1]);
+        element.children[1].style.display = "none";
 
-        element.children[1].innerText = "+";
-        element.children[1].onclick = ()=>{this.addOne(element)};
+        element.children[2].innerText = "+";
+        element.children[2].onclick = ()=>{this.addOne(element)};
 
         if(document.getElementById("myIngredients").children.length === 0){
             document.getElementById("myIngredientsDiv").style.display = "none";
@@ -583,19 +594,27 @@ let addIngredientsComp = {
         let fetchable = [];
 
         for(let i = 0; i < ingredients.length; i++){
-            if(ingredients[i].children[1].value === ""){
+            let quantity = ingredients[i].children[1].value;
+            let unit = ingredients[i].children[2].value;
+
+            if(quantity === ""){
                 banner.createError("PLEASE ENTER A QUANTITY FOR EACH INGREDIENT YOU WANT TO ADD TO YOUR INVENTORY");
                 return;
             }
+            quantity = convertToMain(unit, quantity);
 
-            newIngredients.push({
+            let newIngredient = {
                 ingredient: ingredients[i].ingredient,
-                quantity: ingredients[i].children[1].value
-            });
+                quantity: quantity
+            }
+            newIngredient.ingredient.unit = unit;
+
+            newIngredients.push(newIngredient);
 
             fetchable.push({
                 id: ingredients[i].ingredient.id,
-                quantity: ingredients[i].children[1].value
+                quantity: quantity,
+                defaultUnit: unit
             });
         }
 
@@ -639,10 +658,10 @@ let ingredientDetailsComp = {
         document.querySelector("#ingredientDetails p").innerText = ingredient.ingredient.category;
         document.querySelector("#ingredientDetails h1").innerText = ingredient.ingredient.name;
         let ingredientStock = document.getElementById("ingredientStock");
-        ingredientStock.innerText = `${ingredient.quantity} ${ingredient.ingredient.unit}`;
+        ingredientStock.innerText = `${ingredient.ingredient.convert(ingredient.quantity).toFixed(2)} ${ingredient.ingredient.unit.toUpperCase()}`;
         ingredientStock.style.display = "block";
         let ingredientInput = document.getElementById("ingredientInput");
-        ingredientInput.placeholder = `${ingredient.quantity} ${ingredient.ingredient.unit}`;
+        ingredientInput.value = ingredient.ingredient.convert(ingredient.quantity).toFixed(2);
         ingredientInput.style.display = "none";
 
         let quantities = [];
@@ -681,6 +700,23 @@ let ingredientDetailsComp = {
             ul.appendChild(li);
         }
 
+        let ingredientButtons = document.getElementById("ingredientButtons");
+        let units = merchant.units[this.ingredient.ingredient.unitType];
+        while(ingredientButtons.children.length > 0){
+            ingredientButtons.removeChild(ingredientButtons.firstChild);
+        }
+        for(let i = 0; i < units.length; i++){
+            let button = document.createElement("button");
+            button.classList.add("unitButton");
+            button.innerText = units[i].toUpperCase();
+            button.onclick = ()=>{this.changeUnit(button, units[i])};
+            ingredientButtons.appendChild(button);
+
+            if(units[i] === this.ingredient.ingredient.unit){
+                button.classList.add("unitActive");
+            }
+        }
+
         openSidebar(sidebar);
     },
 
@@ -716,9 +752,9 @@ let ingredientDetailsComp = {
     },
 
     edit: function(){
-        document.querySelector("#ingredientStock").style.display = "none";
-        document.querySelector("#ingredientInput").style.display = "block";
-        document.querySelector("#editSubmitButton").style.display = "block";
+        document.getElementById("ingredientStock").style.display = "none";
+        document.getElementById("ingredientInput").style.display = "block";
+        document.getElementById("editSubmitButton").style.display = "block";
     },
 
     editSubmit: function(){
@@ -755,6 +791,48 @@ let ingredientDetailsComp = {
                     loader.style.display = "none";
                 });
         }
+    },
+
+    changeUnit: function(newActive, unit){
+        this.ingredient.ingredient.unit = unit;
+
+        let ingredientButtons = document.querySelectorAll(".unitButton");
+        for(let i = 0; i < ingredientButtons.length; i++){
+            ingredientButtons[i].classList.remove("unitActive");
+        }
+
+        newActive.classList.add("unitActive");
+
+        homeStrandObj.drawInventoryCheckCard();
+        ingredientsStrandObj.populateByProperty("category");
+        document.getElementById("ingredientStock").innerText = `${this.ingredient.ingredient.convert(this.ingredient.quantity).toFixed(2)} ${this.ingredient.ingredient.unit.toUpperCase()}`;
+    },
+
+    changeUnitDefault: function(){
+        let loader = document.getElementById("loaderContainer");
+        loader.style.display = "flex";
+
+        let id = this.ingredient.ingredient.id;
+        let unit = this.ingredient.ingredient.unit;
+        fetch(`/merchant/ingredients/update/${id}/${unit}`, {
+            method: "put",
+            headers: {
+                "Content-Type": "application/json;charset=utf-8"
+            },
+        })
+            .then((response)=>{
+                if(typeof(response) === "string"){
+                    banner.createError(response);
+                }else{
+                    banner.createNotification("INGREDIENT DEFAULT UNIT UPDATED");
+                }
+            })
+            .catch((err)=>{
+                banner.createError("SOMETHING WENT WRONG. PLEASE REFRESH THE PAGE");
+            })
+            .finally(()=>{
+                loader.style.display = "none";
+            });
     }
 }
 
@@ -775,7 +853,7 @@ let newRecipeComp = {
             for(let ingredient of category.ingredients){
                 let option = document.createElement("option");
                 option.value = ingredient.ingredient.id;
-                option.innerText = ingredient.ingredient.name;
+                option.innerText = `${ingredient.ingredient.name} (${ingredient.ingredient.unit})`;
                 optgroup.appendChild(option);
             }
         }
@@ -813,17 +891,23 @@ let newRecipeComp = {
 
     submit: function(){
         let newRecipe = {
-            name: document.querySelector("#newRecipeName").value,
-            price: document.querySelector("#newRecipePrice").value,
+            name: document.getElementById("newRecipeName").value,
+            price: document.getElementById("newRecipePrice").value,
             ingredients: []
         }
 
         let inputs = document.querySelectorAll("#recipeInputIngredients > div");
-        for(let input of inputs){
-            newRecipe.ingredients.push({
-                ingredient: input.children[1].children[0].value,
-                quantity: input.children[2].children[0].value
-            });
+        for(let i = 0; i < inputs.length; i++){
+            for(let j = 0; j < merchant.ingredients.length; j++){
+                if(merchant.ingredients[j].ingredient.id === inputs[i].children[1].children[0].value){
+                    newRecipe.ingredients.push({
+                        ingredient: inputs[i].children[1].children[0].value,
+                        quantity: convertToMain(merchant.ingredients[j].ingredient.unit, inputs[i].children[2].children[0].value)
+                    });
+
+                    break;
+                }
+            }
         }
 
         if(!validator.recipe(newRecipe)){

+ 12 - 7
views/dashboardPage/transactions.js

@@ -10,10 +10,13 @@ window.transactionsStrandObj = {
                 transactionsList.removeChild(transactionsList.firstChild);
             }
 
-            for(let i = merchant.transactions.length - 1; i > merchant.transactions.length - 101 ; i--){
-                let transaction = template.cloneNode(true);
-                transaction.onclick = ()=>{transactionDetailsComp.display(merchant.transactions[i])};
-                transactionsList.appendChild(transaction);
+            let i = 0
+            while(i < merchant.transactions.length && i < 100){
+                let transactionDiv = template.cloneNode(true);
+                let transaction = merchant.transactions[i];
+
+                transactionDiv.onclick = ()=>{transactionDetailsComp.display(transaction)};
+                transactionsList.appendChild(transactionDiv);
 
                 let totalRecipes = 0;
                 let totalPrice = 0;
@@ -23,9 +26,11 @@ window.transactionsStrandObj = {
                     totalPrice += merchant.transactions[i].recipes[j].recipe.price * merchant.transactions[i].recipes[j].quantity;
                 }
 
-                transaction.children[0].innerText = `${merchant.transactions[i].date.toLocaleDateString()} ${merchant.transactions[i].date.toLocaleTimeString()}`;
-                transaction.children[1].innerText = `${totalRecipes} recipes sold`;
-                transaction.children[2].innerText = `$${(totalPrice / 100).toFixed(2)}`;
+                transactionDiv.children[0].innerText = `${merchant.transactions[i].date.toLocaleDateString()} ${merchant.transactions[i].date.toLocaleTimeString()}`;
+                transactionDiv.children[1].innerText = `${totalRecipes} recipes sold`;
+                transactionDiv.children[2].innerText = `$${(totalPrice / 100).toFixed(2)}`;
+
+                i++;
             }
 
             this.isPopulated = true;

+ 0 - 1
views/shared/shared.css

@@ -155,7 +155,6 @@ form{
     text-align: center;
     font-size: 20px;
     font-weight: bold;
-    margin-right: 33px;
     min-width: 100px;
 }