Назад к задачам
Junior — Senior
6

Валидация списка транзакций относительно баланса

Компании, где спрашивали:

СБЕР Корус
Получайте помощь с лайвкодингом в реальном времени с Sobes Copilot
Условие задачи

Метод проверяет корректность каждой операции. На входе принимает список транзакций и текущий баланс, относительно которого осуществляется проверка. На выходе – карта, где ключом является транзакция, а значением – признак её валидности. Количество элементов во входном списке и в результирующей карте одинаково.

Условия проверки:

  • Транзакции обрабатываются в порядке возрастания их идентификатора id.
  • Если транзакция с определённым id уже была обработана, она считается невалидной.
  • Все транзакции, имеющие тот же orderId, что и уже помеченные как невалидные, также считаются невалидными.
  • Существует два типа операций – UP (увеличивает баланс) и DOWN (уменьшает баланс).
  • Если операция DOWN приводит к отрицательному балансу, такая транзакция считается невалидной.
public class TransactionService {

    public Map<Transaction, Boolean> validate(List<Transaction> transactions, long balance) {
        final var map = new HashMap<Transaction, Boolean>();
        final var ids = new ArrayList<UUID>();
        final var orderIds = new HashSet<Long>();

        for (Transaction transaction : transactions) {
            boolean isValid = false;
            final var orderId = transaction.getOrderId();
            final var isAddId = ids.add(transaction.getId());

            if (isAddId && !orderIds.contains(orderId)) {
                isValid = isValid(transaction, balance);
            }

            if (!isValid) {
                orderIds.add(orderId);
            }

            map.put(transaction, isValid);
        }

        return map;
    }

    public boolean isValid(Transaction transaction, Long balance) {
        final var tempBalance = switch (transaction.getType()) {
            case "UP" -> balance + transaction.getAmount();
            case "DOWN" -> balance - transaction.getAmount();
            default -> balance;
        };

        final var isValid = tempBalance >= 0;

        if (isValid) {
            balance = tempBalance;
        }

        return balance >= 0;
    }

    @Value
    public static class Transaction {
        UUID id;
        long orderId;
        String type;
        long amount;
    }
}