/// <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; }
/// <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."); } }
/// <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."); }
/// <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."); }