/// <summary> /// Processing payment events from the coin receiver /// </summary> /// <param name="cmd">The event to process.</param> /// <param name="payment">The coin received or null</param> void PaymentAction(PaymentCmdEvent cmd, INotionValue payment) { if (VendingMachineState != VendingMachineState.Payment) { return; } if (cmd == PaymentCmdEvent.Cancel) { // Cancellation of the order or/and payment CancelOrder(); } else if (cmd == PaymentCmdEvent.Payment) { _paymentWalletRepository.AddToWallet(payment, 1); Money total = _orderedProducts.Aggregate(Money.Zero, (m, p) => m + p.Price); Money paid = _paymentWalletRepository.WalletList.Aggregate(Money.Zero, (m, p) => m + new Money(0, (int)p.Item1.Nominal * p.Item2)); string msg = String.Format(_vendingMessageRepository.GetMessage(MessageCode.BalancePayment), total, paid); _displayPanel.DisplayMessage(msg); if (paid >= total) { // give change or cancel if (paid > total) { Money change = paid - total; PaymentWalletRepository collectedChange = ChangeComposer(_walletRepository, change); if (collectedChange == null) { DisplayMessageByCode(MessageCode.RunOutOfChange); CancelOrder(); return; } foreach (var pm in collectedChange.WalletList) { msg = String.Format(_vendingMessageRepository.GetMessage(MessageCode.GivenChange), pm.Item1.MoneyValue, pm.Item2); _displayPanel.DisplayMessage(msg); } } // complete purchase foreach (var p in _orderedProducts) { msg = String.Format(_vendingMessageRepository.GetMessage(MessageCode.CollectYourPurchase), p); _saleRecord.Sold(p); _displayPanel.DisplayMessage(msg); } _orderedProducts.Clear(); foreach (var pm in _paymentWalletRepository.WalletList) { _walletRepository.AddToWallet(pm.Item1, pm.Item2); } _paymentWalletRepository.ClearMoney(); // switch back to selling TryToStartSelling(); _coinReceiver.Off(); } } }
public int RemoveFromWallet(INotionValue notion, int number) { if (notion == null) { throw new ArgumentNullException(nameof(notion)); } if (!Repository.ContainsKey(notion)) { throw new InvalidDataException(nameof(notion)); } if (number < 0 || number > Repository[notion]) { throw new InvalidDataException(nameof(number)); } return(Repository[notion] -= number); }
public void TestPayment() { // setup the tested class instance and dependencies with the test case initialization. var mockDisplayPanel = new MockDisplayPanel(); var mockReadKeypadInput = new MockReadKeypadInput(); var mockVendingMessageRepository = new MockVendingMessageRepository(); var paymentPanel = new PaymentReceiver(mockDisplayPanel, mockReadKeypadInput, mockVendingMessageRepository); PaymentCmdEvent cmd = PaymentCmdEvent.Cancel; INotionValue objCoin = null; // !!! define the simulation key pad command of payment var firstCoin = paymentPanel.MapToCoins.First(); mockReadKeypadInput.SimInputAs = firstCoin.Key; // !! define the action test listener paymentPanel.CoinAction += (c, p) => { cmd = c; objCoin = p; // off after getting the event paymentPanel.Off(); }; bool exception = false; paymentPanel.FailtException += ex => exception = true; // Test subject Action - on payment receiver and get simulated payment paymentPanel.On(); Thread.Sleep(10000); // verify - payment Assert.False(exception); Assert.Equal(PaymentCmdEvent.Payment, cmd); Assert.Equal(firstCoin.Value, objCoin); // verify the message flow List <MessageCode> TestCatchedCodes = new List <MessageCode> { MessageCode.MakeYourPayment, MessageCode.Ok }; Assert.Equal((IEnumerable <MessageCode>)TestCatchedCodes, (IEnumerable <MessageCode>)mockVendingMessageRepository.CatchedCodes); Assert.Equal((IEnumerable <string>)mockVendingMessageRepository.ReturnList, (IEnumerable <string>)mockDisplayPanel.DisplayList); }
public int AddToWallet(INotionValue notion, int number) { if (notion == null) { throw new ArgumentNullException(nameof(notion)); } if (number < 0) { throw new InvalidDataException(nameof(number)); } if (Repository.ContainsKey(notion)) { Repository[notion] += number; } else { Repository[notion] = number; } return(Repository[notion]); }
public void InvokeCoinAction(PaymentCmdEvent cmd, INotionValue obj) { CoinAction?.Invoke(cmd, obj); }