public GoodsBuyedEvent BuyGoods(IReadOnlyCollection <Coin> depositedAmount, GoodsIdentity goods) { Contract.Requires(depositedAmount != null); var availableGoods = _availableGoods.Retrieve(goods); var depositWallet = new Wallet(depositedAmount); var depositTotal = depositWallet.TotalFunds(); if (depositTotal < availableGoods.Price) { throw new InsufficientAmountForBuyingGoodsException(availableGoods.Price, depositTotal, goods); } var refundAmount = depositTotal - availableGoods.Price; _vendingMachineWallet = _vendingMachineWallet.Put(depositedAmount); _buyerWallet = _buyerWallet.Retrieve(depositedAmount); var refundCoins = Refund(refundAmount); var refundWallet = new Wallet(refundCoins); if (refundWallet.TotalFunds() != refundAmount) { throw new VendingMachineDoesNotHaveCoinsForRefundException(_vendingMachineWallet, refundAmount); } _vendingMachineWallet = _vendingMachineWallet.Retrieve(refundCoins); _buyerWallet = _buyerWallet.Put(refundCoins); return(new GoodsBuyedEvent(_vendingMachineWallet, _buyerWallet, availableGoods, refundCoins)); }
public Goods(GoodsIdentity identity, decimal price, int count) { Contract.Requires(price > decimal.Zero); Contract.Requires(count >= 0); Identity = identity; Price = price; Count = count; }
public Goods Retrieve(GoodsIdentity goods, int count = 1) { Contract.Requires(count > 0); var availableGoods = _bag.SingleOrDefault(g => g.Identity.Equals(goods)); if (availableGoods == null || availableGoods.Count < count) { throw new GoodsShortageException(availableGoods, count); } _bag.Remove(availableGoods); availableGoods = new Goods(goods, availableGoods.Price, availableGoods.Count - count); if (availableGoods.Count > count) { _bag.Add(availableGoods); } return(availableGoods); }