Ejemplo n.º 1
0
        /// <summary>
        /// <inheritdoc/>
        /// <remarks>
        /// This is the appropriate action for <see cref="T:VendingMachine.WaitUserSelectionState"/> i.e. when the machine is ready for the user to select an item.
        /// <list type="bullet">
        /// <item>
        ///     <description>
        ///     Case 1. Checks the total machine inventory and if it is empty, it transitions back to <see cref="T:VendingMachine.SoldOutState"/>.
        ///     Machine needs a refill.
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 2. Checks if there is sufficient stock of the selected item and transitions the state to <see cref="T:VendingMachine.WaitCoinState"/>.
        ///     User is in a position to insert the coins.
        ///     </description>
        /// </item>
        /// <item>
        ///     <description>
        ///     Case 3. If there is no stock left for the selected item it transitions back to <see cref="T:VendingMachine.WaitUserSelectionState"/>.
        ///     This allows the user to reselect a different item.
        ///     </description>
        /// </item>
        /// </list>
        /// </remarks>
        /// </summary>
        /// <param name="itemName">Name of the product</param>
        public void SelectItem(string itemName)
        {
            // Machine's inventory is Zero. Everything is sold out. Make the state transition to the sold out state
            if (_machine.TotalItemCount == 0)
            {
                _machine.State = _machine.GetSoldOutState;
                return;
            }

            // check if the machine has enough stock of the selected item
            if (_machine.GetItemCount(itemName) > 0)
            {
                // tell the machine to update the selected product in transaction
                _machine.AddItem(itemName);
                _machine.DisplayMessage(string.Format("You selected {0} with a value of {1} ", _machine.SelectedItem.Name, _machine.SelectedItem.Price));

                // change the state to "wait for coins".
                _machine.State = _machine.GetWaitCoinState;

                // display an appropriate message to the user
                _machine.DisplayMessage(string.Format("Please insert coins to buy '{0}'", _machine.SelectedItem.Name));
            }
            else
            {
                // Sufficient stock is not available. Hence, change the state to wait selection state
                // such that the user can select a different drink. Notify this to the user.
                _machine.State = _machine.GetUserSelectItemState;
                throw new ApplicationException(string.Format("Sorry, '{0}' is not available. Please select a different drink.",
                                                             _machine.SelectedItem.Name));
            }
        }
 /// <summary>
 /// <inheritdoc/>
 /// <remarks>
 /// The operation checks if the customer has tendered the correct amount for the selected product.
 /// If the customer owes more then it propmpts to enter further amount else the state is changed to
 /// <see cref="T:VendingMachine.SoldState"/>
 /// </remarks>
 /// </summary>
 public void InsertCoins()
 {
     // if balance is negative that means machine needs to return the amount to the customer
     if (_machine.CustomerBalance <= 0)
     {
         _machine.State = _machine.GetSoldState;
     }
     else
     {
         _machine.DisplayMessage(string.Format("Balance amount remaining {0}", _machine.CustomerBalance));
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// <inheritdoc/>
        /// <remarks>
        /// Dispenses the changes and sets the state back to user wait selection
        /// </remarks>
        /// </summary>
        public void DispenseChange()
        {
            var change = _machine.TenderChange();

            _machine.DisplayMessage(string.Format("Please collect your change : \n{0}", change));
            _machine.State = _machine.GetUserSelectItemState;
        }
Ejemplo n.º 4
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.");
            }
        }
Ejemplo n.º 5
0
 /// <summary>
 /// <inheritdoc />
 /// This can only happen when total item count is zero and machine is in sold out state.
 /// User tries to select an item
 /// </summary>
 public void SelectItem(string itemName)
 {
     _machine.DisplayMessage("Products are not available. Machine needs a refill.");
 }