public void AddItemToCheckout(int sku, decimal quantity, MeasurmentUnits buyUnit, DiscountRule discountRule) { // First get the product with the corresponding SKU from repository var product = _productsRepo.GetProduct(sku); if (product == null) { throw new ArgumentException($"Cannot find product with SKU : {sku}"); } if (product.UnitPrice <= 0) { throw new ArgumentOutOfRangeException("Cannot add a product with invalid price"); } if (quantity <= 0) { throw new ArgumentOutOfRangeException("Cannot add a product with negative or zero quantity"); } if (product.MeasurmentUnit == MeasurmentUnits.PIECE && quantity != Math.Round(quantity)) { throw new ArgumentException("Cannot add product sold by number with a floating decimal quantity"); } if (product.MeasurmentUnit != buyUnit) { try { // get the quantity corresponding to the sell unit, rounded to 3 decimals quantity = Math.Round(GetQuantityFromUnit(quantity, product.MeasurmentUnit, buyUnit), 3); } catch (Exception e) { throw new ArgumentException(e.Message + $": Sell Unit {product.MeasurmentUnit}, Buy Unit {buyUnit}"); } } if (discountRule != null) { discountRule = ConfigureDiscountRuleParams(discountRule.Id, product.UnitPrice); } // Finally add a "quantity" of this product to the list of // checkout items if all the checking conditions are met _checkoutRepo.AddItem(product, quantity, buyUnit, discountRule); }
public void AddItem(Product product, decimal quantity, MeasurmentUnits buyUnit, DiscountRule discountRule) { product.DiscountRule = discountRule; // create a CheckoutItem object from the provided parameters var checkoutItem = new CheckoutItem { Product = product, Quantity = quantity, BuyUnit = buyUnit, Price = product.UnitPrice * quantity }; // Set a unique ID and increment the static counter checkoutItem.Id = _id; Interlocked.Increment(ref _id); // add the item to the checkout list _checkoutItems.Add(checkoutItem); }
[InlineData(4, 800, MeasurmentUnits.MILLILITRE, 1)] // item with SKU = 4 costs $1.25/litre (so what does 800 millilitres cost?) public void Test_CanCalculateTotalSingleItemPerWeightOrVolume(int id, decimal quantity, MeasurmentUnits buyUnit, decimal expectedPrice) { var checkoutService = Subject(); // add the sequence of inline data checkoutService.AddItemToCheckout(id, quantity, buyUnit, null); // verify that the calulated price is equal to the expected price Assert.Equal(expectedPrice, checkoutService.CalculateTotal()); }
// returns the quantity equivalent to sell unit based on the buy unit private decimal GetQuantityFromUnit(decimal quantity, MeasurmentUnits saleUnit, MeasurmentUnits buyUnit) { string message = "Not compatible buy and sell units"; switch (saleUnit) { /***** Mass Conversion *****/ // Convert to pounds case MeasurmentUnits.POUND: if (buyUnit == MeasurmentUnits.OUNCE) { return(MassConversion.OuncesToPounds(quantity)); } if (buyUnit == MeasurmentUnits.GRAM) { return(MassConversion.GramsToPounds(quantity)); } if (buyUnit == MeasurmentUnits.KILOGRAM) { return(MassConversion.KilogramsToPounds(quantity)); } else { throw new ArgumentException(message); } // Convert to Kilograms case MeasurmentUnits.KILOGRAM: if (buyUnit == MeasurmentUnits.GRAM) { return(MassConversion.GramsToKilograms(quantity)); } if (buyUnit == MeasurmentUnits.POUND) { return(MassConversion.PoundsToKilograms(quantity)); } if (buyUnit == MeasurmentUnits.OUNCE) { return(MassConversion.OuncesToKilograms(quantity)); } else { throw new ArgumentException(message); } // Convert to Grams case MeasurmentUnits.GRAM: if (buyUnit == MeasurmentUnits.OUNCE) { return(MassConversion.OuncesToGrams(quantity)); } if (buyUnit == MeasurmentUnits.POUND) { return(MassConversion.PoundsToGrams(quantity)); } if (buyUnit == MeasurmentUnits.KILOGRAM) { return(MassConversion.KilogramsToGrams(quantity)); } else { throw new ArgumentException(message); } // Convert to ounces case MeasurmentUnits.OUNCE: if (buyUnit == MeasurmentUnits.POUND) { return(MassConversion.PoundsToOunces(quantity)); } if (buyUnit == MeasurmentUnits.GRAM) { return(MassConversion.GramsToOunces(quantity)); } if (buyUnit == MeasurmentUnits.KILOGRAM) { return(MassConversion.KilogramsToOunces(quantity)); } else { throw new ArgumentException(message); } /***** Volume Conversion *****/ case MeasurmentUnits.LITRE: if (buyUnit == MeasurmentUnits.GALLON) { return(VolumeConversion.GallonsToLitres(quantity)); } if (buyUnit == MeasurmentUnits.MILLILITRE) { return(VolumeConversion.MillilitresToLitres(quantity)); } else { throw new ArgumentException(message); } case MeasurmentUnits.GALLON: if (buyUnit == MeasurmentUnits.LITRE) { return(VolumeConversion.LitresToGallons(quantity)); } if (buyUnit == MeasurmentUnits.MILLILITRE) { return(VolumeConversion.MillilitresToGallons(quantity)); } else { throw new ArgumentException(message); } case MeasurmentUnits.MILLILITRE: if (buyUnit == MeasurmentUnits.LITRE) { return(VolumeConversion.LitresToMillilitres(quantity)); } if (buyUnit == MeasurmentUnits.GALLON) { return(VolumeConversion.GallonsToMillilitres(quantity)); } else { throw new ArgumentException(message); } default: throw new ArgumentException(message); } }