/// <summary>
        /// <inheritdoc/>
        /// <remarks>
        /// User can wish to do an <see cref="M:VendingMachine.IState.EjectCoin"/> action in the <see cref="T:VendingMachine.WaitCoinState"/>. For ex: User inserted 10P but total price of the item is 20P.
        /// So, instead of continuing, he may as well decide to cancel the transaction and get the refund back.
        /// </remarks>
        /// </summary>
        public void EjectCoin()
        {
            var refund = _machine.RefundMoney();

            _machine.DisplayMessage(string.Format("Transaction has been cancelled. Please collect the refund{0}.", refund));
            _machine.State = _machine.GetUserSelectItemState;
        }
Exemple #2
0
        /// <summary>
        /// <inheritdoc/>
        /// <remarks>
        /// The current state is the <see cref="T:VendingMachine.SoldState"/>. This means that the user has paid.
        /// The following scenarios are possible in this case :-
        /// <list type="bullet">
        /// <item>
        ///     <description>
        ///     Case 1. Machine does not have exact change to tender. Hence, refund the user money and set the transition state to
        ///     <see cref="T:VendingMachine.WaitUserSelectionState"/>
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 2. Everything is fine. Ask the machine to release the drink.
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 3. After releasing the item, check if the machine owes any amount to the user. If yes, then,
        ///     the state is changed to <see cref="T:VendingMachine.DispenseChangeState"/>
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 4. After releasing the item, checks if the machine has enough inventory and it owes nothing to the user.
        ///     Transitions the state to <see cref="T:VendingMachine.WaitUserSelectionState"/>
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 5. After releasing the item, check the total inventory count.
        ///     If its zero, then transition the state to  <see cref="T:VendingMachine.SoldOutState"/>
        ///     </description>
        /// </item>
        /// </list>
        /// </remarks>
        /// </summary>
        public void DispenseItem()
        {
            // Machine does not have exact change to tender, hence do not dispense the item
            // Change back the state to user selection state, refund the money and show an appropriate message to the user.
            if (String.IsNullOrEmpty(_machine.TenderChange()))
            {
                var refund = _machine.RefundMoney();
                _machine.State = _machine.GetUserSelectItemState;
                throw new ApplicationException(string.Format("Machine does not have sufficient change. Please tender exact change. Please collect your inserted amount{0}", refund));
            }

            _machine.ReleaseItem();
            _machine.DisplayMessage("Item has been dispensed. Please do not forget to collect it.");

            // machine has to refund
            if (_machine.CustomerBalance < 0)
            {
                _machine.State = _machine.GetDispenseChangeState;
            }

            // Machine has enough products and has nothing to refund back to the user
            if (_machine.TotalItemCount > 0 && _machine.CustomerBalance == 0)
            {
                _machine.State = _machine.GetUserSelectItemState;
            }

            // Machine is empty. Everything is sold out. Hence, change the state to SoldOut
            if (_machine.TotalItemCount == 0)
            {
                _machine.State = _machine.GetSoldOutState;
                throw new ApplicationException("Sorry, the machine is out of stock.");
            }
        }
Exemple #3
0
 /// <summary>
 /// <inheritdoc/>
 /// <remarks>
 /// If the user performs an Insert Coin action in SoldOut state then refund back the money
 /// </remarks>
 /// </summary>
 public void InsertCoins()
 {
     _machine.RefundMoney();
     throw new ApplicationException("Machine is empty. Please take back your money.");
 }
Exemple #4
0
 /// <summary>
 /// <inheritdoc/>
 /// <remarks>
 /// When the machine is in <see cref="T:VendingMachine.WaitUserSelectionState"/>, user may try to perform the <see cref="M:VendingMachine.IState.InsertCoins"/> action.
 /// In such a situation, the state will signal the machine to refund the coins.
 /// No state transition will happen. The state of the machine remains unaltered.
 /// User is presented with a message saying the product selection needs to happen first.
 /// Alternatively,
 /// </remarks>
 /// </summary>
 public void InsertCoins()
 {
     // return the inserted money from the user as the state is not appropriate to accept coins
     _machine.RefundMoney();
     throw new ApplicationException("Please select a product first. Collect back your money.");
 }