BalanceRecords.java

package com.tdmconsult.ete.accounting;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class BalanceRecords {

    public static final BigDecimal ZERO_AMOUNT = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    private final Map<SKR03Account, BalanceRecord> records = new HashMap<>();

    public BalanceRecords credit(final BigDecimal amount, final SKR03Account account) {
        records.merge(account,
                new BalanceRecord(account, ZERO_AMOUNT, amount.setScale(2, RoundingMode.HALF_UP)),
                (oldValue, newValue) -> new BalanceRecord(account, oldValue.debit(), oldValue.credit().add(amount)));
        return this;
    }

    public BalanceRecord get(final SKR03Account account) {
        return records.containsKey(account)
                ? records.get(account)
                : new BalanceRecord(account, ZERO_AMOUNT, ZERO_AMOUNT);
    }

    public BalanceRecords debit(final BigDecimal amount, final SKR03Account account) {
        records.merge(account,
                new BalanceRecord(account, amount.setScale(2, RoundingMode.HALF_DOWN), ZERO_AMOUNT),
                (oldValue, newValue) -> new BalanceRecord(account, oldValue.debit().add(amount), oldValue.credit()));
        return this;
    }

    public BigDecimal creditTotal() {
        return stream().map(BalanceRecord::credit).reduce(ZERO_AMOUNT, BigDecimal::add);
    }

    public BigDecimal debitTotal() {
        return stream().map(BalanceRecord::debit).reduce(ZERO_AMOUNT, BigDecimal::add);
    }

    public Stream<BalanceRecord> stream() {
        return records.values().stream();
    }
}