001/*
002 *  jDTAUS Banking API
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.banking.dtaus;
022
023import java.io.Serializable;
024import java.math.BigInteger;
025import java.util.Arrays;
026import java.util.Currency;
027import org.jdtaus.banking.AlphaNumericText27;
028import org.jdtaus.banking.Bankleitzahl;
029import org.jdtaus.banking.Kontonummer;
030import org.jdtaus.banking.Referenznummer11;
031import org.jdtaus.banking.Textschluessel;
032
033/**
034 * "C" record.
035 *
036 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
037 * @version $JDTAUS: Transaction.java 8799 2012-12-03 18:52:42Z schulte $
038 */
039public class Transaction implements Cloneable, Serializable
040{
041
042    /** Constant for the name of property {@code type}. */
043    public static final String PROP_TYPE = "org.jdtaus.banking.dtaus.Transaction.PROP_TYPE";
044
045    /** Constant for the name of property {@code amount}. */
046    public static final String PROP_AMOUNT = "org.jdtaus.banking.dtaus.Transaction.PROP_AMOUNT";
047
048    /** Constant for the name of property {@code reference}. */
049    public static final String PROP_REFERENCE = "org.jdtaus.banking.dtaus.Transaction.PROP_REFERENCE";
050
051    /** Constant for the name of property {@code descriptions}. */
052    public static final String PROP_DESCRIPTIONS = "org.jdtaus.banking.dtaus.Transaction.PROP_DESCRIPTIONS";
053
054    /** Constant for the name of property {@code primaryBank}. */
055    public static final String PROP_PRIMARYBANK = "org.jdtaus.banking.dtaus.Transaction.PROP_PRIMARYBANK";
056
057    /** Constant for the name of property {@code executiveAccount}. */
058    public static final String PROP_EXECUTIVEACCOUNT = "org.jdtaus.banking.dtaus.Transaction.PROP_EXECUTIVEACCOUNT";
059
060    /** Constant for the name of property {@code executiveBank}. */
061    public static final String PROP_EXECUTIVEBANK = "org.jdtaus.banking.dtaus.Transaction.PROP_EXECUTIVEBANK";
062
063    /** Constant for the name of property {@code executiveName}. */
064    public static final String PROP_EXECUTIVENAME = "org.jdtaus.banking.dtaus.Transaction.PROP_EXECUTIVENAME";
065
066    /** Constant for the name of property {@code executiveExt}. */
067    public static final String PROP_EXECUTIVEEXT = "org.jdtaus.banking.dtaus.Transaction.PROP_EXECUTIVEEXT";
068
069    /** Constant for the name of property {@code targetAccount}. */
070    public static final String PROP_TARGETACCOUNT = "org.jdtaus.banking.dtaus.Transaction.PROP_TARGETACCOUNT";
071
072    /** Constant for the name of property {@code targetBank}. */
073    public static final String PROP_TARGETBANK = "org.jdtaus.banking.dtaus.Transaction.PROP_TARGETBANK";
074
075    /** Constant for the name of property {@code targetName}. */
076    public static final String PROP_TARGETNAME = "org.jdtaus.banking.dtaus.Transaction.PROP_TARGETNAME";
077
078    /** Constant for the name of property {@code targetExt}. */
079    public static final String PROP_TARGETEXT = "org.jdtaus.banking.dtaus.Transaction.PROP_TARGETEXT";
080
081    /** Constant for the name of property {@code currency}. */
082    public static final String PROP_CURRENCY = "org.jdtaus.banking.dtaus.Transaction.PROP_CURRENCY";
083
084    /** Serial version UID for backwards compatibility with 1.0.x classes. */
085    private static final long serialVersionUID = 1450133285078489771L;
086
087    /**
088     * Payment type.
089     * @serial
090     */
091    private Textschluessel type;
092
093    /**
094     * Amount of money to transfer.
095     * @serial
096     */
097    private BigInteger amount;
098
099    /**
100     * The currency of the transaction.
101     * @serial
102     */
103    private Currency currency;
104
105    /**
106     * Reference number of the transaction.
107     * @serial
108     */
109    private Referenznummer11 reference;
110
111    /**
112     * Descriptions of the transaction.
113     * @serial
114     */
115    private AlphaNumericText27[] descriptions;
116
117    /**
118     * Code of the primary participating bank.
119     * @serial
120     */
121    private Bankleitzahl primaryBank;
122
123    /**
124     * Ordering bank account.
125     * @serial
126     */
127    private Kontonummer executiveAccount;
128
129    /**
130     * Ordering bank.
131     * @serial
132     */
133    private Bankleitzahl executiveBank;
134
135    /**
136     * Ordering customer.
137     * @serial
138     */
139    private AlphaNumericText27 executiveName;
140
141    /**
142     * Extension to property {@code executiveName}.
143     * @serial
144     */
145    private AlphaNumericText27 executiveExt;
146
147    /**
148     * Bank account of the debitor/creditor depending on the transaction's type.
149     * @serial
150     */
151    private Kontonummer targetAccount;
152
153    /**
154     * Bank of the debitor/creditor depending on the transaction's type.
155     * @serial
156     */
157    private Bankleitzahl targetBank;
158
159    /**
160     * Debitor/creditor name depending on the transaction's type.
161     * @serial
162     */
163    private AlphaNumericText27 targetName;
164
165    /**
166     * Extension to property {@code targetName}.
167     * @serial
168     */
169    private AlphaNumericText27 targetExt;
170
171    /** Cached hash code. */
172    private transient int hashCode = NO_HASHCODE;
173    private static final int NO_HASHCODE = Integer.MIN_VALUE;
174
175    /** Creates a new {@code Transaction} instance. */
176    public Transaction()
177    {
178        super();
179    }
180
181    /**
182     * Getter for property {@code type}.
183     *
184     * @return Payment type of the transaction.
185     */
186    public Textschluessel getType()
187    {
188        return this.type;
189    }
190
191    /**
192     * Setter for property {@code type}.
193     *
194     * @param value Payment type of the transaction.
195     */
196    public void setType( final Textschluessel value )
197    {
198        this.type = value;
199        this.hashCode = NO_HASHCODE;
200    }
201
202    /**
203     * Getter for property {@code amount}.
204     *
205     * @return Amount of money to transfer in the smallest unit of the currency (&euro; = Cent).
206     */
207    public BigInteger getAmount()
208    {
209        return this.amount;
210    }
211
212    /**
213     * Setter for property {@code amount}.
214     *
215     * @param value The amount of money to transfer in the smallest unit of the currency (&euro; = Cent).
216     */
217    public void setAmount( final BigInteger value )
218    {
219        this.amount = value;
220        this.hashCode = NO_HASHCODE;
221    }
222
223    /**
224     * Getter for property {@code currency}.
225     *
226     * @return Currency of the transaction.
227     */
228    public Currency getCurrency()
229    {
230        return this.currency;
231    }
232
233    /**
234     * Setter for property {@code currency}.
235     *
236     * @param value Currency of the transaction.
237     */
238    public void setCurrency( final Currency value )
239    {
240        this.currency = value;
241        this.hashCode = NO_HASHCODE;
242    }
243
244    /**
245     * Getter for property {@code reference}.
246     *
247     * @return Reference number of the transaction or {@code null}.
248     */
249    public Referenznummer11 getReference()
250    {
251        return this.reference;
252    }
253
254    /**
255     * Setter for property {@code reference}.
256     *
257     * @param value Reference number of the transaction or {@code null}.
258     */
259    public void setReference( final Referenznummer11 value )
260    {
261        this.reference = value;
262        this.hashCode = NO_HASHCODE;
263    }
264
265    /**
266     * Gets all descriptions of the transaction.
267     *
268     * @return All descriptions of the transaction or an empty array if the transaction does not hold any description.
269     */
270    public AlphaNumericText27[] getDescriptions()
271    {
272        if ( this.descriptions == null )
273        {
274            this.descriptions = new AlphaNumericText27[ 0 ];
275            this.hashCode = NO_HASHCODE;
276        }
277
278        return (AlphaNumericText27[]) this.descriptions.clone();
279    }
280
281    /**
282     * Sets all descriptions of the transaction.
283     *
284     * @param value All descriptions of the transaction or {@code null}.
285     */
286    public void setDescriptions( final AlphaNumericText27[] value )
287    {
288        this.descriptions = value != null ? (AlphaNumericText27[]) value.clone() : null;
289        this.hashCode = NO_HASHCODE;
290    }
291
292    /**
293     * Getter for property {@code primaryBank}.
294     *
295     * @return Code of the primary participating bank or {@code null}.
296     */
297    public Bankleitzahl getPrimaryBank()
298    {
299        return this.primaryBank;
300    }
301
302    /**
303     * Setter for property {@code primaryBank}.
304     *
305     * @param value Code of the primary participating bank or {@code null}.
306     */
307    public void setPrimaryBank( final Bankleitzahl value )
308    {
309        this.primaryBank = value;
310        this.hashCode = NO_HASHCODE;
311    }
312
313    /**
314     * Getter for property {@code executiveAccount}.
315     *
316     * @return Bank account of the orderer requesting the transaction.
317     */
318    public Kontonummer getExecutiveAccount()
319    {
320        return this.executiveAccount;
321    }
322
323    /**
324     * Setter for property {@code executiveAccount}.
325     *
326     * @param value Bank account of the orderer requesting the transaction.
327     */
328    public void setExecutiveAccount( final Kontonummer value )
329    {
330        this.executiveAccount = value;
331        this.hashCode = NO_HASHCODE;
332    }
333
334    /**
335     * Getter for property {@code executiveBank}.
336     *
337     * @return Ordering bank requesting the transaction.
338     */
339    public Bankleitzahl getExecutiveBank()
340    {
341        return this.executiveBank;
342    }
343
344    /**
345     * Setter for property {@code executiveBank}.
346     *
347     * @param value Ordering bank requesting the transaction.
348     */
349    public void setExecutiveBank( final Bankleitzahl value )
350    {
351        this.executiveBank = value;
352        this.hashCode = NO_HASHCODE;
353    }
354
355    /**
356     * Getter for property {@code executiveName}.
357     *
358     * @return Ordering customer requesting the transaction.
359     */
360    public AlphaNumericText27 getExecutiveName()
361    {
362        return this.executiveName;
363    }
364
365    /**
366     * Setter for property {@code executiveName}.
367     *
368     * @param value Ordering customer requesting the transaction.
369     */
370    public void setExecutiveName( final AlphaNumericText27 value )
371    {
372        this.executiveName = value;
373        this.hashCode = NO_HASHCODE;
374    }
375
376    /**
377     * Getter for property {@code executiveExt}.
378     *
379     * @return Additional data extending the executive name or {@code null}.
380     */
381    public AlphaNumericText27 getExecutiveExt()
382    {
383        return this.executiveExt;
384    }
385
386    /**
387     * Setter for property {@code executiveExt}.
388     *
389     * @param value Additional data extending the executive name or {@code null}.
390     */
391    public void setExecutiveExt( final AlphaNumericText27 value )
392    {
393        this.executiveExt = value;
394        this.hashCode = NO_HASHCODE;
395    }
396
397    /**
398     * Getter for property {@code targetAccount}.
399     *
400     * @return Bank account of the debitor/creditor depending on the transaction's type.
401     */
402    public Kontonummer getTargetAccount()
403    {
404        return this.targetAccount;
405    }
406
407    /**
408     * Setter for property {@code targetAccount}.
409     *
410     * @param value Bank account of the debitor/creditor depending on the transaction's type.
411     */
412    public void setTargetAccount( final Kontonummer value )
413    {
414        this.targetAccount = value;
415        this.hashCode = NO_HASHCODE;
416    }
417
418    /**
419     * Getter for property {@code targetBank}.
420     *
421     * @return Bank of the debitor/creditor depending on the transaction's type.
422     */
423    public Bankleitzahl getTargetBank()
424    {
425        return this.targetBank;
426    }
427
428    /**
429     * Setter for property {@code targetBank}.
430     *
431     * @param value Bank of the debitor/creditor depending on the transaction's type.
432     */
433    public void setTargetBank( final Bankleitzahl value )
434    {
435        this.targetBank = value;
436        this.hashCode = NO_HASHCODE;
437    }
438
439    /**
440     * Getter for property {@code targetName}.
441     *
442     * @return Debitor/creditor depending on the transaction's type.
443     */
444    public AlphaNumericText27 getTargetName()
445    {
446        return this.targetName;
447    }
448
449    /**
450     * Setter for property {@code targetName}.
451     *
452     * @param value Debitor/creditor depending on the transaction's type.
453     */
454    public void setTargetName( final AlphaNumericText27 value )
455    {
456        this.targetName = value;
457        this.hashCode = NO_HASHCODE;
458    }
459
460    /**
461     * Getter for property {@code targetExt}.
462     *
463     * @return Additional data extending the target name or {@code null}.
464     */
465    public AlphaNumericText27 getTargetExt()
466    {
467        return this.targetExt;
468    }
469
470    /**
471     * Setter for property {@code targetExt}.
472     *
473     * @param value Additional data extending the target name or {@code null}.
474     */
475    public void setTargetExt( final AlphaNumericText27 value )
476    {
477        this.targetExt = value;
478        this.hashCode = NO_HASHCODE;
479    }
480
481    /**
482     * Indicates whether some other object is equal to this one by comparing the values of all properties.
483     *
484     * @param o The reference object with which to compare.
485     *
486     * @return {@code true} if this object is the same as {@code o}; {@code false} otherwise.
487     */
488    public boolean equals( final Object o )
489    {
490        boolean equal = this == o;
491
492        if ( !equal && o instanceof Transaction )
493        {
494            final Transaction that = (Transaction) o;
495            equal = ( this.getAmount() == null
496                      ? that.getAmount() == null : this.getAmount().equals( that.getAmount() ) ) &&
497                    ( this.getCurrency() == null
498                      ? that.getCurrency() == null : this.getCurrency().equals( that.getCurrency() ) ) &&
499                    ( this.getExecutiveAccount() == null
500                      ? that.getExecutiveAccount() == null
501                      : this.getExecutiveAccount().equals( that.getExecutiveAccount() ) ) &&
502                    ( this.getExecutiveBank() == null
503                      ? that.getExecutiveBank() == null : this.getExecutiveBank().equals( that.getExecutiveBank() ) ) &&
504                    ( this.getExecutiveName() == null
505                      ? that.getExecutiveName() == null : this.getExecutiveName().equals( that.getExecutiveName() ) ) &&
506                    ( this.getExecutiveExt() == null
507                      ? that.getExecutiveExt() == null : this.getExecutiveExt().equals( that.getExecutiveExt() ) ) &&
508                    ( this.getPrimaryBank() == null
509                      ? that.getPrimaryBank() == null : this.getPrimaryBank().equals( that.getPrimaryBank() ) ) &&
510                    ( this.getReference() == null
511                      ? that.getReference() == null : this.getReference().equals( that.getReference() ) ) &&
512                    ( this.getTargetAccount() == null
513                      ? that.getTargetAccount() == null : this.getTargetAccount().equals( that.getTargetAccount() ) ) &&
514                    ( this.getTargetBank() == null
515                      ? that.getTargetBank() == null : this.getTargetBank().equals( that.getTargetBank() ) ) &&
516                    ( this.getTargetName() == null
517                      ? that.getTargetName() == null : this.getTargetName().equals( that.getTargetName() ) ) &&
518                    ( this.getTargetExt() == null
519                      ? that.getTargetExt() == null : this.getTargetExt().equals( that.getTargetExt() ) ) &&
520                    ( this.getType() == null
521                      ? that.getType() == null : this.getType().equals( that.getType() ) );
522
523            if ( equal )
524            {
525                if ( this.getDescriptions() == null || this.getDescriptions().length == 0 )
526                {
527                    equal = that.getDescriptions() == null || that.getDescriptions().length == 0;
528                }
529                else
530                {
531                    equal = that.getDescriptions() != null && that.getDescriptions().length != 0
532                            ? Arrays.equals( this.getDescriptions(), that.getDescriptions() ) : false;
533
534                }
535            }
536        }
537
538        return equal;
539    }
540
541    /**
542     * Returns a hash code value for this object.
543     *
544     * @return A hash code value for this object.
545     */
546    public int hashCode()
547    {
548        if ( this.hashCode == NO_HASHCODE )
549        {
550            int hc = 23;
551            hc = 37 * hc + ( this.amount == null ? 0 : this.amount.hashCode() );
552            hc = 37 * hc + ( this.currency == null ? 0 : this.currency.hashCode() );
553            hc = 37 * hc + ( this.executiveAccount == null ? 0 : this.executiveAccount.hashCode() );
554            hc = 37 * hc + ( this.executiveBank == null ? 0 : this.executiveBank.hashCode() );
555            hc = 37 * hc + ( this.executiveExt == null ? 0 : this.executiveExt.hashCode() );
556            hc = 37 * hc + ( this.executiveName == null ? 0 : this.executiveName.hashCode() );
557            hc = 37 * hc + ( this.primaryBank == null ? 0 : this.primaryBank.hashCode() );
558            hc = 37 * hc + ( this.reference == null ? 0 : this.reference.hashCode() );
559            hc = 37 * hc + ( this.targetAccount == null ? 0 : this.targetAccount.hashCode() );
560            hc = 37 * hc + ( this.targetBank == null ? 0 : this.targetBank.hashCode() );
561            hc = 37 * hc + ( this.targetExt == null ? 0 : this.targetExt.hashCode() );
562            hc = 37 * hc + ( this.targetName == null ? 0 : this.targetName.hashCode() );
563            hc = 37 * hc + ( this.type == null ? 0 : this.type.hashCode() );
564
565            if ( this.descriptions == null || this.descriptions.length == 0 )
566            {
567                hc = 37 * hc;
568            }
569            else
570            {
571                for ( int i = this.descriptions.length - 1; i >= 0; i-- )
572                {
573                    hc = 37 * hc + this.descriptions[i].hashCode();
574                }
575            }
576
577            this.hashCode = hc;
578        }
579
580        return this.hashCode;
581    }
582
583    /**
584     * Creates and returns a copy of this object.
585     *
586     * @return A clone of this instance.
587     */
588    public Object clone()
589    {
590        try
591        {
592            return super.clone();
593        }
594        catch ( final CloneNotSupportedException e )
595        {
596            throw new AssertionError( e );
597        }
598    }
599
600    /**
601     * Returns a string representation of the object.
602     *
603     * @return A string representation of the object.
604     */
605    public String toString()
606    {
607        return super.toString() + this.internalString();
608    }
609
610    /**
611     * Creates a string representing the properties of the instance.
612     *
613     * @return A string representing the properties of the instance.
614     */
615    private String internalString()
616    {
617        return new StringBuffer( 300 ).append( '{' ).
618            append( "amount=" ).append( this.amount ).
619            append( ", currency=" ).append( this.currency ).
620            append( ", descriptions=" ).append( toString( this.descriptions ) ).
621            append( ", executiveAccount=" ).append( this.executiveAccount ).
622            append( ", executiveBank=" ).append( this.executiveBank ).
623            append( ", executiveName=" ).append( (Object) this.executiveName ).
624            append( ", executiveExt=" ).append( (Object) this.executiveExt ).
625            append( ", primaryBank=" ).append( this.primaryBank ).
626            append( ", reference=" ).append( this.reference ).
627            append( ", targetAccount=" ).append( this.targetAccount ).
628            append( ", targetBank=" ).append( this.targetBank ).
629            append( ", targetName=" ).append( (Object) this.targetName ).
630            append( ", targetExt=" ).append( (Object) this.targetExt ).
631            append( ", type=" ).append( this.type ).
632            append( '}' ).toString();
633
634    }
635
636    private static String toString( final AlphaNumericText27[] texts )
637    {
638        String string = null;
639
640        if ( texts != null )
641        {
642            final StringBuffer stringBuilder =
643                new StringBuffer( texts.length * AlphaNumericText27.MAX_LENGTH + texts.length * 2 + 2 );
644
645            stringBuilder.append( '[' );
646
647            for ( int i = 0, max = texts.length - 1; i < max; i++ )
648            {
649                texts[i].format( stringBuilder );
650
651                if ( i < max )
652                {
653                    stringBuilder.append( ", " );
654                }
655            }
656
657            string = stringBuilder.append( ']' ).toString();
658        }
659
660        return string;
661    }
662
663}