Source Code Cross Referenced for BudgetAdjustmentDocumentRule.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » module » financial » rules » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » Kuali Financial System » org.kuali.module.financial.rules 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2006-2007 The Kuali Foundation.
0003:         * 
0004:         * Licensed under the Educational Community License, Version 1.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         * 
0008:         * http://www.opensource.org/licenses/ecl1.php
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        package org.kuali.module.financial.rules;
0017:
0018:        import static org.kuali.kfs.KFSConstants.SOURCE_ACCOUNTING_LINE_ERRORS;
0019:        import static org.kuali.kfs.KFSConstants.TARGET_ACCOUNTING_LINE_ERRORS;
0020:        import static org.kuali.kfs.KFSKeyConstants.ERROR_DOCUMENT_ACCOUNTING_LINE_TOTAL_CHANGED;
0021:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.GENERATE_TOF_GLPE_ENTRIES_PARM_NM;
0022:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_10_PERIOD_CODE;
0023:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_11_PERIOD_CODE;
0024:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_12_PERIOD_CODE;
0025:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_1_PERIOD_CODE;
0026:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_2_PERIOD_CODE;
0027:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_3_PERIOD_CODE;
0028:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_4_PERIOD_CODE;
0029:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_5_PERIOD_CODE;
0030:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_6_PERIOD_CODE;
0031:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_7_PERIOD_CODE;
0032:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_8_PERIOD_CODE;
0033:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.MONTH_9_PERIOD_CODE;
0034:        import static org.kuali.module.financial.rules.BudgetAdjustmentDocumentRuleConstants.TRANSFER_OBJECT_CODE_PARM_NM;
0035:        import static org.kuali.module.financial.rules.TransferOfFundsDocumentRuleConstants.TRANSFER_OF_FUNDS_DOC_TYPE_CODE;
0036:
0037:        import java.util.ArrayList;
0038:        import java.util.HashMap;
0039:        import java.util.Iterator;
0040:        import java.util.List;
0041:        import java.util.Map;
0042:
0043:        import org.apache.commons.lang.StringUtils;
0044:        import org.kuali.core.document.Document;
0045:        import org.kuali.core.exceptions.InfrastructureException;
0046:        import org.kuali.core.util.ErrorMap;
0047:        import org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper;
0048:        import org.kuali.core.util.GlobalVariables;
0049:        import org.kuali.core.util.KualiDecimal;
0050:        import org.kuali.core.util.KualiInteger;
0051:        import org.kuali.core.util.ObjectUtils;
0052:        import org.kuali.core.web.format.CurrencyFormatter;
0053:        import org.kuali.kfs.KFSConstants;
0054:        import org.kuali.kfs.KFSKeyConstants;
0055:        import org.kuali.kfs.KFSPropertyConstants;
0056:        import org.kuali.kfs.bo.AccountingLine;
0057:        import org.kuali.kfs.bo.GeneralLedgerPendingEntry;
0058:        import org.kuali.kfs.bo.Options;
0059:        import org.kuali.kfs.bo.SourceAccountingLine;
0060:        import org.kuali.kfs.context.SpringContext;
0061:        import org.kuali.kfs.document.AccountingDocument;
0062:        import org.kuali.kfs.rule.GenerateGeneralLedgerDocumentPendingEntriesRule;
0063:        import org.kuali.kfs.rules.AccountingDocumentRuleBase;
0064:        import org.kuali.kfs.rules.AccountingLineRuleUtil;
0065:        import org.kuali.kfs.service.OptionsService;
0066:        import org.kuali.kfs.service.ParameterService;
0067:        import org.kuali.module.chart.bo.SubFundGroup;
0068:        import org.kuali.module.financial.bo.BudgetAdjustmentAccountingLine;
0069:        import org.kuali.module.financial.bo.BudgetAdjustmentSourceAccountingLine;
0070:        import org.kuali.module.financial.bo.BudgetAdjustmentTargetAccountingLine;
0071:        import org.kuali.module.financial.document.BudgetAdjustmentDocument;
0072:        import org.kuali.module.financial.service.FiscalYearFunctionControlService;
0073:        import org.kuali.module.financial.service.UniversityDateService;
0074:
0075:        /**
0076:         * Business rule(s) applicable to Budget Adjustment Card document.
0077:         */
0078:        public class BudgetAdjustmentDocumentRule extends
0079:                AccountingDocumentRuleBase
0080:                implements 
0081:                GenerateGeneralLedgerDocumentPendingEntriesRule<AccountingDocument> {
0082:
0083:            private static final String INCOME_STREAM_CHART_ACCOUNT_DELIMITER = "|";
0084:
0085:            /**
0086:             * Validates when an accounting line is added to a budget adjustment document. Accounting line's budget adjustment amount must
0087:             * be non zero and a budget adjustment must be allowed. In addition, the monthly amount fields must equal the current budget
0088:             * amount and the accounting line's account must have a budget recording level and if current adjustment amount is non zero,
0089:             * account must have an associated income stream chart and account.
0090:             * 
0091:             * @param financialDocument submitted document
0092:             * @param accountingLine validated accouting line
0093:             * @return true if validation criteria listed above is true
0094:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#processCustomAddAccountingLineBusinessRules(org.kuali.core.document.FinancialDocument,
0095:             *      org.kuali.core.bo.AccountingLine)
0096:             */
0097:            @Override
0098:            protected boolean processCustomAddAccountingLineBusinessRules(
0099:                    AccountingDocument financialDocument,
0100:                    AccountingLine accountingLine) {
0101:                boolean allow = true;
0102:                BudgetAdjustmentAccountingLine budgetAccountingLine = (BudgetAdjustmentAccountingLine) accountingLine;
0103:
0104:                LOG.debug("validating accounting line # "
0105:                        + accountingLine.getSequenceNumber());
0106:
0107:                /* if they have entered a base amount for line, verify it can be adjusted for the posting year */
0108:                if (budgetAccountingLine.getBaseBudgetAdjustmentAmount()
0109:                        .isNonZero()
0110:                        && !SpringContext
0111:                                .getBean(FiscalYearFunctionControlService.class)
0112:                                .isBaseAmountChangeAllowed(
0113:                                        ((BudgetAdjustmentDocument) financialDocument)
0114:                                                .getPostingYear())) {
0115:                    GlobalVariables
0116:                            .getErrorMap()
0117:                            .putError(
0118:                                    KFSPropertyConstants.BASE_BUDGET_ADJUSTMENT_AMOUNT,
0119:                                    KFSKeyConstants.ERROR_DOCUMENT_BA_BASE_AMOUNT_CHANGE_NOT_ALLOWED);
0120:                    allow = false;
0121:                }
0122:
0123:                LOG.debug("beginning monthly lines validation ");
0124:                allow = allow
0125:                        && validateMonthlyLines(financialDocument,
0126:                                accountingLine);
0127:
0128:                LOG.debug("beginning account number validation ");
0129:                allow = allow
0130:                        && validateAccountNumber(financialDocument,
0131:                                accountingLine);
0132:
0133:                LOG.debug("end validating accounting line, has errors: "
0134:                        + allow);
0135:
0136:                return allow;
0137:            }
0138:
0139:            /**
0140:             * Calls FinancialDocumentRuleBase.processCustomRouteDocumentBusinessRules() and also validates whether the document's
0141:             * accounting lines' fund group and sub fund group codes associate with the 'Budget Adjustment Restriction Code'
0142:             * 
0143:             * @param document submitted document
0144:             * @return true if criteria above is met
0145:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.Document)
0146:             */
0147:            @Override
0148:            protected boolean processCustomRouteDocumentBusinessRules(
0149:                    Document document) {
0150:                boolean isValid = super 
0151:                        .processCustomRouteDocumentBusinessRules(document);
0152:                BudgetAdjustmentDocument baDocument = (BudgetAdjustmentDocument) document;
0153:
0154:                if (isValid) {
0155:                    isValid = isValid
0156:                            && validateFundGroupAdjustmentRestrictions(baDocument);
0157:                }
0158:
0159:                return isValid;
0160:            }
0161:
0162:            /**
0163:             * The budget adjustment document creates GL pending entries much differently that common tp-edocs. The glpes are created for
0164:             * BB, CB, and MB balance types. Up to 14 entries per line can be created. Along with this, the BA will create TOF entries if
0165:             * needed to move funding.
0166:             * 
0167:             * @param financialDocument submitted accounting document
0168:             * @param accountingLine validated accounting line
0169:             * @param sequenceHelper helper class for keeping track of sequence number
0170:             * @return true if GLPE entries are successfully created.
0171:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#processGenerateGeneralLedgerPendingEntries(org.kuali.core.document.FinancialDocument,
0172:             *      org.kuali.core.bo.AccountingLine, org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper)
0173:             */
0174:            @Override
0175:            public boolean processGenerateGeneralLedgerPendingEntries(
0176:                    AccountingDocument financialDocument,
0177:                    AccountingLine accountingLine,
0178:                    GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
0179:                boolean success = true;
0180:
0181:                // determine if we are on increase or decrease side
0182:                KualiDecimal amountSign = null;
0183:                if (accountingLine instanceof  SourceAccountingLine) {
0184:                    amountSign = new KualiDecimal(-1);
0185:                } else {
0186:                    amountSign = new KualiDecimal(1);
0187:                }
0188:
0189:                BudgetAdjustmentAccountingLine budgetAccountingLine = (BudgetAdjustmentAccountingLine) accountingLine;
0190:                Integer currentFiscalYear = SpringContext.getBean(
0191:                        UniversityDateService.class).getCurrentFiscalYear();
0192:                /* Create Base Budget GLPE if base amount != 0 */
0193:                if (budgetAccountingLine.getBaseBudgetAdjustmentAmount()
0194:                        .isNonZero()) {
0195:                    GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
0196:                    populateExplicitGeneralLedgerPendingEntry(
0197:                            financialDocument, accountingLine, sequenceHelper,
0198:                            explicitEntry);
0199:
0200:                    /* D/C code is empty for BA, set correct balance type, correct amount */
0201:                    explicitEntry.setTransactionDebitCreditCode("");
0202:                    explicitEntry
0203:                            .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_BASE_BUDGET);
0204:                    explicitEntry
0205:                            .setTransactionLedgerEntryAmount(budgetAccountingLine
0206:                                    .getBaseBudgetAdjustmentAmount().multiply(
0207:                                            amountSign).kualiDecimalValue());
0208:                    // set fiscal period, if next fiscal year set to 01, else leave to current period
0209:                    if (currentFiscalYear.equals(financialDocument
0210:                            .getPostingYear() - 1)) {
0211:                        explicitEntry
0212:                                .setUniversityFiscalPeriodCode(MONTH_1_PERIOD_CODE);
0213:                    }
0214:
0215:                    customizeExplicitGeneralLedgerPendingEntry(
0216:                            financialDocument, accountingLine, explicitEntry);
0217:
0218:                    // add the new explicit entry to the document now
0219:                    financialDocument.getGeneralLedgerPendingEntries().add(
0220:                            explicitEntry);
0221:
0222:                    // increment the sequence counter
0223:                    sequenceHelper.increment();
0224:                }
0225:
0226:                /* Create Current Budget GLPE if current amount != 0 */
0227:                if (budgetAccountingLine.getCurrentBudgetAdjustmentAmount()
0228:                        .isNonZero()) {
0229:                    GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
0230:                    populateExplicitGeneralLedgerPendingEntry(
0231:                            financialDocument, accountingLine, sequenceHelper,
0232:                            explicitEntry);
0233:
0234:                    /* D/C code is empty for BA, set correct balance type, correct amount */
0235:                    explicitEntry.setTransactionDebitCreditCode("");
0236:                    explicitEntry
0237:                            .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_CURRENT_BUDGET);
0238:                    explicitEntry
0239:                            .setTransactionLedgerEntryAmount(budgetAccountingLine
0240:                                    .getCurrentBudgetAdjustmentAmount()
0241:                                    .multiply(amountSign));
0242:                    // set fiscal period, if next fiscal year set to 01, else leave to current period
0243:                    if (currentFiscalYear.equals(financialDocument
0244:                            .getPostingYear() - 1)) {
0245:                        explicitEntry.setUniversityFiscalPeriodCode("01");
0246:                    }
0247:
0248:                    customizeExplicitGeneralLedgerPendingEntry(
0249:                            financialDocument, accountingLine, explicitEntry);
0250:
0251:                    // add the new explicit entry to the document now
0252:                    financialDocument.getGeneralLedgerPendingEntries().add(
0253:                            explicitEntry);
0254:
0255:                    // create montly lines (MB)
0256:                    if (budgetAccountingLine
0257:                            .getFinancialDocumentMonth1LineAmount().isNonZero()) {
0258:                        sequenceHelper.increment();
0259:                        createMonthlyBudgetGLPE(financialDocument,
0260:                                accountingLine, sequenceHelper,
0261:                                MONTH_1_PERIOD_CODE, budgetAccountingLine
0262:                                        .getFinancialDocumentMonth1LineAmount()
0263:                                        .multiply(amountSign));
0264:                    }
0265:                    if (budgetAccountingLine
0266:                            .getFinancialDocumentMonth2LineAmount().isNonZero()) {
0267:                        sequenceHelper.increment();
0268:                        createMonthlyBudgetGLPE(financialDocument,
0269:                                accountingLine, sequenceHelper,
0270:                                MONTH_2_PERIOD_CODE, budgetAccountingLine
0271:                                        .getFinancialDocumentMonth2LineAmount()
0272:                                        .multiply(amountSign));
0273:                    }
0274:                    if (budgetAccountingLine
0275:                            .getFinancialDocumentMonth3LineAmount().isNonZero()) {
0276:                        sequenceHelper.increment();
0277:                        createMonthlyBudgetGLPE(financialDocument,
0278:                                accountingLine, sequenceHelper,
0279:                                MONTH_3_PERIOD_CODE, budgetAccountingLine
0280:                                        .getFinancialDocumentMonth3LineAmount()
0281:                                        .multiply(amountSign));
0282:                    }
0283:                    if (budgetAccountingLine
0284:                            .getFinancialDocumentMonth4LineAmount().isNonZero()) {
0285:                        sequenceHelper.increment();
0286:                        createMonthlyBudgetGLPE(financialDocument,
0287:                                accountingLine, sequenceHelper,
0288:                                MONTH_4_PERIOD_CODE, budgetAccountingLine
0289:                                        .getFinancialDocumentMonth4LineAmount()
0290:                                        .multiply(amountSign));
0291:                    }
0292:                    if (budgetAccountingLine
0293:                            .getFinancialDocumentMonth5LineAmount().isNonZero()) {
0294:                        sequenceHelper.increment();
0295:                        createMonthlyBudgetGLPE(financialDocument,
0296:                                accountingLine, sequenceHelper,
0297:                                MONTH_5_PERIOD_CODE, budgetAccountingLine
0298:                                        .getFinancialDocumentMonth5LineAmount()
0299:                                        .multiply(amountSign));
0300:                    }
0301:                    if (budgetAccountingLine
0302:                            .getFinancialDocumentMonth6LineAmount().isNonZero()) {
0303:                        sequenceHelper.increment();
0304:                        createMonthlyBudgetGLPE(financialDocument,
0305:                                accountingLine, sequenceHelper,
0306:                                MONTH_6_PERIOD_CODE, budgetAccountingLine
0307:                                        .getFinancialDocumentMonth6LineAmount()
0308:                                        .multiply(amountSign));
0309:                    }
0310:                    if (budgetAccountingLine
0311:                            .getFinancialDocumentMonth7LineAmount().isNonZero()) {
0312:                        sequenceHelper.increment();
0313:                        createMonthlyBudgetGLPE(financialDocument,
0314:                                accountingLine, sequenceHelper,
0315:                                MONTH_7_PERIOD_CODE, budgetAccountingLine
0316:                                        .getFinancialDocumentMonth7LineAmount()
0317:                                        .multiply(amountSign));
0318:                    }
0319:                    if (budgetAccountingLine
0320:                            .getFinancialDocumentMonth8LineAmount().isNonZero()) {
0321:                        sequenceHelper.increment();
0322:                        createMonthlyBudgetGLPE(financialDocument,
0323:                                accountingLine, sequenceHelper,
0324:                                MONTH_8_PERIOD_CODE, budgetAccountingLine
0325:                                        .getFinancialDocumentMonth8LineAmount()
0326:                                        .multiply(amountSign));
0327:                    }
0328:                    if (budgetAccountingLine
0329:                            .getFinancialDocumentMonth9LineAmount().isNonZero()) {
0330:                        sequenceHelper.increment();
0331:                        createMonthlyBudgetGLPE(financialDocument,
0332:                                accountingLine, sequenceHelper,
0333:                                MONTH_9_PERIOD_CODE, budgetAccountingLine
0334:                                        .getFinancialDocumentMonth9LineAmount()
0335:                                        .multiply(amountSign));
0336:                    }
0337:                    if (budgetAccountingLine
0338:                            .getFinancialDocumentMonth10LineAmount()
0339:                            .isNonZero()) {
0340:                        sequenceHelper.increment();
0341:                        createMonthlyBudgetGLPE(
0342:                                financialDocument,
0343:                                accountingLine,
0344:                                sequenceHelper,
0345:                                MONTH_10_PERIOD_CODE,
0346:                                budgetAccountingLine
0347:                                        .getFinancialDocumentMonth10LineAmount()
0348:                                        .multiply(amountSign));
0349:                    }
0350:                    if (budgetAccountingLine
0351:                            .getFinancialDocumentMonth11LineAmount()
0352:                            .isNonZero()) {
0353:                        sequenceHelper.increment();
0354:                        createMonthlyBudgetGLPE(
0355:                                financialDocument,
0356:                                accountingLine,
0357:                                sequenceHelper,
0358:                                MONTH_11_PERIOD_CODE,
0359:                                budgetAccountingLine
0360:                                        .getFinancialDocumentMonth11LineAmount()
0361:                                        .multiply(amountSign));
0362:                    }
0363:                    if (budgetAccountingLine
0364:                            .getFinancialDocumentMonth12LineAmount()
0365:                            .isNonZero()) {
0366:                        sequenceHelper.increment();
0367:                        createMonthlyBudgetGLPE(
0368:                                financialDocument,
0369:                                accountingLine,
0370:                                sequenceHelper,
0371:                                MONTH_12_PERIOD_CODE,
0372:                                budgetAccountingLine
0373:                                        .getFinancialDocumentMonth12LineAmount()
0374:                                        .multiply(amountSign));
0375:                    }
0376:                }
0377:
0378:                return success;
0379:            }
0380:
0381:            /**
0382:             * Helper method for creating monthly budget pending entry lines.
0383:             * 
0384:             * @param financialDocument submitted accounting document
0385:             * @param accountingLine validated accounting line
0386:             * @param sequenceHelper helper class for keeping track of sequence number
0387:             * @param fiscalPeriod fiscal year period code
0388:             * @param monthAmount ledger entry amount for the month
0389:             */
0390:            private void createMonthlyBudgetGLPE(
0391:                    AccountingDocument financialDocument,
0392:                    AccountingLine accountingLine,
0393:                    GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
0394:                    String fiscalPeriod, KualiDecimal monthAmount) {
0395:                GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
0396:                populateExplicitGeneralLedgerPendingEntry(financialDocument,
0397:                        accountingLine, sequenceHelper, explicitEntry);
0398:
0399:                /* D/C code is empty for BA, set correct balance type, correct amount */
0400:                explicitEntry.setTransactionDebitCreditCode("");
0401:                explicitEntry
0402:                        .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_MONTHLY_BUDGET);
0403:                explicitEntry.setTransactionLedgerEntryAmount(monthAmount);
0404:                explicitEntry.setUniversityFiscalPeriodCode(fiscalPeriod);
0405:
0406:                customizeExplicitGeneralLedgerPendingEntry(financialDocument,
0407:                        accountingLine, explicitEntry);
0408:
0409:                // add the new explicit entry to the document now
0410:                financialDocument.getGeneralLedgerPendingEntries().add(
0411:                        explicitEntry);
0412:            }
0413:
0414:            /**
0415:             * Generates any necessary tof entries to transfer funds needed to make the budget adjustments. Based on income chart and
0416:             * accounts. If there is a difference in funds between an income chart and account, a tof entry needs to be created, along with
0417:             * a budget adjustment entry. Object code used is retrieved by a parameter.
0418:             * 
0419:             * @param financialDocument submitted accounting document
0420:             * @param sequenceHelper helper class for keeping track of sequence number
0421:             * @return true general ledger pending entries are generated without any problems
0422:             * @see org.kuali.core.rule.GenerateGeneralLedgerDocumentPendingEntriesRule#processGenerateDocumentGeneralLedgerPendingEntries(org.kuali.core.document.FinancialDocument,
0423:             *      org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper)
0424:             */
0425:            public boolean processGenerateDocumentGeneralLedgerPendingEntries(
0426:                    AccountingDocument financialDocument,
0427:                    GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
0428:                AccountingDocument FinancialDocument = (AccountingDocument) financialDocument;
0429:                BudgetAdjustmentDocument baDocument = (BudgetAdjustmentDocument) FinancialDocument;
0430:
0431:                boolean success = true;
0432:
0433:                // check on-off tof flag
0434:                boolean generateTransfer = SpringContext.getBean(
0435:                        ParameterService.class).getIndicatorParameter(
0436:                        BudgetAdjustmentDocument.class,
0437:                        GENERATE_TOF_GLPE_ENTRIES_PARM_NM);
0438:                String transferObjectCode = SpringContext.getBean(
0439:                        ParameterService.class).getParameterValue(
0440:                        BudgetAdjustmentDocument.class,
0441:                        TRANSFER_OBJECT_CODE_PARM_NM);
0442:                Integer currentFiscalYear = SpringContext.getBean(
0443:                        UniversityDateService.class).getCurrentFiscalYear();
0444:
0445:                if (generateTransfer) {
0446:                    // map of income chart/accounts with balance as value
0447:                    Map incomeStreamMap = buildIncomeStreamBalanceMap(baDocument);
0448:                    for (Iterator iter = incomeStreamMap.keySet().iterator(); iter
0449:                            .hasNext();) {
0450:                        String chartAccount = (String) iter.next();
0451:                        KualiDecimal streamAmount = (KualiDecimal) incomeStreamMap
0452:                                .get(chartAccount);
0453:                        if (streamAmount.isNonZero()) {
0454:                            // build dummy accounting line for gl population
0455:                            AccountingLine accountingLine = null;
0456:                            try {
0457:                                accountingLine = (SourceAccountingLine) baDocument
0458:                                        .getSourceAccountingLineClass()
0459:                                        .newInstance();
0460:                            } catch (IllegalAccessException e) {
0461:                                throw new InfrastructureException(
0462:                                        "unable to access sourceAccountingLineClass",
0463:                                        e);
0464:                            } catch (InstantiationException e) {
0465:                                throw new InfrastructureException(
0466:                                        "unable to instantiate sourceAccountingLineClass",
0467:                                        e);
0468:                            }
0469:
0470:                            // set income chart and account in line
0471:                            String[] incomeString = StringUtils.split(
0472:                                    chartAccount,
0473:                                    INCOME_STREAM_CHART_ACCOUNT_DELIMITER);
0474:                            accountingLine
0475:                                    .setChartOfAccountsCode(incomeString[0]);
0476:                            accountingLine.setAccountNumber(incomeString[1]);
0477:                            accountingLine
0478:                                    .setFinancialObjectCode(transferObjectCode);
0479:
0480:                            // ////////////////// first create current budget entry/////////////////////////////////////////
0481:                            GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
0482:                            populateExplicitGeneralLedgerPendingEntry(
0483:                                    FinancialDocument, accountingLine,
0484:                                    sequenceHelper, explicitEntry);
0485:
0486:                            /* override and set object type to income */
0487:                            Options options = SpringContext.getBean(
0488:                                    OptionsService.class)
0489:                                    .getCurrentYearOptions();
0490:                            explicitEntry.setFinancialObjectTypeCode(options
0491:                                    .getFinObjectTypeIncomecashCode());
0492:
0493:                            /* D/C code is empty for BA, set correct balance type, correct amount */
0494:                            explicitEntry.setTransactionDebitCreditCode("");
0495:                            explicitEntry
0496:                                    .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_CURRENT_BUDGET);
0497:                            explicitEntry
0498:                                    .setTransactionLedgerEntryAmount(streamAmount);
0499:
0500:                            // set fiscal period, if next fiscal year set to 01, else leave to current period
0501:                            if (currentFiscalYear.equals(FinancialDocument
0502:                                    .getPostingYear() - 1)) {
0503:                                explicitEntry
0504:                                        .setUniversityFiscalPeriodCode(MONTH_1_PERIOD_CODE);
0505:                            }
0506:
0507:                            customizeExplicitGeneralLedgerPendingEntry(
0508:                                    FinancialDocument, accountingLine,
0509:                                    explicitEntry);
0510:
0511:                            // add the new explicit entry to the document now
0512:                            FinancialDocument.getGeneralLedgerPendingEntries()
0513:                                    .add(explicitEntry);
0514:
0515:                            // increment the sequence counter
0516:                            sequenceHelper.increment();
0517:
0518:                            // ////////////////// now create actual TOF entry //////////////////////////////////////////////
0519:                            /* set amount in line so Debit/Credit code can be set correctly */
0520:                            accountingLine.setAmount(streamAmount);
0521:                            explicitEntry = new GeneralLedgerPendingEntry();
0522:                            populateExplicitGeneralLedgerPendingEntry(
0523:                                    FinancialDocument, accountingLine,
0524:                                    sequenceHelper, explicitEntry);
0525:
0526:                            /* override and set object type to transfer */
0527:                            explicitEntry.setFinancialObjectTypeCode(options
0528:                                    .getFinancialObjectTypeTransferIncomeCd());
0529:
0530:                            /* set document type to tof */
0531:                            explicitEntry
0532:                                    .setFinancialDocumentTypeCode(getTransferDocumentType());
0533:
0534:                            // set fiscal period, if next fiscal year set to 01, else leave to current period
0535:                            if (currentFiscalYear.equals(FinancialDocument
0536:                                    .getPostingYear() - 1)) {
0537:                                explicitEntry
0538:                                        .setUniversityFiscalPeriodCode(MONTH_1_PERIOD_CODE);
0539:                            }
0540:
0541:                            // add the new explicit entry to the document now
0542:                            FinancialDocument.getGeneralLedgerPendingEntries()
0543:                                    .add(explicitEntry);
0544:
0545:                            customizeExplicitGeneralLedgerPendingEntry(
0546:                                    FinancialDocument, accountingLine,
0547:                                    explicitEntry);
0548:
0549:                            // increment the sequence counter
0550:                            sequenceHelper.increment();
0551:
0552:                            // ////////////////// now create actual TOF offset //////////////////////////////////////////////
0553:                            GeneralLedgerPendingEntry offsetEntry = (GeneralLedgerPendingEntry) ObjectUtils
0554:                                    .deepCopy(explicitEntry);
0555:                            success &= processOffsetGeneralLedgerPendingEntry(
0556:                                    FinancialDocument, sequenceHelper,
0557:                                    accountingLine, explicitEntry, offsetEntry);
0558:
0559:                            // increment the sequence counter
0560:                            sequenceHelper.increment();
0561:                        }
0562:                    }
0563:                }
0564:
0565:                return success;
0566:            }
0567:
0568:            /**
0569:             * Validates the total of the monthly amount fields (if not 0) equals the current budget amount. If current budget is 0, then
0570:             * total of monthly fields must be 0.
0571:             * 
0572:             * @param financialDocument submitted accounting document
0573:             * @param accountingLine validated accounting line
0574:             * @return true if monthly amount fields equals the current budget amount
0575:             */
0576:            public boolean validateMonthlyLines(
0577:                    AccountingDocument financialDocument,
0578:                    AccountingLine accountingLine) {
0579:                BudgetAdjustmentAccountingLine budgetAdjustmentAccountingLine = (BudgetAdjustmentAccountingLine) accountingLine;
0580:
0581:                boolean validMonthlyLines = true;
0582:
0583:                KualiDecimal monthlyTotal = budgetAdjustmentAccountingLine
0584:                        .getMonthlyLinesTotal();
0585:                if (monthlyTotal.isNonZero()
0586:                        && monthlyTotal
0587:                                .compareTo(budgetAdjustmentAccountingLine
0588:                                        .getCurrentBudgetAdjustmentAmount()) != 0) {
0589:                    GlobalVariables
0590:                            .getErrorMap()
0591:                            .putError(
0592:                                    KFSPropertyConstants.CURRENT_BUDGET_ADJUSTMENT_AMOUNT,
0593:                                    KFSKeyConstants.ERROR_DOCUMENT_BA_MONTH_TOTAL_NOT_EQUAL_CURRENT);
0594:                    validMonthlyLines = false;
0595:                }
0596:
0597:                return validMonthlyLines;
0598:            }
0599:
0600:            /**
0601:             * Retrieves the fund group and sub fund group for each accounting line. Then verifies that the codes associated with the
0602:             * 'Budget Adjustment Restriction Code' field are met.
0603:             * 
0604:             * @param financialDocument submitted accounting document
0605:             * @return true if fund group and sub fund group for each accounting line if restrictions are met
0606:             */
0607:            public boolean validateFundGroupAdjustmentRestrictions(
0608:                    AccountingDocument financialDocument) {
0609:                BudgetAdjustmentDocument baDocument = (BudgetAdjustmentDocument) financialDocument;
0610:                ErrorMap errors = GlobalVariables.getErrorMap();
0611:
0612:                boolean isAdjustmentAllowed = true;
0613:
0614:                List accountingLines = new ArrayList();
0615:                accountingLines.addAll(baDocument.getSourceAccountingLines());
0616:                accountingLines.addAll(baDocument.getTargetAccountingLines());
0617:
0618:                // fund group is global restriction
0619:                boolean restrictedToSubFund = false;
0620:                boolean restrictedToChart = false;
0621:                boolean restrictedToOrg = false;
0622:                boolean restrictedToAccount = false;
0623:
0624:                // fields to help with error messages
0625:                String accountRestrictingSubFund = "";
0626:                String accountRestrictingChart = "";
0627:                String accountRestrictingOrg = "";
0628:                String accountRestrictingAccount = "";
0629:
0630:                // first find the restriction level required by the fund or sub funds used on document
0631:                String restrictionLevel = "";
0632:                for (Iterator iter = accountingLines.iterator(); iter.hasNext();) {
0633:                    BudgetAdjustmentAccountingLine line = (BudgetAdjustmentAccountingLine) iter
0634:                            .next();
0635:                    SubFundGroup subFund = line.getAccount().getSubFundGroup();
0636:                    if (!KFSConstants.BudgetAdjustmentDocumentConstants.ADJUSTMENT_RESTRICTION_LEVEL_NONE
0637:                            .equals(subFund
0638:                                    .getFundGroupBudgetAdjustmentRestrictionLevelCode())) {
0639:                        restrictionLevel = subFund
0640:                                .getFundGroupBudgetAdjustmentRestrictionLevelCode();
0641:                        restrictedToSubFund = true;
0642:                        accountRestrictingSubFund = line.getAccountNumber();
0643:                    } else {
0644:                        restrictionLevel = subFund
0645:                                .getFundGroup()
0646:                                .getFundGroupBudgetAdjustmentRestrictionLevelCode();
0647:                    }
0648:
0649:                    if (KFSConstants.BudgetAdjustmentDocumentConstants.ADJUSTMENT_RESTRICTION_LEVEL_CHART
0650:                            .equals(restrictionLevel)) {
0651:                        restrictedToChart = true;
0652:                        accountRestrictingChart = line.getAccountNumber();
0653:                    } else if (KFSConstants.BudgetAdjustmentDocumentConstants.ADJUSTMENT_RESTRICTION_LEVEL_ORGANIZATION
0654:                            .equals(restrictionLevel)) {
0655:                        restrictedToOrg = true;
0656:                        accountRestrictingOrg = line.getAccountNumber();
0657:                    } else if (KFSConstants.BudgetAdjustmentDocumentConstants.ADJUSTMENT_RESTRICTION_LEVEL_ACCOUNT
0658:                            .equals(restrictionLevel)) {
0659:                        restrictedToAccount = true;
0660:                        accountRestrictingAccount = line.getAccountNumber();
0661:                    }
0662:
0663:                    // if we have a sub fund restriction, this overrides anything coming later
0664:                    if (restrictedToSubFund) {
0665:                        break;
0666:                    }
0667:                }
0668:
0669:                String fundLabel = AccountingLineRuleUtil
0670:                        .getFundGroupCodeLabel();
0671:                String subFundLabel = AccountingLineRuleUtil
0672:                        .getSubFundGroupCodeLabel();
0673:                String chartLabel = AccountingLineRuleUtil.getChartLabel();
0674:                String orgLabel = AccountingLineRuleUtil
0675:                        .getOrganizationCodeLabel();
0676:                String acctLabel = AccountingLineRuleUtil.getAccountLabel();
0677:
0678:                /*
0679:                 * now iterate through the accounting lines again and check each record against the previous to verify the restrictions are
0680:                 * met
0681:                 */
0682:                BudgetAdjustmentAccountingLine previousLine = null;
0683:                for (Iterator iter = accountingLines.iterator(); iter.hasNext();) {
0684:                    BudgetAdjustmentAccountingLine line = (BudgetAdjustmentAccountingLine) iter
0685:                            .next();
0686:
0687:                    if (previousLine != null) {
0688:                        String currentFundGroup = line.getAccount()
0689:                                .getSubFundGroup().getFundGroupCode();
0690:                        String previousFundGroup = previousLine.getAccount()
0691:                                .getSubFundGroup().getFundGroupCode();
0692:
0693:                        if (!currentFundGroup.equals(previousFundGroup)) {
0694:                            errors
0695:                                    .putErrorWithoutFullErrorPath(
0696:                                            KFSConstants.ACCOUNTING_LINE_ERRORS,
0697:                                            KFSKeyConstants.ERROR_DOCUMENT_BA_MIXED_FUND_GROUPS);
0698:                            isAdjustmentAllowed = false;
0699:                            break;
0700:                        }
0701:
0702:                        if (restrictedToSubFund) {
0703:                            if (!line.getAccount().getSubFundGroupCode()
0704:                                    .equals(
0705:                                            previousLine.getAccount()
0706:                                                    .getSubFundGroupCode())) {
0707:                                errors
0708:                                        .putErrorWithoutFullErrorPath(
0709:                                                KFSConstants.ACCOUNTING_LINE_ERRORS,
0710:                                                KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0711:                                                new String[] {
0712:                                                        accountRestrictingSubFund,
0713:                                                        subFundLabel });
0714:                                isAdjustmentAllowed = false;
0715:                                break;
0716:                            }
0717:                        }
0718:
0719:                        if (restrictedToChart) {
0720:                            if (!line.getChartOfAccountsCode().equals(
0721:                                    previousLine.getChartOfAccountsCode())) {
0722:                                if (restrictedToSubFund) {
0723:                                    errors
0724:                                            .putErrorWithoutFullErrorPath(
0725:                                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0726:                                                    KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0727:                                                    new String[] {
0728:                                                            accountRestrictingChart,
0729:                                                            subFundLabel
0730:                                                                    + " and "
0731:                                                                    + chartLabel });
0732:                                } else {
0733:                                    errors
0734:                                            .putErrorWithoutFullErrorPath(
0735:                                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0736:                                                    KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0737:                                                    new String[] {
0738:                                                            accountRestrictingChart,
0739:                                                            fundLabel
0740:                                                                    + " and "
0741:                                                                    + chartLabel });
0742:                                }
0743:                                isAdjustmentAllowed = false;
0744:                                break;
0745:                            }
0746:                        }
0747:
0748:                        if (restrictedToOrg) {
0749:                            if (!line.getAccount().getOrganizationCode()
0750:                                    .equals(
0751:                                            previousLine.getAccount()
0752:                                                    .getOrganizationCode())) {
0753:                                if (restrictedToSubFund) {
0754:                                    errors
0755:                                            .putErrorWithoutFullErrorPath(
0756:                                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0757:                                                    KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0758:                                                    new String[] {
0759:                                                            accountRestrictingOrg,
0760:                                                            subFundLabel
0761:                                                                    + " and "
0762:                                                                    + orgLabel });
0763:                                } else {
0764:                                    errors
0765:                                            .putErrorWithoutFullErrorPath(
0766:                                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0767:                                                    KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0768:                                                    new String[] {
0769:                                                            accountRestrictingOrg,
0770:                                                            fundLabel + " and "
0771:                                                                    + orgLabel });
0772:                                }
0773:                                isAdjustmentAllowed = false;
0774:                                break;
0775:                            }
0776:                        }
0777:
0778:                        if (restrictedToAccount) {
0779:                            if (!line.getAccountNumber().equals(
0780:                                    previousLine.getAccountNumber())) {
0781:                                errors
0782:                                        .putErrorWithoutFullErrorPath(
0783:                                                KFSConstants.ACCOUNTING_LINE_ERRORS,
0784:                                                KFSKeyConstants.ERROR_DOCUMENT_BA_RESTRICTION_LEVELS,
0785:                                                new String[] {
0786:                                                        accountRestrictingAccount,
0787:                                                        acctLabel });
0788:                                isAdjustmentAllowed = false;
0789:                                break;
0790:                            }
0791:                        }
0792:                    }
0793:
0794:                    previousLine = line;
0795:                }
0796:
0797:                return isAdjustmentAllowed;
0798:            }
0799:
0800:            /**
0801:             * Checks account number restrictions, including restrictions in parameters table.
0802:             * 
0803:             * @param financialDocument submitted accounting document
0804:             * @param accountingLine accounting line with validated account number
0805:             * @return true if account number has a budget recording level and if the current adjustment amount is non-zero, account must
0806:             *         have an associated income stream chart and account
0807:             */
0808:            public boolean validateAccountNumber(
0809:                    AccountingDocument financialDocument,
0810:                    AccountingLine accountingLine) {
0811:                BudgetAdjustmentDocument baDocument = (BudgetAdjustmentDocument) financialDocument;
0812:                BudgetAdjustmentAccountingLine budgetAccountingLine = (BudgetAdjustmentAccountingLine) accountingLine;
0813:                ErrorMap errors = GlobalVariables.getErrorMap();
0814:
0815:                String errorKey = KFSPropertyConstants.ACCOUNT_NUMBER;
0816:                boolean accountNumberAllowed = true;
0817:
0818:                // check account has a budget recording level
0819:                if (StringUtils.isBlank(accountingLine.getAccount()
0820:                        .getBudgetRecordingLevelCode())
0821:                        || ACCOUNT_NUMBER.BUDGET_LEVEL_NO_BUDGET
0822:                                .equals(accountingLine.getAccount()
0823:                                        .getBudgetRecordingLevelCode())) {
0824:                    errors
0825:                            .putError(
0826:                                    errorKey,
0827:                                    KFSKeyConstants.ERROR_DOCUMENT_BA_NON_BUDGETED_ACCOUNT,
0828:                                    accountingLine.getAccountNumber());
0829:                    accountNumberAllowed = false;
0830:                }
0831:
0832:                // if current adjustment amount is non zero, account must have an associated income stream chart and account
0833:                if (budgetAccountingLine.getCurrentBudgetAdjustmentAmount()
0834:                        .isNonZero()) {
0835:                    if (ObjectUtils.isNull(accountingLine.getAccount()
0836:                            .getIncomeStreamAccount())) {
0837:                        errors
0838:                                .putError(
0839:                                        errorKey,
0840:                                        KFSKeyConstants.ERROR_DOCUMENT_BA_NO_INCOME_STREAM_ACCOUNT,
0841:                                        accountingLine.getAccountNumber());
0842:                        accountNumberAllowed = false;
0843:                    }
0844:                }
0845:
0846:                return accountNumberAllowed;
0847:            }
0848:
0849:            /**
0850:             * Override needed to check the current, base, and monthly amounts.
0851:             * 
0852:             * @param document submitted accounting document
0853:             * @param accountingLine accounting line where current, base, and monthly amounts are being validated.
0854:             * @see org.kuali.core.rule.AccountingLineRule#isAmountValid(org.kuali.core.document.FinancialDocument,
0855:             *      org.kuali.core.bo.AccountingLine)
0856:             */
0857:            @Override
0858:            public boolean isAmountValid(AccountingDocument document,
0859:                    AccountingLine accountingLine) {
0860:                boolean amountValid = true;
0861:
0862:                BudgetAdjustmentAccountingLine budgetAccountingLine = (BudgetAdjustmentAccountingLine) accountingLine;
0863:
0864:                // check amounts both current and base amounts are not zero
0865:                if (budgetAccountingLine.getCurrentBudgetAdjustmentAmount()
0866:                        .isZero()
0867:                        && budgetAccountingLine.getBaseBudgetAdjustmentAmount()
0868:                                .isZero()) {
0869:                    GlobalVariables.getErrorMap().putError(
0870:                            KFSPropertyConstants.BASE_BUDGET_ADJUSTMENT_AMOUNT,
0871:                            KFSKeyConstants.ERROR_BA_AMOUNT_ZERO);
0872:                    amountValid = false;
0873:                }
0874:
0875:                // if not an error correction, all amounts must be positive
0876:                if (!isErrorCorrection(document)) {
0877:                    amountValid &= checkAmountSign(
0878:                            budgetAccountingLine
0879:                                    .getCurrentBudgetAdjustmentAmount(),
0880:                            KFSPropertyConstants.CURRENT_BUDGET_ADJUSTMENT_AMOUNT,
0881:                            "Current");
0882:                    amountValid &= checkAmountSign(budgetAccountingLine
0883:                            .getBaseBudgetAdjustmentAmount()
0884:                            .kualiDecimalValue(),
0885:                            KFSPropertyConstants.BASE_BUDGET_ADJUSTMENT_AMOUNT,
0886:                            "Base");
0887:                    amountValid &= checkAmountSign(
0888:                            budgetAccountingLine
0889:                                    .getFinancialDocumentMonth1LineAmount(),
0890:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_1_LINE_AMOUNT,
0891:                            "Month 1");
0892:                    amountValid &= checkAmountSign(
0893:                            budgetAccountingLine
0894:                                    .getFinancialDocumentMonth2LineAmount(),
0895:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_2_LINE_AMOUNT,
0896:                            "Month 2");
0897:                    amountValid &= checkAmountSign(
0898:                            budgetAccountingLine
0899:                                    .getFinancialDocumentMonth3LineAmount(),
0900:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_3_LINE_AMOUNT,
0901:                            "Month 3");
0902:                    amountValid &= checkAmountSign(
0903:                            budgetAccountingLine
0904:                                    .getFinancialDocumentMonth4LineAmount(),
0905:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_4_LINE_AMOUNT,
0906:                            "Month 4");
0907:                    amountValid &= checkAmountSign(
0908:                            budgetAccountingLine
0909:                                    .getFinancialDocumentMonth5LineAmount(),
0910:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_5_LINE_AMOUNT,
0911:                            "Month 5");
0912:                    amountValid &= checkAmountSign(
0913:                            budgetAccountingLine
0914:                                    .getFinancialDocumentMonth6LineAmount(),
0915:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_6_LINE_AMOUNT,
0916:                            "Month 6");
0917:                    amountValid &= checkAmountSign(
0918:                            budgetAccountingLine
0919:                                    .getFinancialDocumentMonth7LineAmount(),
0920:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_7_LINE_AMOUNT,
0921:                            "Month 7");
0922:                    amountValid &= checkAmountSign(
0923:                            budgetAccountingLine
0924:                                    .getFinancialDocumentMonth8LineAmount(),
0925:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_8_LINE_AMOUNT,
0926:                            "Month 8");
0927:                    amountValid &= checkAmountSign(
0928:                            budgetAccountingLine
0929:                                    .getFinancialDocumentMonth8LineAmount(),
0930:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_9_LINE_AMOUNT,
0931:                            "Month 9");
0932:                    amountValid &= checkAmountSign(
0933:                            budgetAccountingLine
0934:                                    .getFinancialDocumentMonth10LineAmount(),
0935:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_10_LINE_AMOUNT,
0936:                            "Month 10");
0937:                    amountValid &= checkAmountSign(
0938:                            budgetAccountingLine
0939:                                    .getFinancialDocumentMonth10LineAmount(),
0940:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_11_LINE_AMOUNT,
0941:                            "Month 11");
0942:                    amountValid &= checkAmountSign(
0943:                            budgetAccountingLine
0944:                                    .getFinancialDocumentMonth12LineAmount(),
0945:                            KFSPropertyConstants.FINANCIAL_DOCUMENT_MONTH_12_LINE_AMOUNT,
0946:                            "Month 12");
0947:                }
0948:
0949:                return amountValid;
0950:            }
0951:
0952:            /**
0953:             * In order for the BA document to balance: Total of Base Income Adjustments - Base Expense Adjustments on decrease side must
0954:             * equal Total of Base Income Adjustments - Base Expense Adjustments on increase side Total of Current Income Adjustments - Base
0955:             * Current Adjustments on decrease side must equal Total of Current Income Adjustments - Base Current Adjustments on increase
0956:             * side
0957:             * 
0958:             * @param sumbmitted financial document
0959:             * @return true if base amounts are equal and current amounts balance and income stream balance should equal 0
0960:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isDocumentBalanceValid(org.kuali.core.document.FinancialDocument)
0961:             */
0962:            @Override
0963:            protected boolean isDocumentBalanceValid(
0964:                    AccountingDocument financialDocument) {
0965:                BudgetAdjustmentDocument baDocument = (BudgetAdjustmentDocument) financialDocument;
0966:                ErrorMap errors = GlobalVariables.getErrorMap();
0967:
0968:                boolean balanced = true;
0969:
0970:                // check base amounts are equal
0971:                if (baDocument.getSourceBaseBudgetTotal().compareTo(
0972:                        baDocument.getTargetBaseBudgetTotal()) != 0) {
0973:                    GlobalVariables
0974:                            .getErrorMap()
0975:                            .putError(
0976:                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0977:                                    KFSKeyConstants.ERROR_DOCUMENT_BA_BASE_AMOUNTS_BALANCED);
0978:                    balanced = false;
0979:                }
0980:
0981:                // check current amounts balance, income stream balance Map should add to 0
0982:                Map incomeStreamMap = buildIncomeStreamBalanceMap(baDocument);
0983:                KualiDecimal totalCurrentAmount = new KualiDecimal(0);
0984:                for (Iterator iter = incomeStreamMap.values().iterator(); iter
0985:                        .hasNext();) {
0986:                    KualiDecimal streamAmount = (KualiDecimal) iter.next();
0987:                    totalCurrentAmount = totalCurrentAmount.add(streamAmount);
0988:                }
0989:
0990:                if (totalCurrentAmount.isNonZero()) {
0991:                    GlobalVariables
0992:                            .getErrorMap()
0993:                            .putError(
0994:                                    KFSConstants.ACCOUNTING_LINE_ERRORS,
0995:                                    KFSKeyConstants.ERROR_DOCUMENT_BA_CURRENT_AMOUNTS_BALANCED);
0996:                    balanced = false;
0997:                }
0998:
0999:                return balanced;
1000:            }
1001:
1002:            /**
1003:             * Builds a map used for balancing current adjustment amounts. The map contains income chart and accounts contained on the
1004:             * document as the keys, and transfer amounts as the values. The transfer amount is calculated from (curr_frm_inc -
1005:             * curr_frm_exp) - (curr_to_inc - curr_to_exp)
1006:             * 
1007:             * @param baDocument budget ajdustment document
1008:             * @return Map used to balance current amounts
1009:             */
1010:            public Map buildIncomeStreamBalanceMap(
1011:                    BudgetAdjustmentDocument baDocument) {
1012:                Map incomeStreamBalance = new HashMap();
1013:
1014:                List accountingLines = new ArrayList();
1015:                accountingLines.addAll(baDocument.getSourceAccountingLines());
1016:                accountingLines.addAll(baDocument.getTargetAccountingLines());
1017:                for (Iterator iter = accountingLines.iterator(); iter.hasNext();) {
1018:                    BudgetAdjustmentAccountingLine budgetAccountingLine = (BudgetAdjustmentAccountingLine) iter
1019:                            .next();
1020:                    String incomeStreamKey = budgetAccountingLine.getAccount()
1021:                            .getIncomeStreamFinancialCoaCode()
1022:                            + INCOME_STREAM_CHART_ACCOUNT_DELIMITER
1023:                            + budgetAccountingLine.getAccount()
1024:                                    .getIncomeStreamAccountNumber();
1025:
1026:                    KualiDecimal incomeStreamAmount = new KualiDecimal(0);
1027:                    if (incomeStreamBalance.containsKey(incomeStreamKey)) {
1028:                        incomeStreamAmount = (KualiDecimal) incomeStreamBalance
1029:                                .get(incomeStreamKey);
1030:                    }
1031:
1032:                    // amounts need reversed for source expense lines and target income lines
1033:                    if ((budgetAccountingLine instanceof  BudgetAdjustmentSourceAccountingLine && super 
1034:                            .isExpense((AccountingLine) budgetAccountingLine))
1035:                            || (budgetAccountingLine instanceof  BudgetAdjustmentTargetAccountingLine && super 
1036:                                    .isIncome((AccountingLine) budgetAccountingLine))) {
1037:                        incomeStreamAmount = incomeStreamAmount
1038:                                .subtract(budgetAccountingLine
1039:                                        .getCurrentBudgetAdjustmentAmount());
1040:                    } else {
1041:                        incomeStreamAmount = incomeStreamAmount
1042:                                .add(budgetAccountingLine
1043:                                        .getCurrentBudgetAdjustmentAmount());
1044:                    }
1045:
1046:                    // place record in balance map
1047:                    incomeStreamBalance
1048:                            .put(incomeStreamKey, incomeStreamAmount);
1049:                }
1050:
1051:                return incomeStreamBalance;
1052:            }
1053:
1054:            /**
1055:             * Helper method to check if an amount is negative and add an error if not.
1056:             * 
1057:             * @param amount to check
1058:             * @param propertyName to add error under
1059:             * @param label for error
1060:             * @return boolean indicating if the value has the requested sign
1061:             */
1062:            private boolean checkAmountSign(KualiDecimal amount,
1063:                    String propertyName, String label) {
1064:                boolean correctSign = true;
1065:
1066:                if (amount.isNegative()) {
1067:                    GlobalVariables.getErrorMap().putError(propertyName,
1068:                            KFSKeyConstants.ERROR_BA_AMOUNT_NEGATIVE, label);
1069:                    correctSign = false;
1070:                }
1071:
1072:                return correctSign;
1073:            }
1074:
1075:            /**
1076:             * BA document does not have to have source accounting lines. In the case of setting up a budget for a new account, only targets
1077:             * line (increase section) are setup.
1078:             * 
1079:             * @param financialDocument submitted financial document
1080:             * @return true if both source and target lines are NOT empty
1081:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isSourceAccountingLinesRequiredNumberForRoutingMet(org.kuali.core.document.FinancialDocument)
1082:             */
1083:            @Override
1084:            protected boolean isSourceAccountingLinesRequiredNumberForRoutingMet(
1085:                    AccountingDocument financialDocument) {
1086:                // check that both source and target are not empty, in which case is an error
1087:                if (financialDocument.getSourceAccountingLines().isEmpty()
1088:                        && financialDocument.getTargetAccountingLines()
1089:                                .isEmpty()) {
1090:                    GlobalVariables.getErrorMap().putError(
1091:                            KFSConstants.ACCOUNTING_LINE_ERRORS,
1092:                            KFSKeyConstants.ERROR_DOCUMENT_NO_ACCOUNTING_LINES);
1093:                    return false;
1094:                }
1095:
1096:                return true;
1097:            }
1098:
1099:            /**
1100:             * BA document does not have to have source accounting lines. In the case of closing out an account, only source lines (decrease
1101:             * section) are setup.
1102:             * 
1103:             * @param financialDocument submitted financial document
1104:             * @return true
1105:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isTargetAccountingLinesRequiredNumberForRoutingMet(org.kuali.core.document.FinancialDocument)
1106:             */
1107:            @Override
1108:            protected boolean isTargetAccountingLinesRequiredNumberForRoutingMet(
1109:                    AccountingDocument FinancialDocument) {
1110:                return true;
1111:            }
1112:
1113:            /**
1114:             * Returns true if accounting line is debit
1115:             * 
1116:             * @param financialDocument submitted financial document
1117:             * @param accountingLine accouting line being evaulated as a debit or not
1118:             * @see org.kuali.core.rule.AccountingLineRule#isDebit(org.kuali.core.document.FinancialDocument,
1119:             *      org.kuali.core.bo.AccountingLine)
1120:             */
1121:            public boolean isDebit(AccountingDocument financialDocument,
1122:                    AccountingLine accountingLine) {
1123:                try {
1124:                    return IsDebitUtils.isDebitConsideringType(this ,
1125:                            financialDocument, accountingLine);
1126:                } catch (IllegalStateException e) {
1127:                    // for all accounting lines except the transfer lines, the line amount will be 0 and this exception will be thrown
1128:                    return false;
1129:                }
1130:            }
1131:
1132:            /**
1133:             * Returns true if account line totals remains unchanged from what was entered and what was persisted before
1134:             * 
1135:             * @param financialDocument submitted accounting document
1136:             * @return true if account line totals remains unchanged fromw what was entered and what was persisted before
1137:             * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isAccountingLineTotalsUnchanged(org.kuali.core.document.FinancialDocument)
1138:             */
1139:            @Override
1140:            protected boolean isAccountingLineTotalsUnchanged(
1141:                    AccountingDocument financialDocument) {
1142:                boolean isUnchanged = true;
1143:
1144:                BudgetAdjustmentDocument persistedDocument = (BudgetAdjustmentDocument) retrievePersistedDocument(financialDocument);
1145:                BudgetAdjustmentDocument currentDocument = (BudgetAdjustmentDocument) financialDocument;
1146:
1147:                if (persistedDocument == null) {
1148:                    handleNonExistentDocumentWhenApproving(financialDocument);
1149:                } else {
1150:                    // retrieve the persisted totals
1151:                    KualiDecimal persistedSourceCurrentBudgetTotal = persistedDocument
1152:                            .getSourceCurrentBudgetTotal();
1153:                    KualiInteger persistedSourceBaseBudgetTotal = persistedDocument
1154:                            .getSourceBaseBudgetTotal();
1155:                    KualiDecimal persistedTargetCurrentBudgetTotal = persistedDocument
1156:                            .getTargetCurrentBudgetTotal();
1157:                    KualiInteger persistedTargetBaseBudgetTotal = persistedDocument
1158:                            .getTargetBaseBudgetTotal();
1159:
1160:                    // retrieve the updated totals
1161:                    KualiDecimal currentSourceCurrentBudgetTotal = currentDocument
1162:                            .getSourceCurrentBudgetTotal();
1163:                    KualiInteger currentSourceBaseBudgetTotal = currentDocument
1164:                            .getSourceBaseBudgetTotal();
1165:                    KualiDecimal currentTargetCurrentBudgetTotal = currentDocument
1166:                            .getTargetCurrentBudgetTotal();
1167:                    KualiInteger currentTargetBaseBudgetTotal = currentDocument
1168:                            .getTargetBaseBudgetTotal();
1169:
1170:                    // make sure that totals have remained unchanged, if not, recognize that, and
1171:                    // generate appropriate error messages
1172:                    if (persistedSourceCurrentBudgetTotal
1173:                            .compareTo(currentSourceCurrentBudgetTotal) != 0) {
1174:                        isUnchanged = false;
1175:                        buildTotalChangeErrorMessage(
1176:                                SOURCE_ACCOUNTING_LINE_ERRORS,
1177:                                "source current budget",
1178:                                persistedSourceCurrentBudgetTotal,
1179:                                currentSourceCurrentBudgetTotal);
1180:                    }
1181:                    if (persistedSourceBaseBudgetTotal
1182:                            .compareTo(currentSourceBaseBudgetTotal) != 0) {
1183:                        isUnchanged = false;
1184:                        buildTotalChangeErrorMessage(
1185:                                SOURCE_ACCOUNTING_LINE_ERRORS,
1186:                                "source base budget",
1187:                                persistedSourceBaseBudgetTotal
1188:                                        .kualiDecimalValue(),
1189:                                currentSourceBaseBudgetTotal
1190:                                        .kualiDecimalValue());
1191:                    }
1192:                    if (persistedTargetCurrentBudgetTotal
1193:                            .compareTo(currentTargetCurrentBudgetTotal) != 0) {
1194:                        isUnchanged = false;
1195:                        buildTotalChangeErrorMessage(
1196:                                TARGET_ACCOUNTING_LINE_ERRORS,
1197:                                "target current budget",
1198:                                persistedTargetCurrentBudgetTotal,
1199:                                currentTargetCurrentBudgetTotal);
1200:                    }
1201:                    if (persistedTargetBaseBudgetTotal
1202:                            .compareTo(currentTargetBaseBudgetTotal) != 0) {
1203:                        isUnchanged = false;
1204:                        buildTotalChangeErrorMessage(
1205:                                TARGET_ACCOUNTING_LINE_ERRORS,
1206:                                "target base budget",
1207:                                persistedTargetBaseBudgetTotal
1208:                                        .kualiDecimalValue(),
1209:                                currentTargetBaseBudgetTotal
1210:                                        .kualiDecimalValue());
1211:                    }
1212:                }
1213:
1214:                return isUnchanged;
1215:            }
1216:
1217:            /**
1218:             * Builds the error message for when totals have changed.
1219:             * 
1220:             * @param propertyName name of property
1221:             * @param sectionTitle title of section
1222:             * @param persistedSourceLineTotal previously persisted source line total
1223:             * @param currentSourceLineTotal current entered source line total
1224:             */
1225:            private void buildTotalChangeErrorMessage(String propertyName,
1226:                    String sectionTitle, KualiDecimal persistedSourceLineTotal,
1227:                    KualiDecimal currentSourceLineTotal) {
1228:                String persistedTotal = (String) new CurrencyFormatter()
1229:                        .format(persistedSourceLineTotal);
1230:                String currentTotal = (String) new CurrencyFormatter()
1231:                        .format(currentSourceLineTotal);
1232:
1233:                GlobalVariables.getErrorMap().putError(
1234:                        propertyName,
1235:                        ERROR_DOCUMENT_ACCOUNTING_LINE_TOTAL_CHANGED,
1236:                        new String[] { sectionTitle, persistedTotal,
1237:                                currentTotal });
1238:            }
1239:
1240:            /**
1241:             * Returns the document type code for the Transfer of Funds document
1242:             * 
1243:             * @return the document type name to be used for the income stream transfer glpe
1244:             */
1245:            protected String getTransferDocumentType() {
1246:                return TRANSFER_OF_FUNDS_DOC_TYPE_CODE;
1247:            }
1248:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.