Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/pjsofts/eurobudget/beans/Account.java


1   /*
2    * Compte.java
3    *
4    * Created on 10 janvier 2002, 11:02
5    */
6   
7   package com.pjsofts.eurobudget.beans;
8   
9   import com.pjsofts.eurobudget.EBConstants;
10  import java.io.Serializable;
11  import java.util.*;
12  
13  /**
14   * Account, Bean
15   * Compte courant bancaire
16   * Try to keep the minimum of methods.
17   * All convenient methods should be written as AccountLib static methods.
18   * (As we save it as bean, try to minimize change and size)
19   * @author  PJ
20   */
21  public class Account extends Object implements java.lang.Comparable, Serializable {
22      /** serialization trick to be compatible with older implementation ,interoperability */
23      private static final long serialVersionUID = 4486226926471298634L;
24      /** resource for i18n */
25      private static final transient ResourceBundle i18n = EBConstants.i18n;
26      
27      /** compte cloturé (can't add anymore txn) */
28      public static final int FLAG_ENDED = 1;
29      public static final int FLAG_FAVORITE = 2;
30      public static final int FLAG_TVA = 3;
31      public static final int FLAG_O1 = 4;
32      public static final int FLAG_O2 = 5;
33      public static final int FLAG_O3 = 6;
34      public static final int FLAG_O4 = 7;
35      public static final int FLAG_O5 = 8;
36      public static final int FLAG_O6 = 9;
37  
38      // mandatory ///////////
39      /** @serial */
40      private String name;
41      /** @serial */
42      private Bank bank;
43      /** @serial */
44      private Currency ccy = Currency.getInstance(EBConstants.EBLOCALE); //euro only ??
45      
46      /** 
47       * List of Transactions can't be null
48       * ??? Sort per Date in chronological order, cause
49       * 1)normal view 2)allow to compute sum on range of date
50       * -)when saved/exported on file, the sort is not reneeded
51       * -)allow to compute faster the balande for one specific day
52       * Collections.sort(txns,Comparator); binarySearch==> easy even with List
53       * @serial
54       */
55      private List txns = new ArrayList();
56      
57      /**
58       * solde initial du compte 
59       * @serial 
60       */
61      private double initialAmount=0d;
62      
63      /** @serial */
64      private double minAmount = Double.MIN_VALUE;
65      /** @serial */
66      private double maxAmount = Double.MAX_VALUE;
67      
68      // optionnal
69      /** Identification internationale
70       * @serial 
71       */
72      private String iban;
73      /**
74       * Reference bancaire 
75       * @serial 
76       */
77      private String refs;
78      
79      /** Titulaire du compte */
80      //private Entity owner;
81      
82      /**
83       * Holds value of property id. 
84       * @serial 
85       */
86      private String id;
87      
88      /** Holds value of property creationDate. 
89       * @serial 
90       */
91      private Date creationDate;
92      /** derniere modification 
93       * @serial 
94       */
95      private Date lastModificationDate;
96      /** dernier rapprochement 
97       * @serial 
98       */
99      private Date lastBalancedDate;
100     
101     /** Flags ... for future 
102      * @serial
103      */
104     private BitSet flags = new BitSet();
105     
106     /** Group of account 
107      * @serial
108      */
109     private AccountGroup accountGroup = AccountGroup.AG_USUAL;
110     /** comment
111      * @serial 
112      */
113     private String comment = null;
114     
115     //////// NOT BEAN PROPERTIES ////////////
116     /** to compute , not always up to date */
117     /** Final total */
118     private transient double total=0d;
119     /** Final Credit total */
120     private transient double ctotal=0d;
121     /** Final Debit total */
122     private transient double dtotal=0d;
123     /** Today total */
124     private transient double dayTotal=0d;
125     /** Today credit total */
126     private transient double creditDayTotal=0d;
127     /** Today debit total */
128     private transient double debitDayTotal=0d;
129     
130     
131     //private boolean sumsInvalid = false;
132     
133     public Account(){
134     }
135     
136     public Account(String id, String name, Bank bank, Date start) {
137         this();
138         setId(id);
139         setName(name);
140         setBank(bank);
141         setCreationDate(start);
142     }
143     
144     /** update total variable
145      * total = big total
146      * dtotal = debit total
147      * ctotal = credit total
148      * dayTotal = big total until this date
149      * @param date until date included (for dayTotal) or null means all txns.
150      */
151     public void updateTotals(Date date) {
152         this.total = getInitialAmount();
153         this.ctotal = 0d;
154         this.dtotal = 0d;
155         this.dayTotal = 0d;
156         this.creditDayTotal= 0d;
157         this.debitDayTotal = 0d;
158         if ( txns != null ) {
159             Transaction t ;
160             // could use some boolean and start big total only after day total,
161             // but I think it's a too small optimization
162             for (int i=0; i< txns.size() ;i++) {
163                 t = (Transaction)txns.get(i);
164                 total  += t.getRealAmount();
165                 if ( t.getRealAmount() >= 0) {
166                     ctotal += t.getAmount();
167                 } else {
168                     dtotal += t.getAmount();
169                 }
170                 if ( date != null && date.after(t.getDate()) ) {
171                     dayTotal  += t.getRealAmount();
172                     if ( t.getRealAmount() >= 0) {
173                         creditDayTotal  += t.getRealAmount();
174                     } else {
175                         debitDayTotal  += t.getRealAmount();
176                     }
177                 }
178             }
179         }
180     }
181     
182 
183     /** update to now time */
184     public void updateLastModificationDate(){
185         setLastModificationDate(new Date());
186     }
187     
188     /**
189      * Getter for property txns.
190      * @return a read/only list ?? Value of property txns. can't be null
191      * To change data use given method (hence keep order) or respect order
192      */
193     public List getTxns() {
194         return txns;
195         //return Collections.unmodifiableList(txns); //this crash the xml serialization
196     }
197     
198     /**
199      * Setter for property txns.
200      * automatically update total, but when change are made to the list, need to call manually udpateTotals
201      * @param txns New value of property txns. ArrayList better (or Random Access)
202      *
203      */
204     public void setTxns(List txns) {
205         //first sort per date
206         Collections.sort(txns);//no need of Comparator Txn is Comparable already
207         this.txns = txns;
208         updateTotals(new Date());
209         updateLastModificationDate();
210     }
211 
212     /** in right place in the list 
213      * warning date may be null !! (virement)
214      * different of addTransaction because it manages virement 
215      */
216     public int addTransactionAndRelated(Transaction t){
217         if ( t instanceof Virement ) {
218             return addVirement((Virement)t);
219         } else {
220             return addTransaction(t);
221         }
222     }
223     
224     /** in right place in the list 
225      * warning date may be null !! (virement)
226      * do nothing special for virement (use addVirement or addTransactionAndRelated instead)
227      */
228     public int addTransaction(Transaction t){
229         int index = Collections.binarySearch(this.txns,t);//Comparator ??
230         if ( index >= 0 ) {
231             //it is not already there ! just got the same date
232             this.txns.add(index,t);            
233         } else {//index = -insertionpoint -1
234             index = -index -1;
235             this.txns.add(index,t);            
236         }
237         updateLastModificationDate();
238         return index;
239     }
240 
241     /**
242      * in right place in the list 
243      * warning date may be null !! (virement)
244      * special for virement insert also the related ...
245      * @param v virement, related may be null, warning this could be also a RelatedVirement
246      *  RelatedVirement could be copied or cut like original virement ??
247      * @return index of given transaction in this account's list
248      */
249     public int addVirement(Virement v){
250         int index = -1;
251         Virement related = v.getRelatedVirement();
252         if ( related == null ) {
253             if ( v instanceof RelatedVirement )
254                 related = new Virement();//creates a related automatticaly
255             else
256                 related = new RelatedVirement();
257             v.setRelatedVirement(related); 
258         }
259         if ( v instanceof RelatedVirement ) {
260             related.setSourceAccount(v.getTargetAccount());
261             v.getTargetAccount().addTransaction(related);//add the virement to its account
262             index = related.setTargetAccount(this);//will add v to current account
263         } else {
264             // v is a real Virement
265             v.setSourceAccount(this);
266             index =this.addTransaction(v);
267             v.setTargetAccount(v.getTargetAccount());//add the related to right account
268         }
269         return index;
270     }
271     
272     /** remove the transaction from the list of this account, 
273      * (do nothing special on virement)
274      */
275     public void removeTransaction(Transaction t) {
276         if ( t == null ) return;
277         boolean removed = this.txns.remove(t);// if false , throw new exception ??
278         //sumsInvalid = false;
279         updateLastModificationDate();
280     }
281 
282     /** @param index of the transaction in the list */
283 //    public void removeTransaction(int index) {
284 //        if ( index < 0 ) throw new IndexOutOfBoundsException("Index:"+index);
285 //        Transaction t = (Transaction)this.txns.get(index);
286 //        removeTransaction(t);
287 //        //sumsInvalid = false;
288 //    }
289 
290     /** same as removeTransaction but remove also the related */
291     public void removeVirement(Virement v) {
292         removeTransaction(v);
293         Virement related = v.getRelatedVirement();
294         if ( related != null ) {
295             related.setRelatedVirement(null); //mark the related as already removed
296             related.getSourceAccount().removeTransaction(related);
297         }
298     }
299     
300     /** remove transaction and related (means if virement) 
301      * if a virement remove also the related txn
302      */
303     public void removeTransactionAndRelated(int index) {
304         if ( index < 0 ) throw new IllegalArgumentException(i18n.getString("error_index_<_0"));
305         Transaction t = (Transaction)this.txns.get(index);
306         if ( t instanceof Virement ) {
307             removeVirement((Virement)t);
308         } else {
309             removeTransaction(t);
310         }
311     }
312 
313     /**
314      * used just before removing the account for example
315      * could be called removeAllTxnWithRelated
316      */
317     public void removeAllTxnWithRelated() {
318         // don't use iterator as it produces ConcurrentModificationException
319         List txns = this.txns;
320         for (Iterator it = txns.iterator(); it.hasNext() ;) {
321             Transaction t = (Transaction)it.next();
322             if ( t instanceof Virement ) {
323                 Virement v = (Virement)t;
324                 Virement related = v.getRelatedVirement();
325                 if ( related != null ) {
326                     related.setRelatedVirement(null); //mark the related as already removed
327                     if ( related.getSourceAccount() != null 
328                         && related.getSourceAccount() != this ) {
329                         related.getSourceAccount().removeTransaction(related);
330                     }
331                 }
332                 it.remove();
333             }
334         }
335         updateLastModificationDate();
336     }
337     
338     /** 
339      * to call whenever a transaction change its date and want to keep the list ordered
340      * Automatically managed related for Virement
341      * @param index current place in the list for the txn
342      * @return new place in the list for the transaction
343      */
344     public int updateTransaction(int index){
345         if ( index < 0 ) throw new IllegalArgumentException(i18n.getString("error_index_<_0"));
346         Transaction t = (Transaction)this.txns.get(index);
347         return updateTransaction(t);
348     }
349 
350     /** 
351      * to call whenever a transaction change its date and want to keep the list ordered
352      * Automatically managed related synch for Virement
353      * @return new place in the list for the transaction
354      */
355     public int updateTransaction(Transaction t){
356         removeTransaction(t);
357         int newindex = addTransaction(t);
358         if ( t instanceof Virement ) { //assume we don't call updateTransaction on relatedVirement as they are r/o
359             Virement v = (Virement)t;
360             Virement related = v.getRelatedVirement();
361             // same as call to updateTransaction(related)
362             related.getSourceAccount().removeTransaction(related);
363             related.getSourceAccount().addTransaction(related);            
364         }
365         updateLastModificationDate();
366         return newindex;
367     }
368     
369     /** @return true if this key could define this bean */
370     public boolean isEqual(String key) {
371         return key.equalsIgnoreCase(getName());
372     }
373     
374     /** Getter for property bank.
375      * @return Value of property bank.
376      */
377     public com.pjsofts.eurobudget.beans.Bank getBank() {
378         return bank;
379     }
380     
381     /** Setter for property bank.
382      * @param bank New value of property bank.
383      */
384     public void setBank(com.pjsofts.eurobudget.beans.Bank bank) {
385         this.bank = bank;
386         updateLastModificationDate();
387     }
388     
389     /** Getter for property ccy.
390      * @return Value of property ccy.
391      */
392     public Currency getCcy() {
393         return ccy;
394     }
395     
396     /** Setter for property ccy.
397      * @param ccy New value of property ccy.
398      */
399     public void setCcy(Currency ccy) {
400         this.ccy = ccy;
401         updateLastModificationDate();
402     }
403     
404     /** Getter for property id.
405      * @return Value of property id.
406      */
407     public java.lang.String getId() {
408         return id;
409     }
410     
411     /** Setter for property id.
412      * @param id New value of property id.
413      */
414     public void setId(java.lang.String id) {
415         this.id = id;
416         updateLastModificationDate();
417     }
418     
419     /** Getter for property name.
420      * @return Value of property name.
421      */
422     public java.lang.String getName() {
423         return name;
424     }
425     
426     /** Setter for property name.
427      * @param name New value of property name.
428      */
429     public void setName(java.lang.String name) {
430         this.name = name;
431         updateLastModificationDate();
432     }
433     
434     /** Getter for property total.
435      * warning: need to call updateTotal before ...
436      * @return Value of property total.
437      */
438     public double getTotal() {
439         return total;
440     }
441     
442     //    /** Setter for property total.
443     //     * @param total New value of property total.
444     //     */
445     //    public void setTotal(double total) {
446     //        this.total = total;
447     //    }
448     
449     /** Getter for property creationDate.
450      * @return Value of property creationDate.
451      */
452     public Date getCreationDate() {
453         return this.creationDate;
454     }
455     
456     /** Setter for property creationDate.
457      * @param creationDate New value of property creationDate.
458      */
459     public void setCreationDate(Date creationDate) {
460         this.creationDate = creationDate;
461         updateLastModificationDate();
462     }
463     
464     /** Getter for property iban.
465      * @return Value of property iban.
466      */
467     public java.lang.String getIban() {
468         return iban;
469     }
470     
471     /** Setter for property iban.
472      * @param iban New value of property iban.
473      */
474     public void setIban(java.lang.String iban) {
475         this.iban = iban;
476         updateLastModificationDate();
477     }
478     
479     /** Getter for property refs.
480      * @return Value of property refs.
481      */
482     public java.lang.String getRefs() {
483         return refs;
484     }
485     
486     /** Setter for property refs.
487      * @param refs New value of property refs.
488      */
489     public void setRefs(java.lang.String refs) {
490         this.refs = refs;
491         updateLastModificationDate();
492     }
493     
494     
495     public String toString() {
496         String retValue;
497         retValue = getName();//super.toString();
498         return retValue;
499     }
500     
501     /** Getter for property initialAmount.
502      * @return Value of property initialAmount.
503      */
504     public double getInitialAmount() {
505         return initialAmount;
506     }
507     
508     /** Setter for property initialAmount.
509      * @param initialAmount New value of property initialAmount.
510      */
511     public void setInitialAmount(double initialAmount) {
512         this.initialAmount = initialAmount;
513         updateLastModificationDate();
514     }
515     
516     /** Getter for property ctotal.
517      * @return Value of property ctotal.
518      */
519     public double getCtotal() {
520         return ctotal;
521     }
522 
523     public double getCreditDayTotal() {
524         return creditDayTotal;
525     }
526     public double getDebitDayTotal() {
527         return debitDayTotal;
528     }
529     
530     //    /** Setter for property ctotal.
531     //     * @param ctotal New value of property ctotal.
532     //     */
533     //    public void setCtotal(double ctotal) {
534     //        this.ctotal = ctotal;
535     //    }
536     
537     /** Getter for property dtotal.
538      * @return Value of property dtotal.
539      */
540     public double getDtotal() {
541         return dtotal;
542     }
543     
544     /** Getter for property dtotal.
545      * @return Value of property dtotal.
546      */
547     public double getDayTotal() {
548         return dayTotal;
549     }
550     
551     /** Getter for property minAmount.
552      * @return Value of property minAmount.
553      */
554     public double getMinAmount() {
555         return minAmount;
556     }
557     
558     /** Setter for property minAmount.
559      * @param minAmount New value of property minAmount.
560      */
561     public void setMinAmount(double minAmount) {
562         this.minAmount = minAmount;
563         updateLastModificationDate();
564     }
565     
566     /** Getter for property maxAmount.
567      * @return Value of property maxAmount.
568      */
569     public double getMaxAmount() {
570         return maxAmount;
571     }
572 
573     /** Setter for property maxAmount.
574      * @param maxAmount New value of property maxAmount.
575      */
576     public void setMaxAmount(double maxAmount) {
577         this.maxAmount = maxAmount;
578         updateLastModificationDate();
579     }
580     
581     /** Getter for property flags.
582      * @return Value of property flags.
583      * Warning: do no modify this object !
584      */
585     public BitSet getFlags() {
586         return flags; // or clone() ??
587     }
588 
589     /** don't use with flag none */
590     public boolean isFlagSet(int flag) {
591         // assume flag always > 0
592         assert flag >= 0;
593         return flags.get(flag);
594     }
595     
596     /** convenient 
597      * see FLAG_xxx to get possible flag values
598      */
599     public void setFlag(int flag, boolean value) {
600         flags.set(flag,value);
601         updateLastModificationDate();
602     }
603 
604     /** Setter for property flags.
605      * @param flags New value of property flags.
606      */
607     public void setFlags(BitSet flags) {
608         this.flags = flags;
609         updateLastModificationDate();
610     }
611     
612     /** Getter for property lastModificationDate.
613      * @return Value of property lastModificationDate.
614      */
615     public Date getLastModificationDate() {
616         return lastModificationDate;
617     }
618     
619     /** Setter for property lastModificationDate.
620      * @param lastModificationDate New value of property lastModificationDate.
621      */
622     public void setLastModificationDate(Date lastModificationDate) {
623         this.lastModificationDate = lastModificationDate;
624     }
625     
626     /** Getter for property lastBalancedDate.
627      * @return Value of property lastBalancedDate.
628      */
629     public Date getLastBalancedDate() {
630         return lastBalancedDate;
631     }
632     
633     /** Setter for property lastBalancedDate.
634      * @param lastBalancedDate New value of property lastBalancedDate.
635      */
636     public void setLastBalancedDate(Date lastBalancedDate) {
637         this.lastBalancedDate = lastBalancedDate;
638     }
639     
640     /** Getter for property accountGroup.
641      * @return Value of property accountGroup.
642      */
643     public com.pjsofts.eurobudget.beans.AccountGroup getAccountGroup() {
644         return accountGroup;
645     }
646     
647     /** Setter for property accountGroup.
648      * @param accountGroup New value of property accountGroup.
649      */
650     public void setAccountGroup(com.pjsofts.eurobudget.beans.AccountGroup accountGroup) {
651         this.accountGroup = accountGroup;
652         updateLastModificationDate();
653     }
654     
655     /**
656      * Compares this object with the specified object for order.  Returns a
657      * negative integer, zero, or a positive integer as this object is less
658      * than, equal to, or greater than the specified object.<p>
659      *
660      * In the foregoing description, the notation
661      * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
662      * <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
663      * <tt>0</tt>, or <tt>1</tt> according to whether the value of <i>expression</i>
664      * is negative, zero or positive.
665      *
666      * The implementor must ensure <tt>sgn(x.compareTo(y)) ==
667      * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This
668      * implies that <tt>x.compareTo(y)</tt> must throw an exception iff
669      * <tt>y.compareTo(x)</tt> throws an exception.)<p>
670      *
671      * The implementor must also ensure that the relation is transitive:
672      * <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt> implies
673      * <tt>x.compareTo(z)&gt;0</tt>.<p>
674      *
675      * Finally, the implementer must ensure that <tt>x.compareTo(y)==0</tt>
676      * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
677      * all <tt>z</tt>.<p>
678      *
679      * It is strongly recommended, but <i>not</i> strictly required that
680      * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any
681      * class that implements the <tt>Comparable</tt> interface and violates
682      * this condition should clearly indicate this fact.  The recommended
683      * language is "Note: this class has a natural ordering that is
684      * inconsistent with equals."
685      *
686      * @param   o the Object to be compared.
687      * @return  a negative integer, zero, or a positive integer as this object
688      *     is less than, equal to, or greater than the specified object.
689      *
690      * @throws ClassCastException if the specified object's type prevents it
691      *        from being compared to this Object.
692      */
693     public int compareTo(Object o) {
694         if ( o instanceof Account ) {
695             Account obj = (Account)o;
696             if ( obj == null || obj.getName() == null )
697                 return 1;
698             if ( this.getName() == null )
699                 return -1;
700             return this.getName().compareToIgnoreCase(obj.getName());
701         } else {
702             throw new java.lang.IllegalArgumentException(i18n.getString("error_Compare_only_to_another_Account"));
703         }
704     }
705     
706     /** */
707     public boolean contains(Transaction t) {
708         if ( t == null || this.txns == null ) return false;
709         return this.txns.contains(t);
710     }
711     
712     /** Getter for property comment.
713      * @return Value of property comment.
714      */
715     public String getComment() {
716         return this.comment;
717     }
718     
719     /** Setter for property comment.
720      * @param comment New value of property comment.
721      */
722     public void setComment(String comment) {
723         this.comment = comment;
724     }
725     
726 }
727 
728 
729