diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java index 08f551e4..89f9665f 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java @@ -4,11 +4,11 @@ public class Atm { public enum Denomination { - D50(50), - D100(100), - D500(500), + D5000(5000), D1000(1000), - D5000(5000); + D500(500), + D100(100), + D50(50); private final int value; @@ -32,14 +32,59 @@ public static Denomination fromInt(int value) { public Atm() { } - public void deposit(Map banknotes){} + public void deposit(Map banknotes) { + if (banknotes == null || banknotes.isEmpty()) { + throw new InvalidDepositException("Deposit has to be non-empty"); + } + + for (Map.Entry entry : banknotes.entrySet()) { + if (entry.getValue() <= 0) { + throw new InvalidDepositException("Denomination has to be positive value"); + } + + this.banknotes.merge(entry.getKey(), entry.getValue(), Integer::sum); + } + } public Map withdraw(int amount) { - return Map.of(); + if (amount <= 0) { + throw new InvalidAmountException("Amount has to be positive value"); + } else if (amount > getBalance()) { + throw new InsufficientFundsException("Not enough funds in ATM"); + } + + Map change = new EnumMap<>(Denomination.class); + + for (Map.Entry entry : banknotes.entrySet()) { + if (amount == 0) break; + + Denomination denomination = entry.getKey(); + Integer denominationAmount = entry.getValue(); + + int times = Integer.min(amount / denomination.value, denominationAmount); + + amount -= denomination.value * times; + change.put(denomination, times); + } + + if (amount > 0) { + throw new CannotDispenseException("Cannot dispense"); + } + + for (Map.Entry entry : change.entrySet()) { + int times = banknotes.get(entry.getKey()); + banknotes.put(entry.getKey(), times - entry.getValue()); + } + + return change; } public int getBalance() { - return 0; + int sum = 0; + for (Map.Entry entry : banknotes.entrySet()) { + sum += entry.getKey().value * entry.getValue(); + } + return sum; } }