Source code: com/pjsofts/eurobudget/util/AccountLib.java
1 /*
2 * AccountLib.java
3 *
4 * Created on 5 avril 2002, 10:30
5 */
6
7 package com.pjsofts.eurobudget.util;
8
9 import com.pjsofts.DateLib;
10 import com.pjsofts.eurobudget.beans.*;
11 import com.pjsofts.eurobudget.data.Totals;
12 import java.util.*;
13
14 /**
15 * Regroup all computation, convenient methods related to account and transactions
16 * Should not change data of account but just create new ones or transmit information.
17 * (otherwhise notification on changes will not be done)
18 * @author pj
19 */
20 public abstract class AccountLib {
21
22 /** Creates a new instance of AccountLib
23 * can't be instanciated
24 */
25 private AccountLib() {
26 }
27
28 /** Get a list of transaction on a ranged period (optimize way to get txn when working in a period)
29 * @return subview list of Transaction still ordered on date (warning do not work on two lists in same time)
30 * @param account
31 * @param start null means first txn
32 * @param end null means last txn
33 */
34 public static List getTxns(Account account, Date start, Date end) {
35 List txns = account.getTxns();
36 return TransactionLib.subList(txns,start,end);
37 }
38
39
40 /**
41 * Compute many totals related to an account
42 * Will count the original amount of account only if startDate is null.
43 * @param account on which to look for transactions
44 * @param startDate means from this date (included) or if null from first txn (this original amount of account)
45 * @param endDate means until this date (included) or if null until the last txn
46 * @return all totals computed with thoses parameters for this account
47 * Note: Work on effective date before date of txn !!
48 * Precondition: list of transactions is ordered in chronological order
49 */
50 public static Totals computeTotals(Account account, Date startDate, Date endDate) {
51 Totals accTotals = new Totals();
52 if ( startDate == null )
53 accTotals.total = account.getInitialAmount();
54 else
55 accTotals.total = 0d;
56 accTotals.creditTotal= 0d;
57 accTotals.debitTotal = 0d;
58 accTotals.realCreditTotal = 0d;
59 accTotals.realDebitTotal = 0d;
60 accTotals.realTotal = 0d;
61 accTotals.saveOnAccountTotal= 0d;
62 accTotals.saveToAnotherAccountTotal = 0d;
63 List txns = AccountLib.getTxns(account, startDate,endDate);
64 accTotals = TransactionLib.computeTotals(txns, accTotals);
65 // assertions
66 assert accTotals.total == (startDate == null ? account.getInitialAmount() : 0d) + accTotals.creditTotal - accTotals.debitTotal;
67 assert accTotals.realCreditTotal == accTotals.creditTotal - accTotals.saveOnAccountTotal;
68 assert accTotals.realDebitTotal == accTotals.debitTotal - accTotals.saveToAnotherAccountTotal;
69 return accTotals;
70 }
71
72 /**
73 * Basic balance sums ..
74 * Add initial balance of the account at the beginning
75 * @return array of sums for each txn (corresponding to txn order normally ordered on date)
76 */
77 public static double[] getSums(Account account) {
78 double current = account.getInitialAmount();
79 List txns = account.getTxns();
80 double[] result = null;
81 if ( txns != null ) {
82 result = new double[txns.size()];
83 Transaction t ;
84 for (int i=0; i< txns.size() ;i++) {
85 t = (Transaction)txns.get(i);
86 current += t.getRealAmount();
87 result[i] = current;
88 }
89 }
90 //sumsInvalid = false;
91 return result;
92 }
93
94 /**
95 *
96 * @return account sold at the given date
97 */
98 public static Double getSumAt(Account account, Date targetDate) {
99 // this method :
100 Totals totals = computeTotals(account,null,targetDate);
101 return new Double(totals.total);
102 // or this method :
103 /*
104 double current = account.getInitialAmount();
105 List txns = account.getTxns();
106 if ( txns != null ) {
107 result = new double[txns.size()];
108 Transaction t ;
109 boolean dateIsOK = true;
110 for (int i=0; i< txns.size() && dateIsOK; i++) {
111 t = (Transaction)txns.get(i);
112 if ( t.getDate().compareTo(targetDate) <= 0 ) {
113 current += t.getRealAmount();
114 } else {
115 dateIsOK = false;
116 break;
117 }
118 }
119 }
120 return new Double(current);
121 */
122 }
123
124 /**
125 * prec params not null
126 * @return Double[2]: [0] is account total computed [1] is the difference, or null if problems
127 */
128 public static Double[] balance(Account account, Date targetDate, Double targetAmount) {
129 Double[] result = null;
130 Double sum = getSumAt(account,targetDate);//could compute only until targetDate or save results smwhr
131 if ( sum != null ) {
132 result = new Double[2];
133 result[0] = sum;
134 result[1] = new Double(targetAmount.doubleValue() - sum.doubleValue());
135 }
136 return result;
137 }
138
139
140 /**
141 * @param list of Account
142 * @param countCreationDate true means consider acccounts creation's date
143 * @return the date of the first txn of this budget (first in time)
144 * or today if no account and no txn defined !
145 * O(nAccounts) : looks only first txn of accounts
146 */
147 public static Date getFirstOfAllDate(List list, boolean countCreationDate ) {
148 Date date = null;
149 if ( list != null ) {
150 for (Iterator it= list.iterator(); it.hasNext() ;) {
151 Account account = (Account)it.next();
152 Date creation = account.getCreationDate();
153 if ( date == null
154 || ( creation != null && creation.before(date) ) )
155 date = creation; //may be null
156 List txns = account.getTxns();
157 if ( txns != null && !txns.isEmpty() ) {
158 // transactions are ordered on Date ;-)
159 Transaction t = (Transaction)txns.get(0);
160 if ( date == null
161 || (t.getDate() != null && t.getDate().before(date)) ) {
162 date = t.getDate();
163 }
164 }
165 }
166 }
167 if ( date == null ) date = new Date();
168 return date;
169 }
170
171 /**
172 * @param list of Accounts
173 * @return the date of the first txn of this budget (first in time)
174 * O(nAccounts) : looks only last txn of accounts
175 */
176 public static Date getLastOfAllDate(List list) {
177 Date date = null;
178 for (Iterator it= list.iterator(); it.hasNext() ;) {
179 Account account = (Account)it.next();
180 List txns = account.getTxns();
181 if ( txns != null && !txns.isEmpty() ) {
182 // transactions are ordered on Date ;-)
183 Transaction t = (Transaction)txns.get(txns.size()-1);
184 if ( date == null
185 || (t.getDate() != null && t.getDate().before(date)) ) {
186 date = t.getDate();
187 }
188 }
189 }
190 if ( date == null ) date = new Date();
191 return date;
192 }
193
194 /**
195 * @return last verified transaction or null if none
196 **/
197 public static Transaction getLastVerifiedTransaction(Account account) {
198 if ( account == null ) return null;
199 List txns = account.getTxns();
200 // list ordered on chron. order.
201 Transaction t, lastVerified = null;
202 for (int i=txns.size()-1; i>=0 ;i--) {
203 t = (Transaction) txns.get(i);
204 if ( t.isVerified() ) {
205 lastVerified = t;
206 break;
207 }
208 }
209 return lastVerified;
210 }
211
212 // /**
213 // * Look at all transaction of same class and same amount value
214 // * @return latest similar transaction or null if none matches
215 // **/
216 // public static Transaction getLastTransactionWithSimilarAmount(Account account, Transaction model ) {
217 // if ( account == null ) return null;
218 // List txns = account.getTxns();
219 // // list ordered on chron. order.
220 // Transaction t=null, lastVerified = null;
221 // for (int i=txns.size()-1; i>=0 ;i--) {
222 // t = (Transaction) txns.get(i);
223 // if ( t.isVerified() ) {
224 // lastVerified = t;
225 // break;
226 // }
227 // }
228 // return lastVerified;
229 // }
230
231 }
232