@Override public Collection<Coin> getChangeFor(int pence, Product p) throws NotEnoughChangeException, NotEnoughMoneyException { changeInProgress.clear(); int difference = pence - p.getProductPrice(); loadConfig(); if (enoughMoneyProvided(pence, p)) { if (enoughChange(difference)) { for (Coin coin : Coin.values()) { if (isCoinTypeNeeded(coin, difference - getCurrentChange())) { supplyThisCoinType(coin, difference - getCurrentChange(), true); } } if (getCurrentChange() != difference) throw new NotEnoughChangeException("The machine has run out of change."); updateConfig(); } else { throw new NotEnoughChangeException("The machine has run out of change."); } } else { throw new NotEnoughMoneyException("You have not provided enough money."); } return changeInProgress; }
/** * Returns an integer indicating the maximum number of coins available of a specific type. * * @param difference Amount between the money provided and the product price. * @param coin Current coin in the Map<Coin,Integer> * @param changeLimits Indicated whether there is an unlimited supply of change in the machine or * not. * @return Integer indicating the maximum amount of coins available for distribution. */ private int getCap(int difference, Coin coin, boolean changeLimits) { int capExact = difference / coin.getValueAsInt(); if (changeLimits) { int capMachine = availableChangeMachine.get(coin); if (capExact >= capMachine) { return capMachine; } } return capExact; }
@Override public Collection<Coin> getOptimalChangeFor(int pence, Product p) throws NotEnoughMoneyException { changeInProgress.clear(); int difference = pence - p.getProductPrice(); if (enoughMoneyProvided(pence, p)) { for (Coin coin : Coin.values()) { if (isCoinTypeNeeded(coin, difference - getCurrentChange())) { supplyThisCoinType(coin, difference - getCurrentChange(), false); } } } else { throw new NotEnoughMoneyException( "You have not provided enough money.\n" + "Remeber that 10 pounds need to be entered as 1000 (one thousand pennies), for example."); } return changeInProgress; }
/** * Checks if the current coin in the Map<Coin,Integer> needs to be added to the changeInProgress. * * @param coin Current coin in the Map<Coin,Integer> * @param difference Amount between the money provided and the product price. * @return True if the current coin fits the criteria for the return change. */ private boolean isCoinTypeNeeded(Coin coin, int difference) { return difference / coin.getValueAsInt() > 0; }