Ejemplo n.º 1
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.");
            }
        }