Source Code Cross Referenced for DisbursementVoucherTaxServiceImpl.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » module » financial » service » impl » 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.service.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2006-2007 The Kuali Foundation.
003:         * 
004:         * Licensed under the Educational Community License, Version 1.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         * 
008:         * http://www.opensource.org/licenses/ecl1.php
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.kuali.module.financial.service.impl;
017:
018:        import java.math.BigDecimal;
019:        import java.util.ArrayList;
020:        import java.util.Arrays;
021:        import java.util.Collection;
022:        import java.util.HashMap;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:
027:        import org.apache.commons.lang.StringUtils;
028:        import org.kuali.core.bo.user.PersonTaxId;
029:        import org.kuali.core.bo.user.UniversalUser;
030:        import org.kuali.core.bo.user.UserId;
031:        import org.kuali.core.exceptions.InfrastructureException;
032:        import org.kuali.core.exceptions.UserNotFoundException;
033:        import org.kuali.core.service.BusinessObjectService;
034:        import org.kuali.core.service.MaintenanceDocumentService;
035:        import org.kuali.core.service.UniversalUserService;
036:        import org.kuali.core.util.ErrorMap;
037:        import org.kuali.core.util.GlobalVariables;
038:        import org.kuali.core.util.KualiDecimal;
039:        import org.kuali.kfs.KFSConstants;
040:        import org.kuali.kfs.KFSKeyConstants;
041:        import org.kuali.kfs.bo.AccountingLine;
042:        import org.kuali.kfs.bo.SourceAccountingLine;
043:        import org.kuali.kfs.service.ParameterService;
044:        import org.kuali.module.financial.bo.DisbursementVoucherNonResidentAlienTax;
045:        import org.kuali.module.financial.bo.Payee;
046:        import org.kuali.module.financial.document.DisbursementVoucherDocument;
047:        import org.kuali.module.financial.rules.DisbursementVoucherDocumentRule;
048:        import org.kuali.module.financial.rules.DisbursementVoucherRuleConstants;
049:        import org.kuali.module.financial.service.DisbursementVoucherTaxService;
050:
051:        /**
052:         * This is the default implementation of the DisbursementVoucherExtractService interface.
053:         * This class handles queries and validation on tax id numbers.
054:         */
055:        public class DisbursementVoucherTaxServiceImpl implements 
056:                DisbursementVoucherTaxService, DisbursementVoucherRuleConstants {
057:            private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
058:                    .getLogger(DisbursementVoucherTaxServiceImpl.class);
059:
060:            private ParameterService parameterService;
061:            private BusinessObjectService businessObjectService;
062:            private MaintenanceDocumentService maintenanceDocumentService;
063:            private UniversalUserService universalUserService;
064:
065:            /**
066:             * This method retrieves the universal id of the individual or business entity who matches the tax id number and type
067:             * code given.
068:             * 
069:             * @param taxIDNumber The tax identification number of the user being retrieved.
070:             * @param taxPayerTypeCode The tax payer type code of the user being retrieved.  See the TAX_TYPE_* constants defined in 
071:             *                         DisbursementVoucherRuleConstants for examples of valid tax type codes.
072:             * @return The universal id of the individual who matches the tax id and type code given.  Null if no matching user is found.
073:             * 
074:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#getEmployeeNumber(java.lang.String, java.lang.String)
075:             */
076:            public String getUniversalId(String taxIDNumber,
077:                    String taxPayerTypeCode) {
078:                if (TAX_TYPE_FEIN.equals(taxPayerTypeCode)) {
079:                    return null;
080:                }
081:
082:                String universalId = null;
083:                UserId userId = (UserId) new PersonTaxId(taxIDNumber);
084:                UniversalUser universalUser = null;
085:
086:                try {
087:                    universalUser = universalUserService
088:                            .getUniversalUser(userId);
089:                } catch (UserNotFoundException e) {
090:                }
091:
092:                if (universalUser != null) {
093:                    universalId = universalUser.getPersonUniversalIdentifier();
094:                }
095:                return universalId;
096:            }
097:
098:            /**
099:             * This method retrieves the payee identification code for the payee found who has a matching tax id and tax payer type 
100:             * code.
101:             * 
102:             * @param taxIDNumber The tax id number used to retrieve the associated payee.
103:             * @param taxPayerTypeCode The tax payer type code used to retrieve the associated payee.  See the TAX_TYPE_* constants defined in 
104:             *                         DisbursementVoucherRuleConstants for examples of valid tax type codes.
105:             * @return The id of the payee found matching the tax id and type code provided.  Null if no matching payee is found.
106:             * 
107:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#getPayeeNumber(java.lang.String, java.lang.String)
108:             */
109:            public String getPayeeId(String taxIDNumber, String taxPayerTypeCode) {
110:                String payeeId = null;
111:
112:                Map taxIDCrit = new HashMap();
113:                taxIDCrit.put("taxIdNumber", taxIDNumber);
114:                taxIDCrit.put("taxpayerTypeCode", taxPayerTypeCode);
115:                Collection<Payee> foundPayees = businessObjectService
116:                        .findMatching(Payee.class, taxIDCrit);
117:
118:                if (!foundPayees.isEmpty()) {
119:                    Payee payee = (Payee) foundPayees.iterator().next();
120:                    payeeId = payee.getPayeeIdNumber();
121:                }
122:
123:                return payeeId;
124:            }
125:
126:            /**
127:             * This method is not currently implemented.  This method will be implemented once the EPIC vendor system in integrated 
128:             * into Kuali.  Until then, this method will always return null and should not be used.
129:             * 
130:             * @param taxIDNumber The tax id number used to retrieve the associated vendor.
131:             * @param taxPayerTypeCode The tax payer type code used to retrieve the associated vendor.
132:             * @return Always returns null.  
133:             * 
134:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#getVendorNumber(java.lang.String, java.lang.String)
135:             * @deprecated This method is not currently implemented and should not be called until it is fully implemented.
136:             */
137:            public String getVendorId(String taxIDNumber,
138:                    String taxPayerTypeCode) {
139:                String vendorId = null;
140:                // TODO: implement once EPIC is integrated
141:                return vendorId;
142:            }
143:
144:            /**
145:             * This method retrieves the pending payee id based on the tax id and payer type code provided.  
146:             * 
147:             * @param taxIDNumber The tax id number used to retrieve the matching pending payee.
148:             * @param taxPayerTypeCode The tax payer type code used to retrieve the matching pending payee.
149:             * @return The id of the pending payee matching the values given or null if no matching payee is found.
150:             * 
151:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#getPendingPayeeNumber(java.lang.String, java.lang.String)
152:             * @see org.kuali.core.service.MaintenanceDocumentService#getPendingObjects(Class)
153:             */
154:            public String getPendingPayeeId(String taxIDNumber,
155:                    String taxPayerTypeCode) {
156:                String pendingPayeeId = null;
157:
158:                List<Payee> pendingPayees = maintenanceDocumentService
159:                        .getPendingObjects(Payee.class);
160:
161:                for (Payee pendingPayee : pendingPayees) {
162:                    if (taxIDNumber.equals(pendingPayee.getTaxIdNumber())
163:                            && taxPayerTypeCode.equals(pendingPayee
164:                                    .getTaxpayerTypeCode())) {
165:                        pendingPayeeId = pendingPayee.getPayeeIdNumber();
166:                    }
167:                }
168:
169:                return pendingPayeeId;
170:            }
171:
172:            /**
173:             * This method generates non-resident alien (NRA) tax lines for the given disbursement voucher.  
174:             * 
175:             * The NRA tax lines consist of three possible sets of tax lines: 
176:             * - Gross up tax lines
177:             * - Federal tax lines
178:             * - State tax lines
179:             * 
180:             * Gross up tax lines are generated if the income tax gross up code is set on the DisbursementVoucherNonResidentAlienTax 
181:             * attribute of the disbursement voucher.
182:             * 
183:             * Federal tax lines are generated if the federal tax rate in the DisbursementVoucherNonResidentAlienTax attribute is
184:             * other than zero.
185:             * 
186:             * State tax lines are generated if the state tax rate in the DisbursementVoucherNonResidentAlienTax attribute is
187:             * other than zero.
188:             * 
189:             * @param document The disbursement voucher the NRA tax lines will be added to.
190:             * 
191:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#generateNRATaxLines(org.kuali.module.financial.document.DisbursementVoucherDocument)
192:             */
193:            private void generateNRATaxLines(
194:                    DisbursementVoucherDocument document) {
195:                // retrieve first accounting line for tax line attributes
196:                AccountingLine line1 = document.getSourceAccountingLine(0);
197:
198:                List taxLineNumbers = new ArrayList();
199:
200:                // generate gross up
201:                if (document.getDvNonResidentAlienTax()
202:                        .isIncomeTaxGrossUpCode()) {
203:                    AccountingLine grossLine = null;
204:                    try {
205:                        grossLine = (SourceAccountingLine) document
206:                                .getSourceAccountingLineClass().newInstance();
207:                    } catch (IllegalAccessException e) {
208:                        throw new InfrastructureException(
209:                                "unable to access sourceAccountingLineClass", e);
210:                    } catch (InstantiationException e) {
211:                        throw new InfrastructureException(
212:                                "unable to instantiate sourceAccountingLineClass",
213:                                e);
214:                    }
215:
216:                    grossLine.setDocumentNumber(document.getDocumentNumber());
217:                    grossLine.setSequenceNumber(document
218:                            .getNextSourceLineNumber());
219:                    grossLine.setChartOfAccountsCode(line1
220:                            .getChartOfAccountsCode());
221:                    grossLine.setAccountNumber(line1.getAccountNumber());
222:                    grossLine.setFinancialObjectCode(line1
223:                            .getFinancialObjectCode());
224:
225:                    // calculate gross up amount and set as line amount
226:                    BigDecimal federalTaxPercent = document
227:                            .getDvNonResidentAlienTax()
228:                            .getFederalIncomeTaxPercent().bigDecimalValue();
229:                    BigDecimal stateTaxPercent = document
230:                            .getDvNonResidentAlienTax()
231:                            .getStateIncomeTaxPercent().bigDecimalValue();
232:                    BigDecimal documentAmount = document
233:                            .getDisbVchrCheckTotalAmount().bigDecimalValue();
234:
235:                    KualiDecimal grossAmount1 = new KualiDecimal(
236:                            (documentAmount.multiply(federalTaxPercent).divide(
237:                                    new BigDecimal(100).subtract(
238:                                            federalTaxPercent).subtract(
239:                                            stateTaxPercent), 5,
240:                                    BigDecimal.ROUND_HALF_UP)));
241:                    KualiDecimal grossAmount2 = new KualiDecimal(
242:                            (documentAmount.multiply(stateTaxPercent).divide(
243:                                    new BigDecimal(100).subtract(
244:                                            federalTaxPercent).subtract(
245:                                            stateTaxPercent), 5,
246:                                    BigDecimal.ROUND_HALF_UP)));
247:                    grossLine.setAmount(grossAmount1.add(grossAmount2));
248:
249:                    // put line number in line number list, and update next line property in document
250:                    taxLineNumbers.add(grossLine.getSequenceNumber());
251:                    document.setNextSourceLineNumber(new Integer(document
252:                            .getNextSourceLineNumber().intValue() + 1));
253:
254:                    // add to source accounting lines
255:                    grossLine.refresh();
256:                    document.getSourceAccountingLines().add(grossLine);
257:
258:                    // update check total, is added because line amount is negative, so this will take check amount down
259:                    document.setDisbVchrCheckTotalAmount(document
260:                            .getDisbVchrCheckTotalAmount().add(
261:                                    grossLine.getAmount()));
262:                }
263:
264:                KualiDecimal taxableAmount = document
265:                        .getDisbVchrCheckTotalAmount();
266:
267:                // generate federal tax line
268:                if (!(KualiDecimal.ZERO.equals(document
269:                        .getDvNonResidentAlienTax()
270:                        .getFederalIncomeTaxPercent()))) {
271:                    String federalTaxChart = parameterService
272:                            .getParameterValue(
273:                                    DisbursementVoucherDocument.class,
274:                                    DisbursementVoucherRuleConstants.FEDERAL_TAX_PARM_PREFIX
275:                                            + DisbursementVoucherRuleConstants.TAX_PARM_CHART_SUFFIX);
276:                    String federalTaxAccount = parameterService
277:                            .getParameterValue(
278:                                    DisbursementVoucherDocument.class,
279:                                    DisbursementVoucherRuleConstants.FEDERAL_TAX_PARM_PREFIX
280:                                            + DisbursementVoucherRuleConstants.TAX_PARM_ACCOUNT_SUFFIX);
281:                    String federalTaxObjectCode = parameterService
282:                            .getParameterValue(
283:                                    DisbursementVoucherDocument.class,
284:                                    DisbursementVoucherRuleConstants.FEDERAL_TAX_PARM_PREFIX
285:                                            + DisbursementVoucherRuleConstants.TAX_PARM_OBJECT_BY_INCOME_CLASS_SUFFIX,
286:                                    document.getDvNonResidentAlienTax()
287:                                            .getIncomeClassCode());
288:                    if (StringUtils.isBlank(federalTaxChart)
289:                            || StringUtils.isBlank(federalTaxAccount)
290:                            || StringUtils.isBlank(federalTaxObjectCode)) {
291:                        LOG.error("Unable to retrieve federal tax parameters.");
292:                        throw new RuntimeException(
293:                                "Unable to retrieve federal tax parameters.");
294:                    }
295:
296:                    AccountingLine federalTaxLine = generateTaxAccountingLine(
297:                            document, federalTaxChart, federalTaxAccount,
298:                            federalTaxObjectCode, document
299:                                    .getDvNonResidentAlienTax()
300:                                    .getFederalIncomeTaxPercent(),
301:                            taxableAmount);
302:
303:                    // put line number in line number list, and update next line property in document
304:                    taxLineNumbers.add(federalTaxLine.getSequenceNumber());
305:                    document.setNextSourceLineNumber(new Integer(document
306:                            .getNextSourceLineNumber().intValue() + 1));
307:
308:                    // add to source accounting lines
309:                    federalTaxLine.refresh();
310:                    document.getSourceAccountingLines().add(federalTaxLine);
311:
312:                    // update check total, is added because line amount is negative, so this will take check amount down
313:                    document.setDisbVchrCheckTotalAmount(document
314:                            .getDisbVchrCheckTotalAmount().add(
315:                                    federalTaxLine.getAmount()));
316:                }
317:
318:                // generate state tax line
319:                if (!(KualiDecimal.ZERO.equals(document
320:                        .getDvNonResidentAlienTax().getStateIncomeTaxPercent()))) {
321:                    String stateTaxChart = parameterService
322:                            .getParameterValue(
323:                                    DisbursementVoucherDocument.class,
324:                                    DisbursementVoucherRuleConstants.STATE_TAX_PARM_PREFIX
325:                                            + DisbursementVoucherRuleConstants.TAX_PARM_CHART_SUFFIX);
326:                    String stateTaxAccount = parameterService
327:                            .getParameterValue(
328:                                    DisbursementVoucherDocument.class,
329:                                    DisbursementVoucherRuleConstants.STATE_TAX_PARM_PREFIX
330:                                            + DisbursementVoucherRuleConstants.TAX_PARM_ACCOUNT_SUFFIX);
331:                    String stateTaxObjectCode = parameterService
332:                            .getParameterValues(
333:                                    DisbursementVoucherDocument.class,
334:                                    DisbursementVoucherRuleConstants.STATE_TAX_PARM_PREFIX
335:                                            + DisbursementVoucherRuleConstants.TAX_PARM_OBJECT_BY_INCOME_CLASS_SUFFIX,
336:                                    document.getDvNonResidentAlienTax()
337:                                            .getIncomeClassCode()).get(0);
338:
339:                    if (StringUtils.isBlank(stateTaxChart)
340:                            || StringUtils.isBlank(stateTaxAccount)
341:                            || StringUtils.isBlank(stateTaxObjectCode)) {
342:                        LOG.error("Unable to retrieve state tax parameters.");
343:                        throw new RuntimeException(
344:                                "Unable to retrieve state tax parameters.");
345:                    }
346:
347:                    AccountingLine stateTaxLine = generateTaxAccountingLine(
348:                            document, stateTaxChart, stateTaxAccount,
349:                            stateTaxObjectCode, document
350:                                    .getDvNonResidentAlienTax()
351:                                    .getStateIncomeTaxPercent(), taxableAmount);
352:
353:                    // put line number in line number list, and update next line property in document
354:                    taxLineNumbers.add(stateTaxLine.getSequenceNumber());
355:                    document.setNextSourceLineNumber(new Integer(document
356:                            .getNextSourceLineNumber().intValue() + 1));
357:
358:                    // add to source accounting lines
359:                    stateTaxLine.refresh();
360:                    document.getSourceAccountingLines().add(stateTaxLine);
361:
362:                    // update check total, is added because line amount is negative, so this will take check amount down
363:                    document.setDisbVchrCheckTotalAmount(document
364:                            .getDisbVchrCheckTotalAmount().add(
365:                                    stateTaxLine.getAmount()));
366:                }
367:
368:                // update line number field
369:                document.getDvNonResidentAlienTax()
370:                        .setFinancialDocumentAccountingLineText(
371:                                StringUtils
372:                                        .join(taxLineNumbers.iterator(), ","));
373:            }
374:
375:            /**
376:             * Generates an accounting line for the chart, account, object code & tax percentage values given.
377:             * 
378:             * @param document The disbursement voucher the tax will be applied to.
379:             * @param chart The chart code to be assigned to the accounting line generated.
380:             * @param account The account code to be assigned to the accounting line generated.
381:             * @param objectCode The object code used on the accounting line generated.
382:             * @param taxPercent The tax rate to be used to calculate the tax amount.
383:             * @param taxableAmount The total amount that is taxable.  This amount is used in conjunction with the tax percent
384:             *                      to calculate the amount for the accounting lined being generated.
385:             * @return A fully populated AccountingLine instance representing the amount of tax that will be applied to the 
386:             *         disbursement voucher provided.
387:             */
388:            private AccountingLine generateTaxAccountingLine(
389:                    DisbursementVoucherDocument document, String chart,
390:                    String account, String objectCode, KualiDecimal taxPercent,
391:                    KualiDecimal taxableAmount) {
392:                AccountingLine taxLine = null;
393:                try {
394:                    taxLine = (SourceAccountingLine) document
395:                            .getSourceAccountingLineClass().newInstance();
396:                } catch (IllegalAccessException e) {
397:                    throw new InfrastructureException(
398:                            "unable to access sourceAccountingLineClass", e);
399:                } catch (InstantiationException e) {
400:                    throw new InfrastructureException(
401:                            "unable to instantiate sourceAccountingLineClass",
402:                            e);
403:                }
404:
405:                taxLine.setDocumentNumber(document.getDocumentNumber());
406:                taxLine.setSequenceNumber(document.getNextSourceLineNumber());
407:                taxLine.setChartOfAccountsCode(chart);
408:                taxLine.setAccountNumber(account);
409:                taxLine.setFinancialObjectCode(objectCode);
410:
411:                // calculate tax amount and set as line amount
412:                BigDecimal amount = taxableAmount.bigDecimalValue();
413:                BigDecimal tax = taxPercent.bigDecimalValue();
414:                BigDecimal taxDecimal = tax.divide(new BigDecimal(100), 5,
415:                        BigDecimal.ROUND_HALF_UP);
416:                KualiDecimal taxAmount = new KualiDecimal(amount
417:                        .multiply(taxDecimal));
418:                taxLine.setAmount(taxAmount.negated());
419:
420:                return taxLine;
421:            }
422:
423:            /**
424:             * This method validates the non-resident alien (NRA) tax information for the document and if the information validates, 
425:             * the NRA tax lines are generated. 
426:             * 
427:             * @param document The disbursement voucher document the NRA tax information will be validated and the subsequent 
428:             *                 tax lines generated for.
429:             * 
430:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#processNonResidentAlienTax(org.kuali.module.financial.document.DisbursementVoucherDocument,
431:             *      java.util.List)
432:             */
433:            public void processNonResidentAlienTax(
434:                    DisbursementVoucherDocument document) {
435:                if (validateNRATaxInformation(document)) {
436:                    generateNRATaxLines(document);
437:                }
438:            }
439:
440:            /**
441:             * Removes non-resident alien (NRA) tax lines from the document's accounting lines and updates the check total.
442:             * 
443:             * @param document The disbursement voucher the NRA tax lines will be removed from.
444:             */
445:            public void clearNRATaxLines(DisbursementVoucherDocument document) {
446:                ArrayList<SourceAccountingLine> taxLines = new ArrayList<SourceAccountingLine>();
447:                KualiDecimal taxTotal = new KualiDecimal(0);
448:
449:                DisbursementVoucherNonResidentAlienTax dvnrat = document
450:                        .getDvNonResidentAlienTax();
451:                if (dvnrat != null) {
452:                    List<Integer> previousTaxLineNumbers = getNRATaxLineNumbers(dvnrat
453:                            .getFinancialDocumentAccountingLineText());
454:
455:                    // get tax lines out of source lines
456:                    boolean previousGrossUp = false;
457:                    List<SourceAccountingLine> srcLines = document
458:                            .getSourceAccountingLines();
459:                    for (SourceAccountingLine line : srcLines) {
460:                        if (previousTaxLineNumbers.contains(line
461:                                .getSequenceNumber())) {
462:                            taxLines.add(line);
463:
464:                            // check if tax line was a positive amount, in which case we had a gross up
465:                            if ((new KualiDecimal(0)).compareTo(line
466:                                    .getAmount()) < 0) {
467:                                previousGrossUp = true;
468:                            } else {
469:                                taxTotal = taxTotal.add(line.getAmount().abs());
470:                            }
471:                        }
472:                    }
473:
474:                    // remove tax lines
475:                    /*
476:                     * NOTE: a custom remove method needed to be used here because the .equals() method for 
477:                     * AccountingLineBase does not take amount into account when determining equality.  
478:                     * This lead to the issues described in KULRNE-6201.  
479:                     */
480:                    Iterator<SourceAccountingLine> saLineIter = document
481:                            .getSourceAccountingLines().iterator();
482:                    while (saLineIter.hasNext()) {
483:                        SourceAccountingLine saLine = saLineIter.next();
484:                        for (SourceAccountingLine taxLine : taxLines) {
485:                            if (saLine.equals(taxLine)) {
486:                                if (saLine.getAmount().equals(
487:                                        taxLine.getAmount())) {
488:                                    saLineIter.remove();
489:                                }
490:                            }
491:                        }
492:                    }
493:
494:                    // update check total if not grossed up
495:                    if (!previousGrossUp) {
496:                        document.setDisbVchrCheckTotalAmount(document
497:                                .getDisbVchrCheckTotalAmount().add(taxTotal));
498:                    }
499:
500:                    // clear line string
501:                    dvnrat.setFinancialDocumentAccountingLineText("");
502:                }
503:            }
504:
505:            /**
506:             * This method retrieves the non-resident alien (NRA) tax amount using the disbursement voucher given to calculate the 
507:             * amount.  If the payee is not a non-resident alien or they are and there is no gross up code set, the amount returned 
508:             * will be zero.  If the payee is a non-resident alien and gross up has been set, the amount is calculated by 
509:             * retrieving all the source accounting lines for the disbursement voucher provided and summing the amounts of all the 
510:             * lines that are NRA tax lines.  
511:             * 
512:             * @param document The disbursement voucher the NRA tax line amount will be calculated for.
513:             * @return The NRA tax amount applicable to the given disbursement voucher or zero if the voucher does not have any 
514:             *         NRA tax lines.
515:             * 
516:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#getNonResidentAlienTaxAmount(org.kuali.module.financial.document.DisbursementVoucherDocument)
517:             */
518:            public KualiDecimal getNonResidentAlienTaxAmount(
519:                    DisbursementVoucherDocument document) {
520:                KualiDecimal taxAmount = new KualiDecimal(0);
521:
522:                // if not nra payment or gross has been done, no tax amount should have been taken out
523:                if (!document.getDvPayeeDetail().isDisbVchrAlienPaymentCode()
524:                        || (document.getDvPayeeDetail()
525:                                .isDisbVchrAlienPaymentCode() && document
526:                                .getDvNonResidentAlienTax()
527:                                .isIncomeTaxGrossUpCode())) {
528:                    return taxAmount;
529:                }
530:
531:                // get tax line numbers
532:                List taxLineNumbers = getNRATaxLineNumbers(document
533:                        .getDvNonResidentAlienTax()
534:                        .getFinancialDocumentAccountingLineText());
535:
536:                for (Iterator iter = document.getSourceAccountingLines()
537:                        .iterator(); iter.hasNext();) {
538:                    SourceAccountingLine line = (SourceAccountingLine) iter
539:                            .next();
540:
541:                    // check if line is nra tax line
542:                    if (taxLineNumbers.contains(line.getSequenceNumber())) {
543:                        taxAmount.add(line.getAmount().negated());
544:                    }
545:                }
546:
547:                return taxAmount;
548:            }
549:
550:            /**
551:             * This method performs a series of validation checks to ensure that the disbursement voucher given contains non-resident
552:             * alien specific information and non-resident alien tax lines are necessary.  
553:             * 
554:             * The following steps are taken to validate the disbursement voucher given:
555:             * - Set all percentages (ie. federal, state) to zero if their current value is null.
556:             * - Call DisbursementVoucherDocumentRule.validateNonResidentAlienInformation to perform more in-depth validation.
557:             * - The payee for the disbursement voucher given is a non-resident alien.
558:             * - No reference document exists for the assigned DisbursementVoucherNonResidentAlienTax attribute of the voucher given.
559:             * - There is at least one source accounting line to generate the tax line from.
560:             * - Both the state and federal tax percentages are greater than zero.
561:             * - The total check amount is not negative.
562:             * - The total of the accounting lines is not negative.
563:             * - The total check amount is equal to the total of the accounting lines.
564:             * 
565:             * 
566:             * @param document The disbursement voucher document to validate the tax lines for.
567:             * @return True if the information associated with non-resident alien tax is correct and valid, false otherwise.
568:             * 
569:             * @see org.kuali.module.financial.service.DisbursementVoucherTaxService#validateNRATaxInformation(org.kuali.module.financial.document.DisbursementVoucherDocument)
570:             * @see org.kuali.module.financial.rules.DisbursementVoucherDocumentRule#validateNonResidentAlienInformation(DisbursementVoucherDocument)
571:             */
572:            private boolean validateNRATaxInformation(
573:                    DisbursementVoucherDocument document) {
574:                ErrorMap errors = GlobalVariables.getErrorMap();
575:
576:                // set nulls to 0
577:                if (document.getDvNonResidentAlienTax()
578:                        .getFederalIncomeTaxPercent() == null) {
579:                    document.getDvNonResidentAlienTax()
580:                            .setFederalIncomeTaxPercent(new KualiDecimal(0));
581:                }
582:
583:                if (document.getDvNonResidentAlienTax()
584:                        .getStateIncomeTaxPercent() == null) {
585:                    document.getDvNonResidentAlienTax()
586:                            .setStateIncomeTaxPercent(new KualiDecimal(0));
587:                }
588:
589:                /* call dv rule to do general nra validation */
590:                DisbursementVoucherDocumentRule documentRule = new DisbursementVoucherDocumentRule();
591:                documentRule.validateNonResidentAlienInformation(document);
592:
593:                if (!GlobalVariables.getErrorMap().isEmpty()) {
594:                    return false;
595:                }
596:
597:                /* make sure payee is nra */
598:                if (!document.getDvPayeeDetail().isDisbVchrAlienPaymentCode()) {
599:                    errors.putErrorWithoutFullErrorPath("DVNRATaxErrors",
600:                            KFSKeyConstants.ERROR_DV_GENERATE_TAX_NOT_NRA);
601:                    return false;
602:                }
603:
604:                /* don't generate tax if reference doc is given */
605:                if (StringUtils.isNotBlank(document.getDvNonResidentAlienTax()
606:                        .getReferenceFinancialDocumentNumber())) {
607:                    errors
608:                            .putErrorWithoutFullErrorPath(
609:                                    "DVNRATaxErrors",
610:                                    KFSKeyConstants.ERROR_DV_GENERATE_TAX_DOC_REFERENCE);
611:                    return false;
612:                }
613:
614:                // check attributes needed to generate lines
615:                /* need at least 1 line */
616:                if (!(document.getSourceAccountingLines().size() >= 1)) {
617:                    errors.putErrorWithoutFullErrorPath("DVNRATaxErrors",
618:                            KFSKeyConstants.ERROR_DV_GENERATE_TAX_NO_SOURCE);
619:                    return false;
620:                }
621:
622:                /* make sure both fed and state tax percents are not 0, in which case there is no need to generate lines */
623:                if (KualiDecimal.ZERO.equals(document
624:                        .getDvNonResidentAlienTax()
625:                        .getFederalIncomeTaxPercent())
626:                        && KualiDecimal.ZERO.equals(document
627:                                .getDvNonResidentAlienTax()
628:                                .getStateIncomeTaxPercent())) {
629:                    errors.putErrorWithoutFullErrorPath("DVNRATaxErrors",
630:                            KFSKeyConstants.ERROR_DV_GENERATE_TAX_BOTH_0);
631:                    return false;
632:                }
633:
634:                /* check total cannot be negative */
635:                if (KFSConstants.ZERO.compareTo(document
636:                        .getDisbVchrCheckTotalAmount()) == 1) {
637:                    errors.putErrorWithoutFullErrorPath(
638:                            "document.disbVchrCheckTotalAmount",
639:                            KFSKeyConstants.ERROR_NEGATIVE_OR_ZERO_CHECK_TOTAL);
640:                    return false;
641:                }
642:
643:                /* total accounting lines cannot be negative */
644:                if (KFSConstants.ZERO.compareTo(document.getSourceTotal()) == 1) {
645:                    errors.putErrorWithoutFullErrorPath(
646:                            KFSConstants.ACCOUNTING_LINE_ERRORS,
647:                            KFSKeyConstants.ERROR_NEGATIVE_ACCOUNTING_TOTAL);
648:                    return false;
649:                }
650:
651:                /* total of accounting lines must match check total */
652:                if (document.getDisbVchrCheckTotalAmount().compareTo(
653:                        document.getSourceTotal()) != 0) {
654:                    errors.putErrorWithoutFullErrorPath(
655:                            KFSConstants.ACCOUNTING_LINE_ERRORS,
656:                            KFSKeyConstants.ERROR_CHECK_ACCOUNTING_TOTAL);
657:                    return false;
658:                }
659:
660:                return true;
661:            }
662:
663:            /**
664:             * Parses the tax line string given and returns a list of line numbers as Integers.
665:             * 
666:             * @param taxLineString The string to be parsed.
667:             * @return A collection of line numbers represented as Integers.
668:             */
669:            public List<Integer> getNRATaxLineNumbers(String taxLineString) {
670:                List<Integer> taxLineNumbers = new ArrayList();
671:                if (StringUtils.isNotBlank(taxLineString)) {
672:                    List<String> taxLineNumberStrings = Arrays
673:                            .asList(StringUtils.split(taxLineString, ","));
674:                    for (String lineNumber : taxLineNumberStrings) {
675:                        taxLineNumbers.add(Integer.valueOf(lineNumber));
676:                    }
677:                }
678:
679:                return taxLineNumbers;
680:            }
681:
682:            /**
683:             * This method sets the parameterService attribute to the value given.
684:             * @param parameterService The ParameterService to be set.
685:             */
686:            public void setParameterService(ParameterService parameterService) {
687:                this .parameterService = parameterService;
688:            }
689:
690:            /**
691:             * Gets the value of the businessObjectService instance.
692:             * @return Returns the businessObjectService.
693:             */
694:            public BusinessObjectService getBusinessObjectService() {
695:                return businessObjectService;
696:            }
697:
698:            /**
699:             * This method sets the businessObjectService attribute to the value given.
700:             * @param businessObjectService The businessObjectService to set.
701:             */
702:            public void setBusinessObjectService(
703:                    BusinessObjectService businessObjectService) {
704:                this .businessObjectService = businessObjectService;
705:            }
706:
707:            /**
708:             * Gets the value of the maintenanceDocumentService instance.
709:             * @return Returns the maintenanceDocumentService.
710:             */
711:            public MaintenanceDocumentService getMaintenanceDocumentService() {
712:                return maintenanceDocumentService;
713:            }
714:
715:            /**
716:             * This method sets the maintenanceDocumentService attribute to the value given.
717:             * @param maintenanceDocumentService The maintenanceDocumentService to set.
718:             */
719:            public void setMaintenanceDocumentService(
720:                    MaintenanceDocumentService maintenanceDocumentService) {
721:                this .maintenanceDocumentService = maintenanceDocumentService;
722:            }
723:
724:            /**
725:             * Gets the value of the universalUserService instance.
726:             * @return Returns the universalUserService.
727:             */
728:            public UniversalUserService getUniversalUserService() {
729:                return universalUserService;
730:            }
731:
732:            /**
733:             * This method sets the universalUserService attribute to the value given.
734:             * @param universalUserService The universalUserService to set.
735:             */
736:            public void setUniversalUserService(
737:                    UniversalUserService universalUserService) {
738:                this.universalUserService = universalUserService;
739:            }
740:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.