main
 1using System.Collections.Generic;
 2using System.Linq;
 3using gorilla.utility;
 4
 5namespace solidware.financials.service.domain.accounting
 6{
 7    public class Transaction
 8    {
 9        static public Transaction New(UnitOfMeasure reference_units)
10        {
11            return new Transaction(reference_units);
12        }
13
14        Transaction(UnitOfMeasure reference)
15        {
16            reference_units = reference;
17        }
18
19        public void deposit(DetailAccount destination, Quantity amount)
20        {
21            deposits.Add(Potential<Deposit>.New(destination, amount));
22        }
23
24        public void withdraw(DetailAccount source, Quantity amount)
25        {
26            withdrawals.Add(Potential<Withdrawal>.New(source, amount));
27        }
28
29        public void post()
30        {
31            ensure_zero_balance();
32            deposits.Union(withdrawals).each(x => x.commit());
33        }
34
35        void ensure_zero_balance()
36        {
37            var balance = calculate_total(deposits.Union(withdrawals));
38            if (balance == 0) return;
39
40            throw new TransactionDoesNotBalance();
41        }
42
43        Quantity calculate_total(IEnumerable<PotentialEntry> potential_transactions)
44        {
45            var result = new Quantity(0, reference_units);
46            potential_transactions.each(x => result = x.combined_with(result));
47            return result;
48        }
49
50        List<PotentialEntry> deposits = new List<PotentialEntry>();
51        List<PotentialEntry> withdrawals = new List<PotentialEntry>();
52        UnitOfMeasure reference_units;
53    }
54}