/// <summary> /// Builds an ICashSet containing the smallest amount of items totalling at the defined value from a resticted list /// </summary> /// <param name="value">The desired value of the ICashSet</param> /// <param name="availableItems">The set of ICashItems that can be used to build the resurnset</param> public static ICashSet SmallestSetForValue(decimal value, ICashSet availableItems) { if (value <= 0) { return(null); } ICashSet returnSet = new CashSet(); decimal valueToAllocate = value; decimal setValue = availableItems.GetSum(); if (setValue == value) { return(availableItems); } else if (setValue > value) { foreach (KeyValuePair <ICash, int> denomination in availableItems.CashStack) { int amountNeeded = (int)(valueToAllocate / denomination.Key.UnitValue); if (amountNeeded == 0 || denomination.Value == 0) { //we either don't need this denomination, or we don't have any to use => skip adding it to the set continue; } else if (denomination.Value >= amountNeeded) { //There are sufficient units of this value available => add the desired amount to the set returnSet.Add(denomination.Key, amountNeeded); valueToAllocate -= denomination.Key.UnitValue * amountNeeded; } else { //There are insufficient units available (but more than none) => use them all returnSet.Add(denomination.Key, denomination.Value); valueToAllocate -= denomination.Key.UnitValue * denomination.Value; } if (valueToAllocate == 0) { //All value has been accounted for: return the set return(returnSet); } } return(null); } else { return(null); } }
#pragma warning disable CS0246 // The type or namespace name 'Success' could not be found (are you missing a using directive or an assembly reference?) /// <summary> /// Handles the payment /// </summary> /// <param name="moneyGiven"></param> /// <returns></returns> private Success HandlePayment(decimal moneyGiven) #pragma warning restore CS0246 // The type or namespace name 'Success' could not be found (are you missing a using directive or an assembly reference?) { decimal valueToReturn = moneyGiven - Cart.GetTransactionValue(); if (tillDrawer.ContainsEnough(valueToReturn)) { ICashSet givenSet = CashController.SmallestSetForValue(moneyGiven); ICashSet availableCash = new CashSet(tillDrawer.DrawerContent); availableCash.Add(givenSet); ICashSet returnSet = PaymentController.Payout(valueToReturn, availableCash); if (returnSet != null) { consoleDisplay.Print(string.Format("\nReturn {0}, distributed as: {1}", valueToReturn.ToString(), returnSet.ToString())); tillDrawer.Add(givenSet); tillDrawer.Remove(returnSet); return(new Success(true)); } else { return(new Success(false, "\nUnable to allocate sufficient cash; request a different payment method")); } } else { return(new Success(false, "\nNot enough money in the drawer; request a different payment method")); } }
public void CanAddDictionary() { CashSet set = new CashSet(Mocks.MockCashSets.StandardSet); set.Add(new CashSet(new SortedDictionary <ICash, int> { { new CashItem("2 cents", 0.02m), 1 }, { new CashItem("1 cent", 0.01m), 4 } })); Assert.AreEqual(34.77, set.GetSum()); }
public void DetermineChange(object s, ProvideChangeEventArgs pce) { ICashSet transactionSet = new CashSet(TillDrawer.Contents); CashSet givenSet = (CashSet)CashController.SmallestSetForValue(pce.CashGiven); transactionSet.Add(givenSet); decimal valueToPayout = pce.CashGiven - pce.TransactionValue; ICashSet setToReturn = Payout(valueToPayout, transactionSet); if (setToReturn != null) { RaisePrintReturnCash(setToReturn); RaisePaymentPossible(givenSet, (CashSet)setToReturn); } else { RaiseNoChangeFound(); } }
private static CashSet DefaultCashSet() { CashSet cashSet = new CashSet(); cashSet.Add(new CashItem("50 euros", 50m), 0); cashSet.Add(new CashItem("20 euros", 20m), 1); cashSet.Add(new CashItem("10 euros", 10m), 0); cashSet.Add(new CashItem("5 euros", 5m), 1); cashSet.Add(new CashItem("2 euros", 2m), 1); cashSet.Add(new CashItem("1 euros", 1m), 4); cashSet.Add(new CashItem("50 cents", 0.5m), 2); cashSet.Add(new CashItem("20 cents", 0.2m), 10); cashSet.Add(new CashItem("10 cents", 0.1m), 3); cashSet.Add(new CashItem("5 cents", 0.05m), 7); cashSet.Add(new CashItem("2 cents", 0.02m), 1); cashSet.Add(new CashItem("1 cent", 0.01m), 4); return(cashSet); }