Source Code Cross Referenced for KualiAccountingDocumentActionBase.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » kfs » web » struts » action » 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.kfs.web.struts.action 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 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.kfs.web.struts.action;
0017:
0018:        import static org.kuali.kfs.KFSKeyConstants.ERROR_DOCUMENT_ACCOUNTING_LINE_SALES_TAX_INVALID_ACCOUNT;
0019:        import static org.kuali.kfs.KFSKeyConstants.ERROR_DOCUMENT_ACCOUNTING_LINE_SALES_TAX_REQUIRED;
0020:        import static org.kuali.kfs.KFSKeyConstants.ERROR_REQUIRED;
0021:
0022:        import java.io.FileNotFoundException;
0023:        import java.io.IOException;
0024:        import java.util.Arrays;
0025:        import java.util.HashMap;
0026:        import java.util.HashSet;
0027:        import java.util.Iterator;
0028:        import java.util.List;
0029:        import java.util.Map;
0030:        import java.util.Properties;
0031:        import java.util.Set;
0032:
0033:        import javax.servlet.http.HttpServletRequest;
0034:        import javax.servlet.http.HttpServletResponse;
0035:
0036:        import org.apache.commons.lang.StringUtils;
0037:        import org.apache.struts.action.ActionForm;
0038:        import org.apache.struts.action.ActionForward;
0039:        import org.apache.struts.action.ActionMapping;
0040:        import org.apache.struts.upload.FormFile;
0041:        import org.kuali.core.document.AmountTotaling;
0042:        import org.kuali.core.service.BusinessObjectService;
0043:        import org.kuali.core.service.DictionaryValidationService;
0044:        import org.kuali.core.service.DocumentTypeService;
0045:        import org.kuali.core.service.KualiRuleService;
0046:        import org.kuali.core.service.PersistenceService;
0047:        import org.kuali.core.util.GlobalVariables;
0048:        import org.kuali.core.util.ObjectUtils;
0049:        import org.kuali.core.util.Timer;
0050:        import org.kuali.core.util.UrlFactory;
0051:        import org.kuali.core.web.struts.action.KualiTransactionalDocumentActionBase;
0052:        import org.kuali.core.web.struts.form.KualiDocumentFormBase;
0053:        import org.kuali.core.workflow.service.WorkflowDocumentService;
0054:        import org.kuali.kfs.KFSConstants;
0055:        import org.kuali.kfs.KFSKeyConstants;
0056:        import org.kuali.kfs.bo.AccountingLine;
0057:        import org.kuali.kfs.bo.AccountingLineOverride;
0058:        import org.kuali.kfs.bo.AccountingLineParser;
0059:        import org.kuali.kfs.bo.SourceAccountingLine;
0060:        import org.kuali.kfs.bo.TargetAccountingLine;
0061:        import org.kuali.kfs.context.SpringContext;
0062:        import org.kuali.kfs.document.AccountingDocument;
0063:        import org.kuali.kfs.exceptions.AccountingLineParserException;
0064:        import org.kuali.kfs.rule.event.AddAccountingLineEvent;
0065:        import org.kuali.kfs.rule.event.DeleteAccountingLineEvent;
0066:        import org.kuali.kfs.rule.event.UpdateAccountingLineEvent;
0067:        import org.kuali.kfs.rules.AccountingDocumentRuleBaseConstants.APPLICATION_PARAMETER;
0068:        import org.kuali.kfs.service.ParameterEvaluator;
0069:        import org.kuali.kfs.service.ParameterService;
0070:        import org.kuali.kfs.service.impl.ParameterConstants;
0071:        import org.kuali.kfs.web.struts.form.KualiAccountingDocumentFormBase;
0072:        import org.kuali.kfs.web.ui.AccountingLineDecorator;
0073:        import org.kuali.module.financial.bo.SalesTax;
0074:
0075:        import edu.iu.uis.eden.exception.WorkflowException;
0076:
0077:        /**
0078:         * This class handles UI actions for all shared methods of financial documents.
0079:         */
0080:        public class KualiAccountingDocumentActionBase extends
0081:                KualiTransactionalDocumentActionBase {
0082:            private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
0083:                    .getLogger(KualiAccountingDocumentActionBase.class);
0084:
0085:            /**
0086:             * Adds check for accountingLine updates, generates and dispatches any events caused by such updates
0087:             * 
0088:             * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm,
0089:             *      javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
0090:             */
0091:            @Override
0092:            public ActionForward execute(ActionMapping mapping,
0093:                    ActionForm form, HttpServletRequest request,
0094:                    HttpServletResponse response) throws Exception {
0095:                Timer t0 = new Timer("KualiFinancialDocumentFormBase.execute");
0096:                KualiAccountingDocumentFormBase transForm = (KualiAccountingDocumentFormBase) form;
0097:
0098:                // handle changes to accountingLines
0099:                if (transForm.hasDocumentId()) {
0100:                    AccountingDocument financialDocument = (AccountingDocument) transForm
0101:                            .getDocument();
0102:
0103:                    processAccountingLines(financialDocument, transForm,
0104:                            KFSConstants.SOURCE);
0105:                    processAccountingLines(financialDocument, transForm,
0106:                            KFSConstants.TARGET);
0107:                }
0108:
0109:                // This is after a potential handleUpdate(), to display automatically cleared overrides following a route or save.
0110:                processAccountingLineOverrides(transForm);
0111:
0112:                // this refershes if the accounting lines within the form are editable or not
0113:                if (ObjectUtils.isNotNull(transForm.getDocument())
0114:                        && ObjectUtils.isNotNull(transForm.getDocument()
0115:                                .getDocumentHeader())
0116:                        && ObjectUtils.isNotNull(transForm.getDocument()
0117:                                .getDocumentNumber())
0118:                        && SpringContext.getBean(WorkflowDocumentService.class)
0119:                                .workflowDocumentExists(
0120:                                        transForm.getDocument()
0121:                                                .getDocumentNumber())) {
0122:                    transForm.refreshEditableAccounts();
0123:                }
0124:
0125:                // proceed as usual
0126:                ActionForward result = super .execute(mapping, form, request,
0127:                        response);
0128:                t0.log();
0129:                return result;
0130:            }
0131:
0132:            /**
0133:             * All document-creation gets routed through here
0134:             * 
0135:             * @see org.kuali.core.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.core.web.struts.form.KualiDocumentFormBase)
0136:             */
0137:            @Override
0138:            protected void createDocument(
0139:                    KualiDocumentFormBase kualiDocumentFormBase)
0140:                    throws WorkflowException {
0141:                super .createDocument(kualiDocumentFormBase);
0142:
0143:                KualiAccountingDocumentFormBase tform = (KualiAccountingDocumentFormBase) kualiDocumentFormBase;
0144:
0145:                // reset baseline accountingLine lists
0146:                tform.getBaselineSourceAccountingLines().clear();
0147:                tform.getBaselineTargetAccountingLines().clear();
0148:
0149:                // reset decorator lists
0150:                tform.getSourceLineDecorators().clear();
0151:                tform.getTargetLineDecorators().clear();
0152:            }
0153:
0154:            /**
0155:             * All document-load operations get routed through here
0156:             * 
0157:             * @see org.kuali.core.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.core.web.struts.form.KualiDocumentFormBase)
0158:             */
0159:            @Override
0160:            protected void loadDocument(
0161:                    KualiDocumentFormBase kualiDocumentFormBase)
0162:                    throws WorkflowException {
0163:                super .loadDocument(kualiDocumentFormBase);
0164:
0165:                KualiAccountingDocumentFormBase tform = (KualiAccountingDocumentFormBase) kualiDocumentFormBase;
0166:
0167:                // populate baseline accountingLine lists
0168:                List baselineSourceLines = tform
0169:                        .getBaselineSourceAccountingLines();
0170:                baselineSourceLines.clear();
0171:                baselineSourceLines.addAll(tform.getFinancialDocument()
0172:                        .getSourceAccountingLines());
0173:                // sales tax handling
0174:                handleSalesTaxRequiredAllLines(kualiDocumentFormBase,
0175:                        baselineSourceLines);
0176:
0177:                List baselineTargetLines = tform
0178:                        .getBaselineTargetAccountingLines();
0179:                baselineTargetLines.clear();
0180:                baselineTargetLines.addAll(tform.getFinancialDocument()
0181:                        .getTargetAccountingLines());
0182:                // sales tax handling
0183:                handleSalesTaxRequiredAllLines(kualiDocumentFormBase,
0184:                        baselineTargetLines);
0185:
0186:                // populate decorator lists
0187:                tform.resetSourceLineDecorators(baselineSourceLines.size());
0188:                tform.resetTargetLineDecorators(baselineTargetLines.size());
0189:
0190:                // clear out the new accounting line holders
0191:                tform.setNewSourceLine(null);
0192:                tform.setNewTargetLine(null);
0193:
0194:                processAccountingLineOverrides(tform);
0195:            }
0196:
0197:            /**
0198:             * Needed to override this to keep from losing Sales Tax information
0199:             * 
0200:             * @see org.kuali.core.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping,
0201:             *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
0202:             */
0203:            @Override
0204:            public ActionForward refresh(ActionMapping mapping,
0205:                    ActionForm form, HttpServletRequest request,
0206:                    HttpServletResponse response) throws Exception {
0207:                super .refresh(mapping, form, request, response);
0208:                refreshSalesTaxInfo(form);
0209:
0210:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0211:            }
0212:
0213:            /**
0214:             * Needed to override this to keep from losing Sales Tax information
0215:             * 
0216:             * @see org.kuali.core.web.struts.action.KualiAction#toggleTab(org.apache.struts.action.ActionMapping,
0217:             *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
0218:             */
0219:            @Override
0220:            public ActionForward toggleTab(ActionMapping mapping,
0221:                    ActionForm form, HttpServletRequest request,
0222:                    HttpServletResponse response) throws Exception {
0223:                super .toggleTab(mapping, form, request, response);
0224:                refreshSalesTaxInfo(form);
0225:
0226:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0227:            }
0228:
0229:            // Set of actions for which updateEvents should be generated
0230:            protected static final Set UPDATE_EVENT_ACTIONS;
0231:            static {
0232:                String[] updateEventActions = { KFSConstants.SAVE_METHOD,
0233:                        KFSConstants.ROUTE_METHOD, KFSConstants.APPROVE_METHOD,
0234:                        KFSConstants.BLANKET_APPROVE_METHOD };
0235:                UPDATE_EVENT_ACTIONS = new HashSet();
0236:                for (int i = 0; i < updateEventActions.length; ++i) {
0237:                    UPDATE_EVENT_ACTIONS.add(updateEventActions[i]);
0238:                }
0239:            }
0240:
0241:            /**
0242:             * @param transForm
0243:             */
0244:            protected void processAccountingLineOverrides(
0245:                    KualiAccountingDocumentFormBase transForm) {
0246:                processAccountingLineOverrides(transForm.getNewSourceLine());
0247:                processAccountingLineOverrides(transForm.getNewTargetLine());
0248:                if (transForm.hasDocumentId()) {
0249:                    AccountingDocument financialDocument = (AccountingDocument) transForm
0250:                            .getDocument();
0251:
0252:                    processAccountingLineOverrides(financialDocument
0253:                            .getSourceAccountingLines());
0254:                    processAccountingLineOverrides(financialDocument
0255:                            .getTargetAccountingLines());
0256:                }
0257:            }
0258:
0259:            /**
0260:             * @param line
0261:             */
0262:            protected void processAccountingLineOverrides(AccountingLine line) {
0263:                processAccountingLineOverrides(Arrays
0264:                        .asList(new AccountingLine[] { line }));
0265:            }
0266:
0267:            /**
0268:             * @param accountingLines
0269:             */
0270:            protected void processAccountingLineOverrides(List accountingLines) {
0271:                if (!accountingLines.isEmpty()) {
0272:                    SpringContext.getBean(PersistenceService.class)
0273:                            .retrieveReferenceObjects(accountingLines,
0274:                                    AccountingLineOverride.REFRESH_FIELDS);
0275:
0276:                    for (Iterator i = accountingLines.iterator(); i.hasNext();) {
0277:                        AccountingLine line = (AccountingLine) i.next();
0278:                        AccountingLineOverride.processForOutput(line);
0279:                    }
0280:                }
0281:            }
0282:
0283:            /**
0284:             * @param transDoc
0285:             * @param transForm
0286:             * @param lineSet
0287:             */
0288:            private void processAccountingLines(AccountingDocument transDoc,
0289:                    KualiAccountingDocumentFormBase transForm, String lineSet) {
0290:                // figure out which set of lines we're looking at
0291:                List baseLines;
0292:                List formLines;
0293:                List<AccountingLineDecorator> decorators;
0294:                String pathPrefix;
0295:                boolean source;
0296:                if (lineSet.equals(KFSConstants.SOURCE)) {
0297:                    baseLines = transForm.getBaselineSourceAccountingLines();
0298:                    formLines = transDoc.getSourceAccountingLines();
0299:                    decorators = transForm.getSourceLineDecorators(formLines
0300:                            .size());
0301:                    pathPrefix = KFSConstants.DOCUMENT_PROPERTY_NAME
0302:                            + "."
0303:                            + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME;
0304:                    source = true;
0305:                } else {
0306:                    baseLines = transForm.getBaselineTargetAccountingLines();
0307:                    formLines = transDoc.getTargetAccountingLines();
0308:                    decorators = transForm.getTargetLineDecorators(formLines
0309:                            .size());
0310:                    pathPrefix = KFSConstants.DOCUMENT_PROPERTY_NAME
0311:                            + "."
0312:                            + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME;
0313:                    source = false;
0314:                }
0315:
0316:                Map baseLineMap = new HashMap();
0317:                for (Iterator i = baseLines.iterator(); i.hasNext();) {
0318:                    AccountingLine baseLine = (AccountingLine) i.next();
0319:                    baseLineMap.put(baseLine.getSequenceNumber(), baseLine);
0320:                }
0321:
0322:                // find and process corresponding form and baselines
0323:                int index = 0;
0324:                for (Iterator i = formLines.iterator(); i.hasNext(); index++) {
0325:                    AccountingLine formLine = (AccountingLine) i.next();
0326:                    AccountingLine baseLine = (AccountingLine) baseLineMap
0327:                            .get(formLine.getSequenceNumber());
0328:                    AccountingLineDecorator decorator = decorators.get(index);
0329:
0330:                    // always update decorator
0331:                    handleDecorator(formLine, baseLine, decorator);
0332:
0333:                    // update sales tax required attribute for view
0334:                    // handleSalesTaxRequired(transDoc, formLine, source, false, index);
0335:                    checkSalesTax(transDoc, formLine, source, false, index);
0336:                    if (baseLine != null) {
0337:                        handleSalesTaxRequired(transDoc, baseLine, source,
0338:                                false, index);
0339:                        // checkSalesTax(transDoc, baseLine, source, false, index);
0340:                    }
0341:
0342:                    // only generate update events for specific action methods
0343:                    String methodToCall = transForm.getMethodToCall();
0344:                    if (UPDATE_EVENT_ACTIONS.contains(methodToCall)) {
0345:                        handleUpdate(transDoc, pathPrefix + "[" + index + "]",
0346:                                formLine, baseLine);
0347:                    }
0348:                }
0349:            }
0350:
0351:            /**
0352:             * @param formLine
0353:             * @param baseLine
0354:             * @param decorator
0355:             */
0356:            private void handleDecorator(AccountingLine formLine,
0357:                    AccountingLine baseLine, AccountingLineDecorator decorator) {
0358:                // if line is new, or line hasn't changed, make non-revertible;
0359:                // otherwise, revertible
0360:                if ((baseLine == null) || formLine.isLike(baseLine)) {
0361:                    decorator.setRevertible(false);
0362:                } else {
0363:                    decorator.setRevertible(true);
0364:                }
0365:            }
0366:
0367:            /**
0368:             * @param transDoc
0369:             * @param errorPathPrefix
0370:             * @param formLine
0371:             * @param baseLine
0372:             */
0373:            private void handleUpdate(AccountingDocument transDoc,
0374:                    String errorPathPrefix, AccountingLine formLine,
0375:                    AccountingLine baseLine) {
0376:                if ((baseLine != null) && !formLine.isLike(baseLine)) {
0377:                    // reluctantly refresh BOs for clearOverridesThatBecameUnneeded()
0378:                    formLine.refreshNonUpdateableReferences();
0379:                    clearOverridesThatBecameUnneeded(formLine);
0380:                    // the rule itself is responsible for adding error messages to the global ErrorMap
0381:                    SpringContext.getBean(KualiRuleService.class).applyRules(
0382:                            new UpdateAccountingLineEvent(errorPathPrefix,
0383:                                    transDoc, baseLine, formLine));
0384:                }
0385:            }
0386:
0387:            /**
0388:             * Automatically clears any overrides that have become unneeded. This is for accounting lines that were changed right before
0389:             * final actions like route. Normally the unneeded overrides are cleared in accountingLineOverrideField.tag instead, but that
0390:             * requires another form submit. This method shouldn't be called on lines that haven't changed, to avoid automatically changing
0391:             * read-only lines. This cannot be done in the Rule because Rules cannot change the AccountingLines; they only get a deepCopy.
0392:             * 
0393:             * @param formLine
0394:             */
0395:            protected void clearOverridesThatBecameUnneeded(
0396:                    AccountingLine formLine) {
0397:                AccountingLineOverride currentlyNeeded = AccountingLineOverride
0398:                        .determineNeededOverrides(formLine);
0399:                AccountingLineOverride currentOverride = AccountingLineOverride
0400:                        .valueOf(formLine.getOverrideCode());
0401:                if (!currentOverride.isValidMask(currentlyNeeded)) {
0402:                    // todo: handle unsupported combinations of overrides (not a problem until we allow certain multiple overrides)
0403:                }
0404:                formLine.setOverrideCode(currentOverride.mask(currentlyNeeded)
0405:                        .getCode());
0406:            }
0407:
0408:            /**
0409:             * This method will revert a TargetAccountingLine by overwriting its current values with the values in the corresponding
0410:             * baseline accountingLine. This assumes that the user presses the revert button for a specific accounting line on the document
0411:             * and that the document is represented by a FinancialDocumentFormBase.
0412:             * 
0413:             * @param mapping
0414:             * @param form
0415:             * @param request
0416:             * @param response
0417:             * @return ActionForward
0418:             * @throws Exception
0419:             */
0420:            public ActionForward revertTargetLine(ActionMapping mapping,
0421:                    ActionForm form, HttpServletRequest request,
0422:                    HttpServletResponse response) throws Exception {
0423:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0424:                AccountingDocument financialDocument = (AccountingDocument) financialDocumentForm
0425:                        .getDocument();
0426:
0427:                int revertIndex = getSelectedLine(request);
0428:
0429:                TargetAccountingLine originalLine = financialDocumentForm
0430:                        .getBaselineTargetAccountingLine(revertIndex);
0431:                TargetAccountingLine brokenLine = financialDocument
0432:                        .getTargetAccountingLine(revertIndex);
0433:
0434:                if (revertAccountingLine(financialDocumentForm, revertIndex,
0435:                        originalLine, brokenLine)) {
0436:                    financialDocumentForm.getTargetLineDecorator(revertIndex)
0437:                            .setRevertible(false);
0438:                }
0439:
0440:                // no business rules to check, no events to create
0441:
0442:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0443:            }
0444:
0445:            /**
0446:             * This method will revert a SourceAccountingLine by overwriting its current values with the values in the corresponding
0447:             * baseline accountingLine. This assumes that the user presses the revert button for a specific accounting line on the document
0448:             * and that the document is represented by a FinancialDocumentFormBase.
0449:             * 
0450:             * @param mapping
0451:             * @param form
0452:             * @param request
0453:             * @param response
0454:             * @return ActionForward
0455:             * @throws Exception
0456:             */
0457:            public ActionForward revertSourceLine(ActionMapping mapping,
0458:                    ActionForm form, HttpServletRequest request,
0459:                    HttpServletResponse response) throws Exception {
0460:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0461:                AccountingDocument financialDocument = (AccountingDocument) financialDocumentForm
0462:                        .getDocument();
0463:
0464:                int revertIndex = getSelectedLine(request);
0465:
0466:                SourceAccountingLine originalLine = financialDocumentForm
0467:                        .getBaselineSourceAccountingLine(revertIndex);
0468:                SourceAccountingLine brokenLine = financialDocument
0469:                        .getSourceAccountingLine(revertIndex);
0470:
0471:                if (revertAccountingLine(financialDocumentForm, revertIndex,
0472:                        originalLine, brokenLine)) {
0473:                    financialDocumentForm.getSourceLineDecorator(revertIndex)
0474:                            .setRevertible(false);
0475:                }
0476:
0477:                // no business rules to check, no events to create
0478:
0479:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0480:            }
0481:
0482:            /**
0483:             * Overwrites field values in the given brokenLine with those in the given originalLine, if the two accountingLines differ.
0484:             * 
0485:             * @param transForm
0486:             * @param revertIndex
0487:             * @param originalLine
0488:             * @param newerLine
0489:             * @return true if and only if the brokenLine was actually changed
0490:             */
0491:            protected boolean revertAccountingLine(
0492:                    KualiAccountingDocumentFormBase transForm, int revertIndex,
0493:                    AccountingLine originalLine, AccountingLine newerLine) {
0494:                boolean reverted = false;
0495:
0496:                SpringContext.getBean(PersistenceService.class)
0497:                        .refreshAllNonUpdatingReferences(originalLine);
0498:
0499:                // *always* revert (so that if someone manually changes the line to its original values, then hits revert, they won't get an
0500:                // error message saying "couldn't revert")
0501:                newerLine.copyFrom(originalLine);
0502:                if (isSalesTaxRequired((AccountingDocument) transForm
0503:                        .getDocument(), newerLine)) {
0504:                    newerLine.setSalesTaxRequired(true);
0505:                }
0506:                reverted = true;
0507:                GlobalVariables.getMessageList().add(
0508:                        KFSKeyConstants.MESSAGE_REVERT_SUCCESSFUL);
0509:
0510:                return reverted;
0511:            }
0512:
0513:            /**
0514:             * This method will remove a TargetAccountingLine from a FinancialDocument. This assumes that the user presses the delete button
0515:             * for a specific accounting line on the document and that the document is represented by a FinancialDocumentFormBase.
0516:             * 
0517:             * @param mapping
0518:             * @param form
0519:             * @param request
0520:             * @param response
0521:             * @return ActionForward
0522:             * @throws Exception
0523:             */
0524:            public ActionForward deleteTargetLine(ActionMapping mapping,
0525:                    ActionForm form, HttpServletRequest request,
0526:                    HttpServletResponse response) throws Exception {
0527:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0528:
0529:                boolean rulePassed = false;
0530:                int deleteIndex = getLineToDelete(request);
0531:                String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "."
0532:                        + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME
0533:                        + "[" + deleteIndex + "]";
0534:
0535:                // check business rule, if there is a baseline copy
0536:                // (accountingLines without baselines haven't been persisted yet, so they can safely be deleted)
0537:                if (financialDocumentForm
0538:                        .hasBaselineTargetAccountingLine(deleteIndex)) {
0539:                    TargetAccountingLine baseline = financialDocumentForm
0540:                            .getBaselineTargetAccountingLine(deleteIndex);
0541:                    SpringContext.getBean(PersistenceService.class)
0542:                            .refreshAllNonUpdatingReferences(baseline);
0543:
0544:                    rulePassed = SpringContext
0545:                            .getBean(KualiRuleService.class)
0546:                            .applyRules(
0547:                                    new DeleteAccountingLineEvent(
0548:                                            errorPath,
0549:                                            financialDocumentForm.getDocument(),
0550:                                            baseline, false));
0551:                } else {
0552:                    rulePassed = true;
0553:                }
0554:
0555:                // if the rule evaluation passed, let's delete it
0556:                if (rulePassed) {
0557:                    deleteAccountingLine(false, financialDocumentForm,
0558:                            deleteIndex);
0559:                } else {
0560:                    financialDocumentForm.getTargetLineDecorator(deleteIndex)
0561:                            .setRevertible(true);
0562:
0563:                    String[] errorParams = new String[] { "target",
0564:                            Integer.toString(deleteIndex + 1) };
0565:                    GlobalVariables
0566:                            .getErrorMap()
0567:                            .putError(
0568:                                    errorPath,
0569:                                    KFSKeyConstants.ERROR_ACCOUNTINGLINE_DELETERULE_INVALIDACCOUNT,
0570:                                    errorParams);
0571:                }
0572:
0573:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0574:            }
0575:
0576:            /**
0577:             * This method will remove a SourceAccountingLine from a FinancialDocument. This assumes that the user presses the delete button
0578:             * for a specific accounting line on the document and that the document is represented by a FinancialDocumentFormBase.
0579:             * 
0580:             * @param mapping
0581:             * @param form
0582:             * @param request
0583:             * @param response
0584:             * @return ActionForward
0585:             * @throws Exception
0586:             */
0587:            public ActionForward deleteSourceLine(ActionMapping mapping,
0588:                    ActionForm form, HttpServletRequest request,
0589:                    HttpServletResponse response) throws Exception {
0590:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0591:
0592:                boolean rulePassed = false;
0593:                int deleteIndex = getLineToDelete(request);
0594:                String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "."
0595:                        + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME
0596:                        + "[" + deleteIndex + "]";
0597:
0598:                // check business rule, if there is a baseline copy
0599:                // (accountingLines without baselines haven't been persisted yet, so they can safely be deleted)
0600:                if (financialDocumentForm
0601:                        .hasBaselineSourceAccountingLine(deleteIndex)) {
0602:                    SourceAccountingLine baseline = financialDocumentForm
0603:                            .getBaselineSourceAccountingLine(deleteIndex);
0604:                    SpringContext.getBean(PersistenceService.class)
0605:                            .refreshAllNonUpdatingReferences(baseline);
0606:
0607:                    rulePassed = SpringContext
0608:                            .getBean(KualiRuleService.class)
0609:                            .applyRules(
0610:                                    new DeleteAccountingLineEvent(
0611:                                            errorPath,
0612:                                            financialDocumentForm.getDocument(),
0613:                                            baseline, false));
0614:                } else {
0615:                    rulePassed = true;
0616:                }
0617:
0618:                // if the rule evaluation passed, let's delete it
0619:                if (rulePassed) {
0620:                    deleteAccountingLine(true, financialDocumentForm,
0621:                            deleteIndex);
0622:                } else {
0623:                    financialDocumentForm.getSourceLineDecorator(deleteIndex)
0624:                            .setRevertible(true);
0625:
0626:                    String[] errorParams = new String[] { "source",
0627:                            Integer.toString(deleteIndex + 1) };
0628:                    GlobalVariables
0629:                            .getErrorMap()
0630:                            .putError(
0631:                                    errorPath,
0632:                                    KFSKeyConstants.ERROR_ACCOUNTINGLINE_DELETERULE_INVALIDACCOUNT,
0633:                                    errorParams);
0634:                }
0635:
0636:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0637:            }
0638:
0639:            /**
0640:             * Deletes the source or target accountingLine with the given index from the given form. Assumes that the rule- and form-
0641:             * validation have already occurred.
0642:             * 
0643:             * @param isSource
0644:             * @param financialDocumentForm
0645:             * @param deleteIndex
0646:             */
0647:            protected void deleteAccountingLine(boolean isSource,
0648:                    KualiAccountingDocumentFormBase financialDocumentForm,
0649:                    int deleteIndex) {
0650:                if (isSource) {
0651:                    // remove from document
0652:                    financialDocumentForm.getFinancialDocument()
0653:                            .getSourceAccountingLines().remove(deleteIndex);
0654:
0655:                    // remove baseline duplicate and decorator
0656:                    if (deleteIndex < financialDocumentForm
0657:                            .getBaselineSourceAccountingLines().size()) {
0658:                        financialDocumentForm
0659:                                .getBaselineSourceAccountingLines().remove(
0660:                                        deleteIndex);
0661:                    }
0662:                    financialDocumentForm.getSourceLineDecorators().remove(
0663:                            deleteIndex);
0664:
0665:                    // update the doc total
0666:                    AccountingDocument tdoc = (AccountingDocument) financialDocumentForm
0667:                            .getDocument();
0668:                    if (tdoc instanceof  AmountTotaling)
0669:                        financialDocumentForm.getDocument().getDocumentHeader()
0670:                                .setFinancialDocumentTotalAmount(
0671:                                        ((AmountTotaling) tdoc)
0672:                                                .getTotalDollarAmount());
0673:                } else {
0674:                    // remove from document
0675:                    financialDocumentForm.getFinancialDocument()
0676:                            .getTargetAccountingLines().remove(deleteIndex);
0677:
0678:                    // remove baseline duplicate and decorator
0679:                    if (deleteIndex < financialDocumentForm
0680:                            .getBaselineTargetAccountingLines().size()) {
0681:                        financialDocumentForm
0682:                                .getBaselineTargetAccountingLines().remove(
0683:                                        deleteIndex);
0684:                    }
0685:                    financialDocumentForm.getTargetLineDecorators().remove(
0686:                            deleteIndex);
0687:                }
0688:            }
0689:
0690:            /**
0691:             * This action executes a call to upload CSV accounting line values as TargetAccountingLines for a given transactional document.
0692:             * The "uploadAccountingLines()" method handles the multi-part request.
0693:             * 
0694:             * @param mapping
0695:             * @param form
0696:             * @param request
0697:             * @param response
0698:             * @return ActionForward
0699:             * @throws Exception
0700:             */
0701:            public ActionForward uploadTargetLines(ActionMapping mapping,
0702:                    ActionForm form, HttpServletRequest request,
0703:                    HttpServletResponse response) throws Exception {
0704:
0705:                // call method that sourceform and destination list
0706:                uploadAccountingLines(false, form);
0707:
0708:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0709:            }
0710:
0711:            /**
0712:             * This action executes a call to upload CSV accounting line values as SourceAccountingLines for a given transactional document.
0713:             * The "uploadAccountingLines()" method handles the multi-part request.
0714:             * 
0715:             * @param mapping
0716:             * @param form
0717:             * @param request
0718:             * @param response
0719:             * @return ActionForward
0720:             * @throws FileNotFoundException
0721:             * @throws IOException
0722:             */
0723:            public ActionForward uploadSourceLines(ActionMapping mapping,
0724:                    ActionForm form, HttpServletRequest request,
0725:                    HttpServletResponse response) throws FileNotFoundException,
0726:                    IOException {
0727:                LOG.info("Uploading source accounting lines");
0728:                // call method that sourceform and destination list
0729:                uploadAccountingLines(true, form);
0730:
0731:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0732:            }
0733:
0734:            /**
0735:             * This method determines whether we are uploading source or target lines, and then calls uploadAccountingLines directly on the
0736:             * document object. This method handles retrieving the actual upload file as an input stream into the document.
0737:             * 
0738:             * @param isSource
0739:             * @param form
0740:             * @throws FileNotFoundException
0741:             * @throws IOException
0742:             */
0743:            protected void uploadAccountingLines(boolean isSource,
0744:                    ActionForm form) throws FileNotFoundException, IOException {
0745:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
0746:
0747:                List importedLines = null;
0748:
0749:                AccountingDocument financialDocument = tmpForm
0750:                        .getFinancialDocument();
0751:                AccountingLineParser accountingLineParser = financialDocument
0752:                        .getAccountingLineParser();
0753:
0754:                // import the lines
0755:                String errorPathPrefix = null;
0756:                try {
0757:                    if (isSource) {
0758:                        errorPathPrefix = KFSConstants.DOCUMENT_PROPERTY_NAME
0759:                                + "."
0760:                                + KFSConstants.SOURCE_ACCOUNTING_LINE_ERRORS;
0761:                        FormFile sourceFile = tmpForm.getSourceFile();
0762:                        checkUploadFile(sourceFile);
0763:                        importedLines = accountingLineParser
0764:                                .importSourceAccountingLines(sourceFile
0765:                                        .getFileName(), sourceFile
0766:                                        .getInputStream(), financialDocument);
0767:                    } else {
0768:                        errorPathPrefix = KFSConstants.DOCUMENT_PROPERTY_NAME
0769:                                + "."
0770:                                + KFSConstants.TARGET_ACCOUNTING_LINE_ERRORS;
0771:                        FormFile targetFile = tmpForm.getTargetFile();
0772:                        checkUploadFile(targetFile);
0773:                        importedLines = accountingLineParser
0774:                                .importTargetAccountingLines(targetFile
0775:                                        .getFileName(), targetFile
0776:                                        .getInputStream(), financialDocument);
0777:                    }
0778:                } catch (AccountingLineParserException e) {
0779:                    GlobalVariables.getErrorMap().putError(errorPathPrefix,
0780:                            e.getErrorKey(), e.getErrorParameters());
0781:                }
0782:
0783:                // add line to list for those lines which were successfully imported
0784:                if (importedLines != null) {
0785:                    for (Iterator i = importedLines.iterator(); i.hasNext();) {
0786:                        AccountingLine importedLine = (AccountingLine) i.next();
0787:                        insertAccountingLine(isSource, tmpForm, importedLine);
0788:                    }
0789:                }
0790:            }
0791:
0792:            private void checkUploadFile(FormFile file) {
0793:                if (file == null) {
0794:                    throw new AccountingLineParserException(
0795:                            "invalid (null) upload file",
0796:                            KFSKeyConstants.ERROR_UPLOADFILE_NULL);
0797:                }
0798:            }
0799:
0800:            /**
0801:             * This method will add a TargetAccountingLine to a FinancialDocument. This assumes that the user presses the add button for a
0802:             * specific accounting line on the document and that the document is represented by a FinancialDocumentFormBase. It first
0803:             * validates the line for data integrity and then checks appropriate business rules.
0804:             * 
0805:             * @param mapping
0806:             * @param form
0807:             * @param request
0808:             * @param response
0809:             * @return ActionForward
0810:             * @throws Exception
0811:             */
0812:            public ActionForward insertTargetLine(ActionMapping mapping,
0813:                    ActionForm form, HttpServletRequest request,
0814:                    HttpServletResponse response) throws Exception {
0815:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0816:
0817:                TargetAccountingLine line = financialDocumentForm
0818:                        .getNewTargetLine();
0819:                boolean rulePassed = true;
0820:                // before we check the regular rules we need to check the sales tax rules
0821:                // TODO: Refactor rules so we no longer have to call this before a copy of the
0822:                // accountingLine
0823:                rulePassed &= checkSalesTax(
0824:                        (AccountingDocument) financialDocumentForm
0825:                                .getDocument(), line, false, true, 0);
0826:
0827:                // check any business rules
0828:                rulePassed &= SpringContext
0829:                        .getBean(KualiRuleService.class)
0830:                        .applyRules(
0831:                                new AddAccountingLineEvent(
0832:                                        KFSConstants.NEW_TARGET_ACCT_LINE_PROPERTY_NAME,
0833:                                        financialDocumentForm.getDocument(),
0834:                                        line));
0835:
0836:                // if the rule evaluation passed, let's add it
0837:                if (rulePassed) {
0838:                    // add accountingLine
0839:                    SpringContext.getBean(PersistenceService.class)
0840:                            .refreshAllNonUpdatingReferences(line);
0841:                    insertAccountingLine(false, financialDocumentForm, line);
0842:
0843:                    // clear the used newTargetLine
0844:                    financialDocumentForm.setNewTargetLine(null);
0845:                }
0846:
0847:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0848:            }
0849:
0850:            /**
0851:             * This action executes an insert of a SourceAccountingLine into a document only after validating the accounting line and
0852:             * checking any appropriate business rules.
0853:             * 
0854:             * @param mapping
0855:             * @param form
0856:             * @param request
0857:             * @param response
0858:             * @return ActionForward
0859:             * @throws Exception
0860:             */
0861:            public ActionForward insertSourceLine(ActionMapping mapping,
0862:                    ActionForm form, HttpServletRequest request,
0863:                    HttpServletResponse response) throws Exception {
0864:                KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
0865:
0866:                SourceAccountingLine line = financialDocumentForm
0867:                        .getNewSourceLine();
0868:                boolean rulePassed = true;
0869:                // before we check the regular rules we need to check the sales tax rules
0870:                // TODO: Refactor rules so we no longer have to call this before a copy of the
0871:                // accountingLine
0872:                rulePassed &= checkSalesTax(
0873:                        (AccountingDocument) financialDocumentForm
0874:                                .getDocument(), line, true, true, 0);
0875:                // check any business rules
0876:                rulePassed &= SpringContext
0877:                        .getBean(KualiRuleService.class)
0878:                        .applyRules(
0879:                                new AddAccountingLineEvent(
0880:                                        KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME,
0881:                                        financialDocumentForm.getDocument(),
0882:                                        line));
0883:
0884:                if (rulePassed) {
0885:                    // add accountingLine
0886:                    SpringContext.getBean(PersistenceService.class)
0887:                            .refreshAllNonUpdatingReferences(line);
0888:                    insertAccountingLine(true, financialDocumentForm, line);
0889:
0890:                    // clear the used newTargetLine
0891:                    financialDocumentForm.setNewSourceLine(null);
0892:                }
0893:
0894:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0895:            }
0896:
0897:            /**
0898:             * Adds the given accountingLine to the appropriate form-related datastructures.
0899:             * 
0900:             * @param isSource
0901:             * @param financialDocumentForm
0902:             * @param line
0903:             */
0904:            protected void insertAccountingLine(boolean isSource,
0905:                    KualiAccountingDocumentFormBase financialDocumentForm,
0906:                    AccountingLine line) {
0907:                // create and init a decorator
0908:                AccountingLineDecorator decorator = new AccountingLineDecorator();
0909:                decorator.setRevertible(false);
0910:
0911:                AccountingDocument tdoc = financialDocumentForm
0912:                        .getFinancialDocument();
0913:                if (isSource) {
0914:                    // add it to the document
0915:                    tdoc.addSourceAccountingLine((SourceAccountingLine) line);
0916:
0917:                    // add it to the baseline, to prevent generation of spurious update events
0918:                    financialDocumentForm.getBaselineSourceAccountingLines()
0919:                            .add(line);
0920:
0921:                    // add the decorator
0922:                    financialDocumentForm.getSourceLineDecorators().add(
0923:                            decorator);
0924:
0925:                    // add PK fields to sales tax if needed
0926:                    if (line.isSalesTaxRequired()) {
0927:                        populateSalesTax(line);
0928:                    }
0929:
0930:                    // Update the doc total
0931:                    if (tdoc instanceof  AmountTotaling)
0932:                        financialDocumentForm.getDocument().getDocumentHeader()
0933:                                .setFinancialDocumentTotalAmount(
0934:                                        ((AmountTotaling) tdoc)
0935:                                                .getTotalDollarAmount());
0936:                } else {
0937:                    // add it to the document
0938:                    tdoc.addTargetAccountingLine((TargetAccountingLine) line);
0939:
0940:                    // add it to the baseline, to prevent generation of spurious update events
0941:                    financialDocumentForm.getBaselineTargetAccountingLines()
0942:                            .add(line);
0943:
0944:                    // add the decorator
0945:                    financialDocumentForm.getTargetLineDecorators().add(
0946:                            decorator);
0947:
0948:                    // add PK fields to sales tax if needed
0949:                    if (line.isSalesTaxRequired()) {
0950:                        populateSalesTax(line);
0951:                    }
0952:                }
0953:            }
0954:
0955:            /**
0956:             * Method that will take the current document, copy it, replace all references to doc header id with a new one, clear pending
0957:             * entries, clear notes, and reset version numbers
0958:             * 
0959:             * @param mapping
0960:             * @param form
0961:             * @param request
0962:             * @param response
0963:             * @return
0964:             * @throws Exception
0965:             */
0966:            public ActionForward copy(ActionMapping mapping, ActionForm form,
0967:                    HttpServletRequest request, HttpServletResponse response)
0968:                    throws Exception {
0969:                super .copy(mapping, form, request, response);
0970:
0971:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
0972:
0973:                // KULEDOCS-1440: need to reset base accounting lines since when doc number changes on copy base lines would still reference
0974:                // old doc number causing revert button to show up
0975:                tmpForm.setBaselineSourceAccountingLines(tmpForm
0976:                        .getFinancialDocument().getSourceAccountingLines());
0977:                tmpForm.setBaselineTargetAccountingLines(tmpForm
0978:                        .getFinancialDocument().getTargetAccountingLines());
0979:                tmpForm.getSourceLineDecorators().clear();
0980:                tmpForm.getTargetLineDecorators().clear();
0981:
0982:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
0983:            }
0984:
0985:            /**
0986:             * This action changes the value of the hide field in the user interface so that when the page is rendered, the UI knows to show
0987:             * all of the labels for each of the accounting line values.
0988:             * 
0989:             * @param mapping
0990:             * @param form
0991:             * @param request
0992:             * @param response
0993:             * @return ActionForward
0994:             * @throws Exception
0995:             */
0996:            public ActionForward showDetails(ActionMapping mapping,
0997:                    ActionForm form, HttpServletRequest request,
0998:                    HttpServletResponse response) throws Exception {
0999:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
1000:                tmpForm.setHideDetails(false);
1001:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
1002:            }
1003:
1004:            /**
1005:             * This method is triggered when the user toggles the show/hide button to "hide" thus making the UI render without any of the
1006:             * accounting line labels/descriptions showing up underneath the values in the UI.
1007:             * 
1008:             * @param mapping
1009:             * @param form
1010:             * @param request
1011:             * @param response
1012:             * @return ActionForward
1013:             * @throws Exception
1014:             */
1015:            public ActionForward hideDetails(ActionMapping mapping,
1016:                    ActionForm form, HttpServletRequest request,
1017:                    HttpServletResponse response) throws Exception {
1018:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
1019:                tmpForm.setHideDetails(true);
1020:                return mapping.findForward(KFSConstants.MAPPING_BASIC);
1021:            }
1022:
1023:            /**
1024:             * Takes care of storing the action form in the User session and forwarding to the balance inquiry report menu action for a
1025:             * source accounting line.
1026:             * 
1027:             * @param mapping
1028:             * @param form
1029:             * @param request
1030:             * @param response
1031:             * @return ActionForward
1032:             * @throws Exception
1033:             */
1034:            public ActionForward performBalanceInquiryForSourceLine(
1035:                    ActionMapping mapping, ActionForm form,
1036:                    HttpServletRequest request, HttpServletResponse response)
1037:                    throws Exception {
1038:                SourceAccountingLine line = (SourceAccountingLine) getSourceAccountingLine(
1039:                        form, request);
1040:                return performBalanceInquiryForAccountingLine(mapping, form,
1041:                        request, line);
1042:            }
1043:
1044:            /**
1045:             * Takes care of storing the action form in the User session and forwarding to the balance inquiry report menu action for a
1046:             * target accounting line.
1047:             * 
1048:             * @param mapping
1049:             * @param form
1050:             * @param request
1051:             * @param response
1052:             * @return ActionForward
1053:             * @throws Exception
1054:             */
1055:            public ActionForward performBalanceInquiryForTargetLine(
1056:                    ActionMapping mapping, ActionForm form,
1057:                    HttpServletRequest request, HttpServletResponse response)
1058:                    throws Exception {
1059:                int lineIndex = getSelectedLine(request);
1060:
1061:                TargetAccountingLine line = (TargetAccountingLine) ObjectUtils
1062:                        .deepCopy(((KualiAccountingDocumentFormBase) form)
1063:                                .getFinancialDocument()
1064:                                .getTargetAccountingLine(lineIndex));
1065:
1066:                return performBalanceInquiryForAccountingLine(mapping, form,
1067:                        request, line);
1068:            }
1069:
1070:            /**
1071:             * This method is a helper method that will return a source accounting line. The reason we're making it protected in here is so
1072:             * that we can override this method in some of the modules. PurchasingActionBase is one of the subclasses that will be
1073:             * overriding this, because in PurchasingActionBase, we'll need to get the source accounting line using both an item index and
1074:             * an account index.
1075:             * 
1076:             * @param form
1077:             * @param request
1078:             * @param isSource
1079:             * @return
1080:             */
1081:            protected SourceAccountingLine getSourceAccountingLine(
1082:                    ActionForm form, HttpServletRequest request) {
1083:                int lineIndex = getSelectedLine(request);
1084:                SourceAccountingLine line = (SourceAccountingLine) ObjectUtils
1085:                        .deepCopy(((KualiAccountingDocumentFormBase) form)
1086:                                .getFinancialDocument()
1087:                                .getSourceAccountingLine(lineIndex));
1088:                return line;
1089:            }
1090:
1091:            /**
1092:             * This method handles preparing all of the accounting line data so that it can be pushed up to the balance inquiries for
1093:             * populating the search criteria of each.
1094:             * 
1095:             * @param mapping
1096:             * @param form
1097:             * @param request
1098:             * @param line
1099:             * @return ActionForward
1100:             */
1101:            protected ActionForward performBalanceInquiryForAccountingLine(
1102:                    ActionMapping mapping, ActionForm form,
1103:                    HttpServletRequest request, AccountingLine line) {
1104:                // build out base path for return location
1105:                String basePath = request.getScheme() + "://"
1106:                        + request.getServerName() + ":"
1107:                        + request.getServerPort() + request.getContextPath();
1108:
1109:                // build out the actual form key that will be used to retrieve the form on refresh
1110:                String callerDocFormKey = GlobalVariables.getUserSession()
1111:                        .addObject(form);
1112:
1113:                // now add required parameters
1114:                Properties parameters = new Properties();
1115:                parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER,
1116:                        KFSConstants.START_METHOD);
1117:                // need this next param b/c the lookup's return back will overwrite
1118:                // the original doc form key
1119:                parameters
1120:                        .put(
1121:                                KFSConstants.BALANCE_INQUIRY_REPORT_MENU_CALLER_DOC_FORM_KEY,
1122:                                callerDocFormKey);
1123:                parameters.put(KFSConstants.DOC_FORM_KEY, callerDocFormKey);
1124:                parameters.put(KFSConstants.BACK_LOCATION, basePath
1125:                        + mapping.getPath() + ".do");
1126:
1127:                if (StringUtils.isNotBlank(line.getReferenceOriginCode())) {
1128:                    parameters.put("referenceOriginCode", line
1129:                            .getReferenceOriginCode());
1130:                }
1131:                if (StringUtils.isNotBlank(line.getReferenceNumber())) {
1132:                    parameters
1133:                            .put("referenceNumber", line.getReferenceNumber());
1134:                }
1135:                if (StringUtils.isNotBlank(line.getReferenceTypeCode())) {
1136:                    parameters.put("referenceTypeCode", line
1137:                            .getReferenceTypeCode());
1138:                }
1139:                if (StringUtils.isNotBlank(line.getDebitCreditCode())) {
1140:                    parameters
1141:                            .put("debitCreditCode", line.getDebitCreditCode());
1142:                }
1143:                if (StringUtils.isNotBlank(line.getChartOfAccountsCode())) {
1144:                    parameters.put("chartOfAccountsCode", line
1145:                            .getChartOfAccountsCode());
1146:                }
1147:                if (StringUtils.isNotBlank(line.getAccountNumber())) {
1148:                    parameters.put("accountNumber", line.getAccountNumber());
1149:                }
1150:                if (StringUtils.isNotBlank(line.getFinancialObjectCode())) {
1151:                    parameters.put("financialObjectCode", line
1152:                            .getFinancialObjectCode());
1153:                }
1154:                if (StringUtils.isNotBlank(line.getSubAccountNumber())) {
1155:                    parameters.put("subAccountNumber", line
1156:                            .getSubAccountNumber());
1157:                }
1158:                if (StringUtils.isNotBlank(line.getFinancialSubObjectCode())) {
1159:                    parameters.put("financialSubObjectCode", line
1160:                            .getFinancialSubObjectCode());
1161:                }
1162:                if (StringUtils.isNotBlank(line.getProjectCode())) {
1163:                    parameters.put("projectCode", line.getProjectCode());
1164:                }
1165:                if (StringUtils.isNotBlank(line.getObjectTypeCode())) {
1166:                    parameters.put("objectTypeCode", line.getObjectTypeCode());
1167:                }
1168:
1169:                String lookupUrl = UrlFactory.parameterizeUrl(basePath + "/"
1170:                        + KFSConstants.BALANCE_INQUIRY_REPORT_MENU_ACTION,
1171:                        parameters);
1172:
1173:                return new ActionForward(lookupUrl, true);
1174:            }
1175:
1176:            @Override
1177:            public ActionForward save(ActionMapping mapping, ActionForm form,
1178:                    HttpServletRequest request, HttpServletResponse response)
1179:                    throws Exception {
1180:                ActionForward forward = super .save(mapping, form, request,
1181:                        response);
1182:
1183:                // KULEDOCS-1443: For the revert button, set the new baseline accounting lines as the most recently saved lines
1184:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
1185:                tmpForm.setBaselineSourceAccountingLines(tmpForm
1186:                        .getFinancialDocument().getSourceAccountingLines());
1187:                tmpForm.setBaselineTargetAccountingLines(tmpForm
1188:                        .getFinancialDocument().getTargetAccountingLines());
1189:                // need to check on sales tax for all the accounting lines
1190:                checkSalesTaxRequiredAllLines(tmpForm, tmpForm
1191:                        .getFinancialDocument().getSourceAccountingLines());
1192:                checkSalesTaxRequiredAllLines(tmpForm, tmpForm
1193:                        .getFinancialDocument().getTargetAccountingLines());
1194:                return forward;
1195:            }
1196:
1197:            @Override
1198:            public ActionForward route(ActionMapping mapping, ActionForm form,
1199:                    HttpServletRequest request, HttpServletResponse response)
1200:                    throws Exception {
1201:                ActionForward forward = super .route(mapping, form, request,
1202:                        response);
1203:                KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
1204:                checkSalesTaxRequiredAllLines(tmpForm, tmpForm
1205:                        .getFinancialDocument().getSourceAccountingLines());
1206:                checkSalesTaxRequiredAllLines(tmpForm, tmpForm
1207:                        .getFinancialDocument().getTargetAccountingLines());
1208:
1209:                return forward;
1210:            }
1211:
1212:            /**
1213:             * Encapsulate the rule check so we can call it from multiple places
1214:             * 
1215:             * @param document
1216:             * @param line
1217:             * @return true if sales is either not required or it contains sales tax
1218:             */
1219:            private boolean checkSalesTax(AccountingDocument document,
1220:                    AccountingLine line, boolean source, boolean newLine,
1221:                    int index) {
1222:                boolean passed = true;
1223:                if (isSalesTaxRequired(document, line)) {
1224:                    // then set the salesTaxRequired on the accountingLine
1225:                    line.setSalesTaxRequired(true);
1226:                    populateSalesTax(line);
1227:                    // check to see if the sales tax info has been put in
1228:                    passed &= isValidSalesTaxEntered(line, source, newLine,
1229:                            index);
1230:                }
1231:                return passed;
1232:            }
1233:
1234:            /**
1235:             * This method checks to see if this doctype needs sales tax If it does then it checks to see if the account and object code
1236:             * require sales tax If it does then it returns true. Note - this is hackish as we shouldn't have to call rules directly from
1237:             * the action class But we need to in this instance because we are copying the lines before calling rules and need a way to
1238:             * modify them before they go on
1239:             * 
1240:             * @param accountingLine
1241:             * @return true if sales tax check is needed, false otherwise
1242:             */
1243:            protected boolean isSalesTaxRequired(
1244:                    AccountingDocument financialDocument,
1245:                    AccountingLine accountingLine) {
1246:                boolean required = false;
1247:                DocumentTypeService docTypeService = SpringContext
1248:                        .getBean(DocumentTypeService.class);
1249:                String docType = docTypeService
1250:                        .getDocumentTypeCodeByClass(financialDocument
1251:                                .getClass());
1252:                // first we need to check just the doctype to see if it needs the sales tax check
1253:                ParameterService parameterService = SpringContext
1254:                        .getBean(ParameterService.class);
1255:                // apply the rule, see if it fails
1256:                ParameterEvaluator docTypeSalesTaxCheckEvaluator = SpringContext
1257:                        .getBean(ParameterService.class)
1258:                        .getParameterEvaluator(
1259:                                ParameterConstants.FINANCIAL_PROCESSING_DOCUMENT.class,
1260:                                APPLICATION_PARAMETER.DOCTYPE_SALES_TAX_CHECK,
1261:                                docType);
1262:                if (docTypeSalesTaxCheckEvaluator.evaluationSucceeds()) {
1263:                    required = true;
1264:                }
1265:
1266:                // second we need to check the account and object code combination to see if it needs sales tax
1267:                if (required) {
1268:                    // get the object code and account
1269:                    String objCd = accountingLine.getFinancialObjectCode();
1270:                    String account = accountingLine.getAccountNumber();
1271:                    if (!StringUtils.isEmpty(objCd)
1272:                            && !StringUtils.isEmpty(account)) {
1273:                        String compare = account + ":" + objCd;
1274:                        ParameterEvaluator salesTaxApplicableAcctAndObjectEvaluator = SpringContext
1275:                                .getBean(ParameterService.class)
1276:                                .getParameterEvaluator(
1277:                                        ParameterConstants.FINANCIAL_PROCESSING_DOCUMENT.class,
1278:                                        APPLICATION_PARAMETER.SALES_TAX_APPLICABLE_ACCOUNTS_AND_OBJECT_CODES,
1279:                                        compare);
1280:                        if (!salesTaxApplicableAcctAndObjectEvaluator
1281:                                .evaluationSucceeds()) {
1282:                            required = false;
1283:                        }
1284:                    } else {
1285:                        // the two fields are currently empty and we don't need to check yet
1286:                        required = false;
1287:                    }
1288:                }
1289:                return required;
1290:            }
1291:
1292:            /**
1293:             * This method checks to see if the sales tax information was put into the accounting line
1294:             * 
1295:             * @param accountingLine
1296:             * @return true if entered correctly, false otherwise
1297:             */
1298:            private boolean isValidSalesTaxEntered(
1299:                    AccountingLine accountingLine, boolean source,
1300:                    boolean newLine, int index) {
1301:                boolean valid = true;
1302:                DictionaryValidationService dictionaryValidationService = SpringContext
1303:                        .getBean(DictionaryValidationService.class);
1304:                BusinessObjectService boService = SpringContext
1305:                        .getBean(BusinessObjectService.class);
1306:                String objCd = accountingLine.getFinancialObjectCode();
1307:                String account = accountingLine.getAccountNumber();
1308:                SalesTax salesTax = accountingLine.getSalesTax();
1309:                String pathPrefix = "";
1310:                if (source && !newLine) {
1311:                    pathPrefix = "document."
1312:                            + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME
1313:                            + "[" + index + "]";
1314:                } else if (!source && !newLine) {
1315:                    pathPrefix = "document."
1316:                            + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME
1317:                            + "[" + index + "]";
1318:                } else if (source && newLine) {
1319:                    pathPrefix = KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME;
1320:                } else if (!source && newLine) {
1321:                    pathPrefix = KFSConstants.NEW_TARGET_ACCT_LINE_PROPERTY_NAME;
1322:                }
1323:                GlobalVariables.getErrorMap().addToErrorPath(pathPrefix);
1324:                if (ObjectUtils.isNull(salesTax)) {
1325:                    valid &= false;
1326:                    GlobalVariables.getErrorMap().putError(
1327:                            "salesTax.chartOfAccountsCode",
1328:                            ERROR_DOCUMENT_ACCOUNTING_LINE_SALES_TAX_REQUIRED,
1329:                            account, objCd);
1330:                } else {
1331:
1332:                    if (StringUtils.isBlank(salesTax.getChartOfAccountsCode())) {
1333:                        valid &= false;
1334:                        GlobalVariables.getErrorMap().putError(
1335:                                "salesTax.chartOfAccountsCode", ERROR_REQUIRED,
1336:                                "Chart of Accounts");
1337:                    }
1338:                    if (StringUtils.isBlank(salesTax.getAccountNumber())) {
1339:                        valid &= false;
1340:                        GlobalVariables.getErrorMap().putError(
1341:                                "salesTax.accountNumber", ERROR_REQUIRED,
1342:                                "Account Number");
1343:                    }
1344:                    if (salesTax.getFinancialDocumentGrossSalesAmount() == null) {
1345:                        valid &= false;
1346:                        GlobalVariables.getErrorMap().putError(
1347:                                "salesTax.financialDocumentGrossSalesAmount",
1348:                                ERROR_REQUIRED, "Gross Sales Amount");
1349:                    }
1350:                    if (salesTax.getFinancialDocumentTaxableSalesAmount() == null) {
1351:                        valid &= false;
1352:                        GlobalVariables.getErrorMap().putError(
1353:                                "salesTax.financialDocumentTaxableSalesAmount",
1354:                                ERROR_REQUIRED, "Taxable Sales Amount");
1355:                    }
1356:                    if (salesTax.getFinancialDocumentSaleDate() == null) {
1357:                        valid &= false;
1358:                        GlobalVariables.getErrorMap().putError(
1359:                                "salesTax.financialDocumentSaleDate",
1360:                                ERROR_REQUIRED, "Sale Date");
1361:                    }
1362:                    if (StringUtils.isNotBlank(salesTax
1363:                            .getChartOfAccountsCode())
1364:                            && StringUtils.isNotBlank(salesTax
1365:                                    .getAccountNumber())) {
1366:
1367:                        if (boService.getReferenceIfExists(salesTax, "account") == null) {
1368:                            valid &= false;
1369:                            GlobalVariables
1370:                                    .getErrorMap()
1371:                                    .putError(
1372:                                            "salesTax.accountNumber",
1373:                                            ERROR_DOCUMENT_ACCOUNTING_LINE_SALES_TAX_INVALID_ACCOUNT,
1374:                                            salesTax.getChartOfAccountsCode(),
1375:                                            salesTax.getAccountNumber());
1376:
1377:                        }
1378:                    }
1379:                    if (!valid) {
1380:                        GlobalVariables
1381:                                .getErrorMap()
1382:                                .putError(
1383:                                        "salesTax.chartOfAccountsCode",
1384:                                        ERROR_DOCUMENT_ACCOUNTING_LINE_SALES_TAX_REQUIRED,
1385:                                        account, objCd);
1386:                    }
1387:                }
1388:                GlobalVariables.getErrorMap().removeFromErrorPath(pathPrefix);
1389:                return valid;
1390:            }
1391:
1392:            /**
1393:             * This method removes the sales tax information from a line that no longer requires it
1394:             * 
1395:             * @param accountingLine
1396:             */
1397:            private void removeSalesTax(AccountingLine accountingLine) {
1398:                SalesTax salesTax = accountingLine.getSalesTax();
1399:                if (ObjectUtils.isNotNull(salesTax)) {
1400:                    accountingLine.setSalesTax(null);
1401:                }
1402:            }
1403:
1404:            /**
1405:             * This method checks to see if the given accounting needs sales tax and if it does it sets the salesTaxRequired variable on the
1406:             * line If it doesn't and it has it then it removes the sales tax information from the line This method is called from the
1407:             * execute() on all accounting lines that have been edited or lines that have already been added to the document, not on new
1408:             * lines
1409:             * 
1410:             * @param transDoc
1411:             * @param formLine
1412:             * @param baseLine
1413:             */
1414:            private void handleSalesTaxRequired(AccountingDocument transDoc,
1415:                    AccountingLine formLine, boolean source, boolean newLine,
1416:                    int index) {
1417:                boolean salesTaxRequired = isSalesTaxRequired(transDoc,
1418:                        formLine);
1419:                if (salesTaxRequired) {
1420:                    formLine.setSalesTaxRequired(true);
1421:                    populateSalesTax(formLine);
1422:                } else if (!salesTaxRequired
1423:                        && hasSalesTaxBeenEntered(formLine, source, newLine,
1424:                                index)) {
1425:                    // remove it if it has been added but is no longer required
1426:                    removeSalesTax(formLine);
1427:                }
1428:            }
1429:
1430:            private boolean hasSalesTaxBeenEntered(
1431:                    AccountingLine accountingLine, boolean source,
1432:                    boolean newLine, int index) {
1433:                boolean entered = true;
1434:                String objCd = accountingLine.getFinancialObjectCode();
1435:                String account = accountingLine.getAccountNumber();
1436:                SalesTax salesTax = accountingLine.getSalesTax();
1437:                if (ObjectUtils.isNull(salesTax)) {
1438:                    return false;
1439:                }
1440:                if (StringUtils.isBlank(salesTax.getChartOfAccountsCode())) {
1441:                    entered &= false;
1442:                }
1443:                if (StringUtils.isBlank(salesTax.getAccountNumber())) {
1444:                    entered &= false;
1445:                }
1446:                if (salesTax.getFinancialDocumentGrossSalesAmount() == null) {
1447:                    entered &= false;
1448:                }
1449:                if (salesTax.getFinancialDocumentTaxableSalesAmount() == null) {
1450:                    entered &= false;
1451:                }
1452:                if (salesTax.getFinancialDocumentSaleDate() == null) {
1453:                    entered &= false;
1454:                }
1455:                return entered;
1456:            }
1457:
1458:            /**
1459:             * This method is called from the createDocument and processes through all the accouting lines and checks to see if they need
1460:             * sales tax fields
1461:             * 
1462:             * @param kualiDocumentFormBase
1463:             * @param baselineSourceLines
1464:             */
1465:            private void handleSalesTaxRequiredAllLines(
1466:                    KualiDocumentFormBase kualiDocumentFormBase,
1467:                    List<AccountingLine> baselineAcctingLines) {
1468:                AccountingDocument accoutingDocument = (AccountingDocument) kualiDocumentFormBase
1469:                        .getDocument();
1470:                int index = 0;
1471:                for (AccountingLine accountingLine : baselineAcctingLines) {
1472:                    boolean source = false;
1473:                    if (accountingLine.isSourceAccountingLine()) {
1474:                        source = true;
1475:                    }
1476:                    handleSalesTaxRequired(accoutingDocument, accountingLine,
1477:                            source, false, index);
1478:                    index++;
1479:                }
1480:
1481:            }
1482:
1483:            private boolean checkSalesTaxRequiredAllLines(
1484:                    KualiDocumentFormBase kualiDocumentFormBase,
1485:                    List<AccountingLine> baselineAcctingLines) {
1486:                AccountingDocument accoutingDocument = (AccountingDocument) kualiDocumentFormBase
1487:                        .getDocument();
1488:                boolean passed = true;
1489:                int index = 0;
1490:                for (AccountingLine accountingLine : baselineAcctingLines) {
1491:                    boolean source = false;
1492:                    if (accountingLine.isSourceAccountingLine()) {
1493:                        source = true;
1494:                    }
1495:                    passed &= checkSalesTax(accoutingDocument, accountingLine,
1496:                            source, false, index);
1497:                    index++;
1498:                }
1499:                return passed;
1500:            }
1501:
1502:            /**
1503:             * This method refreshes the sales tax fields on a refresh or tab toggle so that all the information that was there before is
1504:             * still there after a state change
1505:             * 
1506:             * @param form
1507:             */
1508:            private void refreshSalesTaxInfo(ActionForm form) {
1509:                KualiAccountingDocumentFormBase accountingForm = (KualiAccountingDocumentFormBase) form;
1510:                AccountingDocument document = (AccountingDocument) accountingForm
1511:                        .getDocument();
1512:                List sourceLines = document.getSourceAccountingLines();
1513:                List targetLines = document.getTargetAccountingLines();
1514:                handleSalesTaxRequiredAllLines(accountingForm, sourceLines);
1515:                handleSalesTaxRequiredAllLines(accountingForm, targetLines);
1516:
1517:                AccountingLine newTargetLine = accountingForm
1518:                        .getNewTargetLine();
1519:                AccountingLine newSourceLine = accountingForm
1520:                        .getNewSourceLine();
1521:                if (newTargetLine != null) {
1522:                    handleSalesTaxRequired(document, newTargetLine, false,
1523:                            true, 0);
1524:                }
1525:                if (newSourceLine != null) {
1526:                    handleSalesTaxRequired(document, newSourceLine, true, true,
1527:                            0);
1528:                }
1529:            }
1530:
1531:            /**
1532:             * This method populates the sales tax for a given accounting line with the appropriate primary key fields from the accounting
1533:             * line since OJB won't do it automatically for us
1534:             * 
1535:             * @param line
1536:             */
1537:            private void populateSalesTax(AccountingLine line) {
1538:                SalesTax salesTax = line.getSalesTax();
1539:
1540:                if (ObjectUtils.isNotNull(salesTax)) {
1541:                    salesTax.setDocumentNumber(line.getDocumentNumber());
1542:                    salesTax.setFinancialDocumentLineTypeCode(line
1543:                            .getFinancialDocumentLineTypeCode());
1544:                    salesTax.setFinancialDocumentLineNumber(line
1545:                            .getSequenceNumber());
1546:                }
1547:            }
1548:
1549:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.