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));
        }
Exemple #2
0
        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);
        }