001    /**
002     * Copyright 2004-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.coa.businessobject;
017    
018    import java.sql.Date;
019    import java.util.Calendar;
020    import java.util.LinkedHashMap;
021    import java.util.List;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.commons.lang.time.DateUtils;
025    import org.kuali.rice.core.api.mo.common.active.Inactivatable;
026    import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
027    
028    /**
029     * 
030     */
031    public class Account extends PersistableBusinessObjectBase implements Inactivatable {
032        protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(Account.class);
033    
034        private String chartOfAccountsCode;
035        private String accountNumber;
036        private String accountName;
037        private Date accountCreateDate;
038        private Date accountEffectiveDate;
039        private Date accountExpirationDate;
040        private boolean active;
041        private String organizationCode;
042    
043    
044        public String getOrganizationCode() {
045                    return organizationCode;
046            }
047    
048            public void setOrganizationCode(String organizationCode) {
049                    this.organizationCode = organizationCode;
050            }
051    
052    
053            private Chart chartOfAccounts;
054        private Organization organization;
055    
056        private List subAccounts;
057    
058        /**
059         * Default no-arg constructor.
060         */
061        public Account() {
062            active = true; // assume active is true until set otherwise
063        }
064        
065    
066        /**
067         * Gets the accountNumber attribute.
068         * 
069         * @return Returns the accountNumber
070         */
071        public String getAccountNumber() {
072            return accountNumber;
073        }
074    
075        /**
076         * Sets the accountNumber attribute.
077         * 
078         * @param accountNumber The accountNumber to set.
079         */
080        public void setAccountNumber(String accountNumber) {
081            this.accountNumber = accountNumber;
082        }
083    
084        /**
085         * Gets the accountName attribute.
086         * 
087         * @return Returns the accountName
088         */
089        public String getAccountName() {
090            return accountName;
091        }
092    
093        /**
094         * Sets the accountName attribute.
095         * 
096         * @param accountName The accountName to set.
097         */
098        public void setAccountName(String accountName) {
099            this.accountName = accountName;
100        }
101    
102        /**
103         * Gets the accountCreateDate attribute.
104         * 
105         * @return Returns the accountCreateDate
106         */
107        public Date getAccountCreateDate() {
108            return accountCreateDate;
109        }
110    
111        /**
112         * Sets the accountCreateDate attribute.
113         * 
114         * @param accountCreateDate The accountCreateDate to set.
115         */
116        public void setAccountCreateDate(Date accountCreateDate) {
117            this.accountCreateDate = accountCreateDate;
118        }
119    
120        /**
121         * Gets the accountEffectiveDate attribute.
122         * 
123         * @return Returns the accountEffectiveDate
124         */
125        public Date getAccountEffectiveDate() {
126            return accountEffectiveDate;
127        }
128    
129        /**
130         * Sets the accountEffectiveDate attribute.
131         * 
132         * @param accountEffectiveDate The accountEffectiveDate to set.
133         */
134        public void setAccountEffectiveDate(Date accountEffectiveDate) {
135            this.accountEffectiveDate = accountEffectiveDate;
136        }
137    
138        /**
139         * Gets the accountExpirationDate attribute.
140         * 
141         * @return Returns the accountExpirationDate
142         */
143        public Date getAccountExpirationDate() {
144            return accountExpirationDate;
145        }
146    
147        /**
148         * Sets the accountExpirationDate attribute.
149         * 
150         * @param accountExpirationDate The accountExpirationDate to set.
151         */
152        public void setAccountExpirationDate(Date accountExpirationDate) {
153            this.accountExpirationDate = accountExpirationDate;
154        }
155    
156        /**
157         * This method determines whether the account is expired or not. Note that if Expiration Date is the same date as testDate, then
158         * this will return false. It will only return true if the account expiration date is one day earlier than testDate or earlier.
159         * Note that this logic ignores all time components when doing the comparison. It only does the before/after comparison based on
160         * date values, not time-values.
161         * 
162         * @param testDate - Calendar instance with the date to test the Account's Expiration Date against. This is most commonly set to
163         *        today's date.
164         * @return true or false based on the logic outlined above
165         */
166        public boolean isExpired(Calendar testDate) {
167            if (LOG.isDebugEnabled()) {
168                LOG.debug("entering isExpired(" + testDate + ")");
169            }
170    
171            // dont even bother trying to test if the accountExpirationDate is null
172            if (this.accountExpirationDate == null) {
173                return false;
174            }
175    
176            // remove any time-components from the testDate
177            testDate = DateUtils.truncate(testDate, Calendar.DAY_OF_MONTH);
178    
179            // get a calendar reference to the Account Expiration
180            // date, and remove any time components
181            Calendar acctDate = Calendar.getInstance();
182            acctDate.setTime(this.accountExpirationDate);
183            acctDate = DateUtils.truncate(acctDate, Calendar.DAY_OF_MONTH);
184    
185            // if the Account Expiration Date is before the testDate
186            if (acctDate.before(testDate)) {
187                return true;
188            }
189            else {
190                return false;
191            }
192        }
193    
194        /**
195         * This method determines whether the account is expired or not. Note that if Expiration Date is the same date as testDate, then
196         * this will return false. It will only return true if the account expiration date is one day earlier than testDate or earlier.
197         * Note that this logic ignores all time components when doing the comparison. It only does the before/after comparison based on
198         * date values, not time-values.
199         * 
200         * @param testDate - java.util.Date instance with the date to test the Account's Expiration Date against. This is most commonly
201         *        set to today's date.
202         * @return true or false based on the logic outlined above
203         */
204        public boolean isExpired(Date testDate) {
205    
206            // dont even bother trying to test if the accountExpirationDate is null
207            if (this.accountExpirationDate == null) {
208                return false;
209            }
210    
211            Calendar acctDate = Calendar.getInstance();
212            acctDate.setTime(testDate);
213            return isExpired(acctDate);
214        }
215    
216        /**
217         * Gets the active attribute.
218         * 
219         * @return Returns the active
220         */
221        public boolean isActive() {
222            return active;
223        }
224    
225        /**
226         * Sets the active attribute.
227         * 
228         * @param active The active to set.
229         */
230        public void setActive(boolean active) {
231            this.active = active;
232        }
233    
234        /**
235         * Returns whether this account is not active or not
236         * 
237         * @return the opposite of isActive()
238         */
239        public boolean isClosed() {
240            return !active;
241        }
242        
243        /**
244         * Sets the closed attribute.
245         * 
246         * @param closed The closed to set.
247         */
248        public void setClosed(boolean closed) {
249            this.active = !closed;
250        }
251    
252        /**
253         * Gets the chartOfAccounts attribute.
254         * 
255         * @return Returns the chartOfAccounts
256         */
257        public Chart getChartOfAccounts() {
258            return chartOfAccounts;
259        }
260    
261        /**
262         * Sets the chartOfAccounts attribute.
263         * 
264         * @param chartOfAccounts The chartOfAccounts to set.
265         * @deprecated
266         */
267        public void setChartOfAccounts(Chart chartOfAccounts) {
268            this.chartOfAccounts = chartOfAccounts;
269        }
270    
271        /**
272         * Gets the organization attribute.
273         * 
274         * @return Returns the organization
275         */
276        public Organization getOrganization() {
277            return organization;
278        }
279    
280        /**
281         * Sets the organization attribute.
282         * 
283         * @param organization The organization to set.
284         * @deprecated
285         */
286        public void setOrganization(Organization organization) {
287            this.organization = organization;
288        }
289    
290        /**
291         * @return Returns the subAccounts.
292         */
293        public List getSubAccounts() {
294            return subAccounts;
295        }
296    
297    
298        /**
299         * @param subAccounts The subAccounts to set.
300         */
301        public void setSubAccounts(List subAccounts) {
302            this.subAccounts = subAccounts;
303        }
304    
305    
306        /**
307         * @return Returns the chartOfAccountsCode.
308         */
309        public String getChartOfAccountsCode() {
310            return chartOfAccountsCode;
311        }
312    
313    
314        /**
315         * @param chartOfAccountsCode The chartOfAccountsCode to set.
316         */
317        public void setChartOfAccountsCode(String chartOfAccountsCode) {
318            this.chartOfAccountsCode = chartOfAccountsCode;
319        }
320    
321        /**
322         * @see org.kuali.rice.kns.bo.BusinessObjectBase#toStringMapper()
323         */
324        protected LinkedHashMap toStringMapper() {
325            LinkedHashMap m = new LinkedHashMap();
326    
327            m.put("chartCode", this.chartOfAccountsCode);
328            m.put("accountNumber", this.accountNumber);
329    
330            return m;
331        }
332    
333    
334        /**
335         * Implementing equals since I need contains to behave reasonably in a hashed datastructure.
336         * 
337         * @see java.lang.Object#equals(java.lang.Object)
338         */
339        public boolean equals(Object obj) {
340            boolean equal = false;
341    
342            if (obj != null) {
343                if (this.getClass().equals(obj.getClass())) {
344                    Account other = (Account) obj;
345    
346                    if (StringUtils.equals(this.getChartOfAccountsCode(), other.getChartOfAccountsCode())) {
347                        if (StringUtils.equals(this.getAccountNumber(), other.getAccountNumber())) {
348                            equal = true;
349                        }
350                    }
351                }
352            }
353    
354            return equal;
355        }
356    
357        /**
358         * Calcluates hashCode based on current values of chartOfAccountsCode and accountNumber fields. Somewhat dangerous, since both
359         * of those fields are mutable, but I don't expect people to be editing those values directly for Accounts stored in hashed
360         * datastructures.
361         * 
362         * @see java.lang.Object#hashCode()
363         */
364        public int hashCode() {
365            String hashString = getChartOfAccountsCode() + "|" + getAccountNumber();
366    
367            return hashString.hashCode();
368        }
369    
370    
371        /**
372         * Convenience method to make the primitive account fields from this Account easier to compare to the account fields from
373         * another Account or an AccountingLine
374         * 
375         * @return String representing the account associated with this Accounting
376         */
377        public String getAccountKey() {
378            String key = getChartOfAccountsCode() + ":" + getAccountNumber();
379            return key;
380        }
381    }
382