private decimal CalculatePriceForProductOrder(ProductOrder item)
        {
            decimal price       = 0;
            var     pricingRule = item.Product.PricingRule;

            if (pricingRule == null)
            {
                // standard pricing
                price = item.Quantity * item.Product.UnitPrice;
            }
            else
            {
                if (pricingRule.Quantity <= 0)
                {
                    throw new ArgumentOutOfRangeException("Cannot calculate price with invalid quantity on pricing rule");
                }

                if (pricingRule.Price <= 0)
                {
                    throw new ArgumentOutOfRangeException("Cannot calculate price with invalid pricing rule");
                }

                var nbrOfUnits = UnitsConverter.GetEquivalentUnit(item.Product.MeasureUnit, pricingRule.MeasureUnit);
                //price = item.Quantity * item.Product.UnitPrice;

                if (nbrOfUnits < 1)
                {
                    // don't apply the pricing rule
                    price = nbrOfUnits * item.Product.UnitPrice * item.Quantity;
                }
                else
                {
                    // apply the pricing rule
                    // get the total qunatity after unit conversion
                    var totalQty = item.Quantity * nbrOfUnits;

                    // calculate the number of discounts corresponding to pricing rule
                    var nbrOfDiscounts = Math.Floor(totalQty / pricingRule.Quantity);

                    // calculate the remaing quantity price
                    // may be calculated with applied pricing rule or with initial price
                    var restQty = totalQty % pricingRule.Quantity;

                    price = nbrOfDiscounts * pricingRule.Price;

                    // calculate the price of remaing quantity depending on the pricing rule
                    if (item.Product.UnitPrice > 0)
                    {
                        price += restQty * item.Product.UnitPrice;
                    }
                    else
                    {
                        // calculate the unitprice from princing rule
                        price += restQty * (pricingRule.Price / pricingRule.Quantity);
                    }
                }
            }

            return(price);
        }
 public void Test_UnitConvesrionExceptionWhenDifferentType()
 {
     Assert.Catch(() => UnitsConverter.GetEquivalentUnit(MeasureUnit.KILOGRAM, MeasureUnit.LITER));
 }
 public void Test_UnitConvesrionExceptionWhenPiece()
 {
     Assert.Catch(() => UnitsConverter.GetEquivalentUnit(MeasureUnit.PIECE, MeasureUnit.KILOGRAM));
 }
 public void Test_UnitConvesrionPoundToOunce()
 {
     Assert.AreEqual(16, UnitsConverter.GetEquivalentUnit(MeasureUnit.POUND, MeasureUnit.OUNCE));
 }
 public void Test_UnitConvesrionKgToGramm()
 {
     Assert.AreEqual(1000, UnitsConverter.GetEquivalentUnit(MeasureUnit.KILOGRAM, MeasureUnit.GRAM));
 }