001/*
002 * Copyright 2005 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 */
016package org.kuali.ole.gl.businessobject;
017
018import java.math.BigDecimal;
019import java.sql.Date;
020import java.util.LinkedHashMap;
021import java.util.Map;
022
023import org.kuali.ole.coa.businessobject.A21SubAccount;
024import org.kuali.ole.coa.businessobject.Account;
025import org.kuali.ole.coa.businessobject.Chart;
026import org.kuali.ole.coa.businessobject.ObjectCode;
027import org.kuali.ole.coa.businessobject.SubAccount;
028import org.kuali.ole.coa.businessobject.SubObjectCode;
029import org.kuali.ole.gl.GeneralLedgerConstants;
030import org.kuali.ole.sys.OLEPropertyConstants;
031import org.kuali.ole.sys.businessobject.ReportBusinessObject;
032import org.kuali.ole.sys.businessobject.SystemOptions;
033import org.kuali.ole.sys.context.SpringContext;
034import org.kuali.rice.core.api.util.type.KualiDecimal;
035import org.kuali.rice.coreservice.framework.parameter.ParameterService;
036import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
037import org.kuali.rice.krad.util.ObjectUtils;
038
039/**
040 * Just as Balance is a summarization of Entry, so AccountBalance is a summarization of Balance.
041 * Specifically, it stores the current budget, actual, and encumbrance totals in one record.
042 */
043public class AccountBalance extends PersistableBusinessObjectBase implements ReportBusinessObject{
044    static final long serialVersionUID = 6873573726961704771L;
045
046    private Integer universityFiscalYear;
047    private String chartOfAccountsCode;
048    private String accountNumber;
049    private String subAccountNumber;
050    private String objectCode;
051    private String subObjectCode;
052    private KualiDecimal currentBudgetLineBalanceAmount;
053    private KualiDecimal accountLineActualsBalanceAmount;
054    private KualiDecimal accountLineEncumbranceBalanceAmount;
055    private Date timestamp;
056
057    private Chart chart;
058    private Account account;
059    private SubAccount subAccount;
060    private ObjectCode financialObject;
061    private SubObjectCode financialSubObject;
062    private A21SubAccount a21SubAccount;
063    private TransientBalanceInquiryAttributes dummyBusinessObject;
064    private SystemOptions option;
065    private String title;
066
067    public static final String TYPE_CONSOLIDATION = "Consolidation";
068    public static final String TYPE_LEVEL = "Level";
069    public static final String TYPE_OBJECT = "Object";
070
071    public AccountBalance() {
072        super();
073        this.dummyBusinessObject = new TransientBalanceInquiryAttributes();
074        this.financialObject = new ObjectCode();
075    }
076
077    public AccountBalance(Transaction t) {
078        this();
079        universityFiscalYear = t.getUniversityFiscalYear();
080        chartOfAccountsCode = t.getChartOfAccountsCode();
081        accountNumber = t.getAccountNumber();
082        subAccountNumber = t.getSubAccountNumber();
083        objectCode = t.getFinancialObjectCode();
084        subObjectCode = t.getFinancialSubObjectCode();
085        currentBudgetLineBalanceAmount = KualiDecimal.ZERO;
086        accountLineActualsBalanceAmount = KualiDecimal.ZERO;
087        accountLineEncumbranceBalanceAmount = KualiDecimal.ZERO;
088    }
089
090    public AccountBalance(String type, Map data, Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber) {
091        this();
092
093        this.universityFiscalYear = universityFiscalYear;
094        this.chartOfAccountsCode = chartOfAccountsCode;
095        this.accountNumber = accountNumber;
096        subAccountNumber = (String) data.get(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER);
097
098        currentBudgetLineBalanceAmount = new KualiDecimal((BigDecimal) data.get(GeneralLedgerConstants.ColumnNames.CURRENT_BDLN_BALANCE_AMOUNT));
099        accountLineActualsBalanceAmount = new KualiDecimal((BigDecimal) data.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ACTUALS_BALANCE_AMOUNT));
100        accountLineEncumbranceBalanceAmount = new KualiDecimal((BigDecimal) data.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ENCUMBRANCE_BALANCE_AMOUNT));
101
102        financialObject.getFinancialObjectLevel().setFinancialConsolidationObjectCode((String) data.get(GeneralLedgerConstants.ColumnNames.CONSOLIDATION_OBJECT_CODE));
103        financialObject.getFinancialObjectLevel().getFinancialConsolidationObject().setFinConsolidationObjectCode((String) data.get(GeneralLedgerConstants.ColumnNames.CONSOLIDATION_OBJECT_CODE));
104
105        if (TYPE_CONSOLIDATION.equals(type)) {
106            financialObject.getFinancialObjectType().setFinancialReportingSortCode((String) data.get(GeneralLedgerConstants.ColumnNames.REPORT_SORT_CODE));
107            financialObject.getFinancialObjectLevel().getFinancialConsolidationObject().setFinancialReportingSortCode((String) data.get(GeneralLedgerConstants.ColumnNames.CONSOLIDATION_REPORT_SORT_CODE));
108            
109            financialObject.getFinancialObjectType().setBasicAccountingCategoryCode((String) data.get(GeneralLedgerConstants.ColumnNames.ACCTG_CTGRY_CD));
110            fixVariance();
111        }
112        else if (TYPE_LEVEL.equals(type)) {
113            financialObject.getFinancialObjectLevel().setFinancialReportingSortCode((String) data.get(GeneralLedgerConstants.ColumnNames.REPORT_SORT_CODE));
114            financialObject.setFinancialObjectLevelCode((String) data.get(GeneralLedgerConstants.ColumnNames.OBJECT_LEVEL_CODE2));
115            financialObject.getFinancialObjectLevel().setFinancialObjectLevelCode((String) data.get(GeneralLedgerConstants.ColumnNames.OBJECT_LEVEL_CODE2));
116
117            // tricking it so getVariance() works
118            financialObject.getFinancialObjectType().setBasicAccountingCategoryCode((String) data.get(GeneralLedgerConstants.ColumnNames.ACCTG_CTGRY_CD));
119            fixVariance();
120        }
121        else if (TYPE_OBJECT.equals(type)) {
122            objectCode = (String) data.get(GeneralLedgerConstants.ColumnNames.OBJECT_CODE);
123            financialObject.setFinancialObjectLevelCode((String) data.get(GeneralLedgerConstants.ColumnNames.OBJECT_LEVEL_CODE));
124            financialObject.getFinancialObjectLevel().setFinancialObjectLevelCode((String) data.get(GeneralLedgerConstants.ColumnNames.OBJECT_LEVEL_CODE));
125
126            // tricking it so getVariance() works
127            financialObject.getFinancialObjectType().setBasicAccountingCategoryCode((String) data.get(GeneralLedgerConstants.ColumnNames.ACCTG_CTGRY_CD));
128            fixVariance();
129        }
130        else {
131            throw new RuntimeException("Unknown type: " + type);
132        }
133    }
134
135    /**
136     * Perform the refresh non-updateable method but do an additional check on the following  objects
137     * within financialObject if either the object is null or the primary key returned null.  If that is true,
138     * re-use the original object/values.
139     * 
140     * 1. FinancialObjectLevel
141     * 2. FinancialObjectType
142     *
143     * @see org.kuali.ole.gl.businessobject.ReportBusinessObject#refreshNonUpdateableForReport()
144     */
145    @Override
146    public void refreshNonUpdateableForReport() {
147        //store the orignal financial object
148        ObjectCode origfinancialObject = getFinancialObject();
149        super.refreshNonUpdateableReferences();
150        
151        if (ObjectUtils.isNull(financialObject)){
152            //entire financial object is  null, simply replace with the original
153            setFinancialObject(origfinancialObject);
154        }else{
155            //check individual subobjects
156            
157            //check financial object level - if the object is null or primary key value is null, this object needs to be updated
158            if (ObjectUtils.isNull(financialObject.getFinancialObjectLevel()) || ObjectUtils.isNull(financialObject.getFinancialObjectLevel().getFinancialObjectLevelCode())){
159                financialObject.setFinancialObjectLevel(origfinancialObject.getFinancialObjectLevel());
160                financialObject.setFinancialObjectLevelCode(origfinancialObject.getFinancialObjectCode());
161            }
162            //check financial object type - if the object is null or primary key value is null, this object needs to be updated
163            if (ObjectUtils.isNull(financialObject.getFinancialObjectType().getCode()) || ObjectUtils.isNull(financialObject.getFinancialObjectType())){
164                financialObject.setFinancialObjectType(origfinancialObject.getFinancialObjectType());
165            }
166        }
167    }
168
169    /**
170     * Retrieve from parameter the Accounting Category Expense Code 
171     * 
172     * @return
173     */
174    public String getAccountingCategoryExpenseCode(){
175        ParameterService parameterService = SpringContext.getBean(ParameterService.class);
176        String accountingCategoryExpenseCode = parameterService.getParameterValueAsString(AccountBalanceByConsolidation.class, GeneralLedgerConstants.BASIC_ACCOUNTING_CATEGORY_REPRESENTING_EXPENSES);
177        return accountingCategoryExpenseCode;
178    }
179
180    public AccountBalance(String title) {
181        this();
182        this.title = title;
183        // financialObject.getFinancialObjectLevel().setFinancialConsolidationObjectCode(title);
184        currentBudgetLineBalanceAmount = KualiDecimal.ZERO;
185        accountLineActualsBalanceAmount = KualiDecimal.ZERO;
186        accountLineEncumbranceBalanceAmount = KualiDecimal.ZERO;
187    }
188    
189    /**
190     * Constructs a AccountBalance.java per the primary keys only of the passed in accountBalanceHistory
191     * @param accountBalanceHistory
192     */
193    public AccountBalance(AccountBalanceHistory accountBalanceHistory) {
194        universityFiscalYear = accountBalanceHistory.getUniversityFiscalYear();
195        chartOfAccountsCode = accountBalanceHistory.getChartOfAccountsCode();
196        accountNumber = accountBalanceHistory.getAccountNumber();
197        subAccountNumber = accountBalanceHistory.getSubAccountNumber();
198        objectCode = accountBalanceHistory.getObjectCode();
199        subObjectCode = accountBalanceHistory.getSubObjectCode();
200    }
201
202    public void fixVariance() {
203        dummyBusinessObject.setGenericAmount(getVariance());
204    }
205
206    public KualiDecimal getVariance() {
207
208        KualiDecimal variance = KualiDecimal.ZERO;
209
210        // calculate the variance based on the basic accounting category code
211        if (getAccountingCategoryExpenseCode().equals(financialObject.getFinancialObjectType().getBasicAccountingCategoryCode())) {
212            variance = currentBudgetLineBalanceAmount.subtract(accountLineActualsBalanceAmount);
213            variance = variance.subtract(accountLineEncumbranceBalanceAmount);
214        }
215        else {
216            variance = accountLineActualsBalanceAmount.subtract(currentBudgetLineBalanceAmount);
217        }
218        return variance;
219    }
220
221    public void add(AccountBalance ab) {
222        currentBudgetLineBalanceAmount = currentBudgetLineBalanceAmount.add(ab.currentBudgetLineBalanceAmount);
223        accountLineActualsBalanceAmount = accountLineActualsBalanceAmount.add(ab.accountLineActualsBalanceAmount);
224        accountLineEncumbranceBalanceAmount = accountLineEncumbranceBalanceAmount.add(ab.accountLineEncumbranceBalanceAmount);
225    }
226
227    /*
228     * (non-Javadoc)
229     * 
230     * @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper()
231     */
232    protected LinkedHashMap toStringMapper_RICE20_REFACTORME() {
233
234        LinkedHashMap map = new LinkedHashMap();
235        map.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, getUniversityFiscalYear());
236        map.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, getChartOfAccountsCode());
237        map.put(OLEPropertyConstants.ACCOUNT_NUMBER, getAccountNumber());
238        map.put(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, getSubAccountNumber());
239        map.put(OLEPropertyConstants.OBJECT_CODE, getObjectCode());
240        map.put(OLEPropertyConstants.SUB_OBJECT_CODE, getSubObjectCode());
241        return map;
242    }
243
244    public String getTitle() {
245        return title;
246    }
247
248    public A21SubAccount getA21SubAccount() {
249        return a21SubAccount;
250    }
251
252    public void setA21SubAccount(A21SubAccount subAccount) {
253        a21SubAccount = subAccount;
254    }
255
256    public SystemOptions getOption() {
257        return option;
258    }
259
260    public void setOption(SystemOptions option) {
261        this.option = option;
262    }
263
264    public KualiDecimal getAccountLineActualsBalanceAmount() {
265        return accountLineActualsBalanceAmount;
266    }
267
268    public void setAccountLineActualsBalanceAmount(KualiDecimal accountLineActualsBalanceAmount) {
269        this.accountLineActualsBalanceAmount = accountLineActualsBalanceAmount;
270    }
271
272    public KualiDecimal getAccountLineEncumbranceBalanceAmount() {
273        return accountLineEncumbranceBalanceAmount;
274    }
275
276    public void setAccountLineEncumbranceBalanceAmount(KualiDecimal accountLineEncumbranceBalanceAmount) {
277        this.accountLineEncumbranceBalanceAmount = accountLineEncumbranceBalanceAmount;
278    }
279
280    public String getAccountNumber() {
281        return accountNumber;
282    }
283
284    public void setAccountNumber(String accountNumber) {
285        this.accountNumber = accountNumber;
286    }
287
288    public String getChartOfAccountsCode() {
289        return chartOfAccountsCode;
290    }
291
292    public void setChartOfAccountsCode(String chartOfAccountsCode) {
293        this.chartOfAccountsCode = chartOfAccountsCode;
294    }
295
296    public KualiDecimal getCurrentBudgetLineBalanceAmount() {
297        return currentBudgetLineBalanceAmount;
298    }
299
300    public void setCurrentBudgetLineBalanceAmount(KualiDecimal currentBudgetLineBalanceAmount) {
301        this.currentBudgetLineBalanceAmount = currentBudgetLineBalanceAmount;
302    }
303
304    public String getObjectCode() {
305        return objectCode;
306    }
307
308    public void setObjectCode(String objectCode) {
309        this.objectCode = objectCode;
310    }
311
312    public String getSubAccountNumber() {
313        return subAccountNumber;
314    }
315
316    public void setSubAccountNumber(String subAccountNumber) {
317        this.subAccountNumber = subAccountNumber;
318    }
319
320    public String getSubObjectCode() {
321        return subObjectCode;
322    }
323
324    public void setSubObjectCode(String subObjectCode) {
325        this.subObjectCode = subObjectCode;
326    }
327
328    public Date getTimestamp() {
329        return timestamp;
330    }
331
332    public void setTimestamp(Date timestamp) {
333        this.timestamp = timestamp;
334    }
335
336    public Integer getUniversityFiscalYear() {
337        return universityFiscalYear;
338    }
339
340    public void setUniversityFiscalYear(Integer universityFiscalYear) {
341        this.universityFiscalYear = universityFiscalYear;
342    }
343
344    /**
345     * Gets the account attribute.
346     * 
347     * @return Returns the account.
348     */
349    public Account getAccount() {
350        return account;
351    }
352
353    /**
354     * Sets the account attribute value.
355     * 
356     * @param account The account to set.
357     */
358    public void setAccount(Account account) {
359        this.account = account;
360    }
361
362    /**
363     * Gets the chart attribute.
364     * 
365     * @return Returns the chart.
366     */
367    public Chart getChart() {
368        return chart;
369    }
370
371    /**
372     * Sets the chart attribute value.
373     * 
374     * @param chart The chart to set.
375     */
376    public void setChart(Chart chart) {
377        this.chart = chart;
378    }
379
380    /**
381     * Gets the financialObject attribute.
382     * 
383     * @return Returns the financialObject.
384     */
385    public ObjectCode getFinancialObject() {
386        return financialObject;
387    }
388
389    /**
390     * Sets the financialObject attribute value.
391     * 
392     * @param financialObject The financialObject to set.
393     */
394    public void setFinancialObject(ObjectCode financialObject) {
395        this.financialObject = financialObject;
396    }
397
398    /**
399     * Gets the dummyBusinessObject attribute.
400     * 
401     * @return Returns the dummyBusinessObject.
402     */
403    public TransientBalanceInquiryAttributes getDummyBusinessObject() {
404        return dummyBusinessObject;
405    }
406
407    /**
408     * Sets the dummyBusinessObject attribute value.
409     * 
410     * @param dummyBusinessObject The dummyBusinessObject to set.
411     */
412    public void setDummyBusinessObject(TransientBalanceInquiryAttributes dummyBusinessObject) {
413        this.dummyBusinessObject = dummyBusinessObject;
414    }
415
416    /**
417     * Gets the subAccount attribute.
418     * 
419     * @return Returns the subAccount.
420     */
421    public SubAccount getSubAccount() {
422        return subAccount;
423    }
424
425    /**
426     * Sets the subAccount attribute value.
427     * 
428     * @param subAccount The subAccount to set.
429     */
430    public void setSubAccount(SubAccount subAccount) {
431        this.subAccount = subAccount;
432    }
433
434    /**
435     * Gets the subObject
436     * 
437     * @return
438     */
439    public SubObjectCode getFinancialSubObject() {
440        return financialSubObject;
441    }
442
443    /**
444     * Sets the subObject.
445     * 
446     * @param financialSubObject
447     */
448    public void setFinancialSubObject(SubObjectCode financialSubObject) {
449        this.financialSubObject = financialSubObject;
450    }
451
452}