Source Code Cross Referenced for PurapGeneralLedgerServiceImpl.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » module » purap » 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.purap.service.impl 
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.module.purap.service.impl;
0017:
0018:        import static org.kuali.core.util.KualiDecimal.ZERO;
0019:        import static org.kuali.kfs.KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE;
0020:        import static org.kuali.kfs.KFSConstants.ENCUMB_UPDT_DOCUMENT_CD;
0021:        import static org.kuali.kfs.KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD;
0022:        import static org.kuali.kfs.KFSConstants.GL_CREDIT_CODE;
0023:        import static org.kuali.kfs.KFSConstants.GL_DEBIT_CODE;
0024:        import static org.kuali.module.purap.PurapConstants.HUNDRED;
0025:        import static org.kuali.module.purap.PurapConstants.PURAP_ORIGIN_CODE;
0026:
0027:        import java.math.BigDecimal;
0028:        import java.util.ArrayList;
0029:        import java.util.Collections;
0030:        import java.util.HashMap;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:
0035:        import org.kuali.core.service.BusinessObjectService;
0036:        import org.kuali.core.service.DateTimeService;
0037:        import org.kuali.core.service.KualiConfigurationService;
0038:        import org.kuali.core.service.KualiRuleService;
0039:        import org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper;
0040:        import org.kuali.core.util.KualiDecimal;
0041:        import org.kuali.core.util.ObjectUtils;
0042:        import org.kuali.kfs.bo.AccountingLine;
0043:        import org.kuali.kfs.bo.GeneralLedgerPendingEntry;
0044:        import org.kuali.kfs.bo.SourceAccountingLine;
0045:        import org.kuali.kfs.context.SpringContext;
0046:        import org.kuali.kfs.rule.event.GenerateGeneralLedgerPendingEntriesEvent;
0047:        import org.kuali.kfs.service.GeneralLedgerPendingEntryService;
0048:        import org.kuali.module.chart.bo.ObjectCode;
0049:        import org.kuali.module.chart.bo.SubObjCd;
0050:        import org.kuali.module.chart.service.ObjectCodeService;
0051:        import org.kuali.module.chart.service.SubObjectCodeService;
0052:        import org.kuali.module.financial.service.UniversityDateService;
0053:        import org.kuali.module.gl.bo.UniversityDate;
0054:        import org.kuali.module.purap.PurapConstants;
0055:        import org.kuali.module.purap.PurapPropertyConstants;
0056:        import org.kuali.module.purap.PurapConstants.PurapDocTypeCodes;
0057:        import org.kuali.module.purap.bo.CreditMemoItem;
0058:        import org.kuali.module.purap.bo.ItemType;
0059:        import org.kuali.module.purap.bo.PaymentRequestItem;
0060:        import org.kuali.module.purap.bo.PaymentRequestSummaryAccount;
0061:        import org.kuali.module.purap.bo.PurchaseOrderAccount;
0062:        import org.kuali.module.purap.bo.PurchaseOrderItem;
0063:        import org.kuali.module.purap.document.AccountsPayableDocument;
0064:        import org.kuali.module.purap.document.CreditMemoDocument;
0065:        import org.kuali.module.purap.document.PaymentRequestDocument;
0066:        import org.kuali.module.purap.document.PurchaseOrderDocument;
0067:        import org.kuali.module.purap.document.PurchasingAccountsPayableDocument;
0068:        import org.kuali.module.purap.service.PaymentRequestService;
0069:        import org.kuali.module.purap.service.PurapAccountingService;
0070:        import org.kuali.module.purap.service.PurapGeneralLedgerService;
0071:        import org.kuali.module.purap.service.PurchaseOrderService;
0072:        import org.springframework.transaction.annotation.Transactional;
0073:
0074:        @Transactional
0075:        public class PurapGeneralLedgerServiceImpl implements 
0076:                PurapGeneralLedgerService {
0077:            private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
0078:                    .getLogger(PurapGeneralLedgerServiceImpl.class);
0079:
0080:            private BusinessObjectService businessObjectService;
0081:            private DateTimeService dateTimeService;
0082:            private GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
0083:            private KualiConfigurationService kualiConfigurationService;
0084:            private KualiRuleService kualiRuleService;
0085:            private PaymentRequestService paymentRequestService;
0086:            private PurapAccountingService purapAccountingService;
0087:            private PurchaseOrderService purchaseOrderService;
0088:            private UniversityDateService universityDateService;
0089:
0090:            /**
0091:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#customizeGeneralLedgerPendingEntry(org.kuali.module.purap.document.PurchasingAccountsPayableDocument,
0092:             *      org.kuali.kfs.bo.AccountingLine, org.kuali.kfs.bo.GeneralLedgerPendingEntry, java.lang.Integer, java.lang.String,
0093:             *      java.lang.String, boolean)
0094:             */
0095:            public void customizeGeneralLedgerPendingEntry(
0096:                    PurchasingAccountsPayableDocument purapDocument,
0097:                    AccountingLine accountingLine,
0098:                    GeneralLedgerPendingEntry explicitEntry,
0099:                    Integer referenceDocumentNumber, String debitCreditCode,
0100:                    String docType, boolean isEncumbrance) {
0101:                LOG.debug("customizeGeneralLedgerPendingEntry() started");
0102:
0103:                // USE CURRENT; don't use FY on doc in case it's a prior year
0104:                UniversityDate uDate = universityDateService
0105:                        .getCurrentUniversityDate();
0106:                explicitEntry.setUniversityFiscalYear(uDate
0107:                        .getUniversityFiscalYear());
0108:                explicitEntry.setUniversityFiscalPeriodCode(uDate
0109:                        .getUniversityFiscalAccountingPeriod());
0110:
0111:                explicitEntry.setDocumentNumber(purapDocument
0112:                        .getDocumentNumber());
0113:                explicitEntry
0114:                        .setTransactionLedgerEntryDescription(entryDescription(purapDocument
0115:                                .getVendorName()));
0116:                explicitEntry
0117:                        .setFinancialSystemOriginationCode(PURAP_ORIGIN_CODE);
0118:
0119:                if (ObjectUtils.isNotNull(referenceDocumentNumber)) {
0120:                    explicitEntry
0121:                            .setReferenceFinancialDocumentNumber(referenceDocumentNumber
0122:                                    .toString());
0123:                    explicitEntry
0124:                            .setReferenceFinancialDocumentTypeCode(PurapDocTypeCodes.PO_DOCUMENT);
0125:                    explicitEntry
0126:                            .setReferenceFinancialSystemOriginationCode(PURAP_ORIGIN_CODE);
0127:                }
0128:
0129:                ObjectCode objectCode = SpringContext.getBean(
0130:                        ObjectCodeService.class).getByPrimaryId(
0131:                        explicitEntry.getUniversityFiscalYear(),
0132:                        explicitEntry.getChartOfAccountsCode(),
0133:                        explicitEntry.getFinancialObjectCode());
0134:                if (ObjectUtils.isNotNull(objectCode)) {
0135:                    explicitEntry.setFinancialObjectTypeCode(objectCode
0136:                            .getFinancialObjectTypeCode());
0137:                }
0138:
0139:                SubObjCd subObjectCode = SpringContext.getBean(
0140:                        SubObjectCodeService.class).getByPrimaryId(
0141:                        explicitEntry.getUniversityFiscalYear(),
0142:                        explicitEntry.getChartOfAccountsCode(),
0143:                        explicitEntry.getAccountNumber(),
0144:                        explicitEntry.getFinancialObjectCode(),
0145:                        explicitEntry.getFinancialSubObjectCode());
0146:                if (ObjectUtils.isNotNull(subObjectCode)) {
0147:                    explicitEntry.setFinancialSubObjectCode(subObjectCode
0148:                            .getFinancialSubObjectCode());
0149:                }
0150:
0151:                if (isEncumbrance) {
0152:                    explicitEntry
0153:                            .setFinancialBalanceTypeCode(BALANCE_TYPE_EXTERNAL_ENCUMBRANCE);
0154:
0155:                    // D - means the encumbrance is based on the document number
0156:                    // R - means the encumbrance is based on the referring document number
0157:                    // Encumbrances are created on the PO. They are updated by PREQ's and CM's.
0158:                    // So PO encumbrances are D, PREQ & CM's are R.
0159:                    if (PurapDocTypeCodes.PO_DOCUMENT.equals(docType)) {
0160:                        explicitEntry
0161:                                .setTransactionEncumbranceUpdateCode(ENCUMB_UPDT_DOCUMENT_CD);
0162:                    } else {
0163:                        explicitEntry
0164:                                .setTransactionEncumbranceUpdateCode(ENCUMB_UPDT_REFERENCE_DOCUMENT_CD);
0165:                    }
0166:                }
0167:
0168:                // if the amount is negative, flip the D/C indicator
0169:                if (accountingLine.getAmount().doubleValue() < 0) {
0170:                    if (GL_CREDIT_CODE.equals(debitCreditCode)) {
0171:                        explicitEntry
0172:                                .setTransactionDebitCreditCode(GL_DEBIT_CODE);
0173:                    } else {
0174:                        explicitEntry
0175:                                .setTransactionDebitCreditCode(GL_CREDIT_CODE);
0176:                    }
0177:                } else {
0178:                    explicitEntry
0179:                            .setTransactionDebitCreditCode(debitCreditCode);
0180:                }
0181:
0182:            }// end purapCustomizeGeneralLedgerPendingEntry()
0183:
0184:            /**
0185:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesCancelAccountsPayableDocument(org.kuali.module.purap.document.AccountsPayableDocument)
0186:             */
0187:            public void generateEntriesCancelAccountsPayableDocument(
0188:                    AccountsPayableDocument apDocument) {
0189:                LOG
0190:                        .debug("generateEntriesCancelAccountsPayableDocument() started");
0191:                if (apDocument instanceof  PaymentRequestDocument) {
0192:                    LOG
0193:                            .info("generateEntriesCancelAccountsPayableDocument() cancel PaymentRequestDocument");
0194:                    generateEntriesCancelPaymentRequest((PaymentRequestDocument) apDocument);
0195:                } else if (apDocument instanceof  CreditMemoDocument) {
0196:                    LOG
0197:                            .info("generateEntriesCancelAccountsPayableDocument() cancel CreditMemoDocument");
0198:                    generateEntriesCancelCreditMemo((CreditMemoDocument) apDocument);
0199:                } else {
0200:                    // doc not found
0201:                }
0202:            }
0203:
0204:            /**
0205:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesCreatePaymentRequest(org.kuali.module.purap.document.PaymentRequestDocument)
0206:             */
0207:            public void generateEntriesCreatePaymentRequest(
0208:                    PaymentRequestDocument preq) {
0209:                LOG.debug("generateEntriesCreatePaymentRequest() started");
0210:                List encumbrances = relieveEncumbrance(preq);
0211:                List accountingLines = purapAccountingService
0212:                        .generateSummaryWithNoZeroTotals(preq.getItems());
0213:                generateEntriesPaymentRequest(preq, encumbrances,
0214:                        accountingLines, CREATE_PAYMENT_REQUEST);
0215:            }
0216:
0217:            /**
0218:             * Called from generateEntriesCancelAccountsPayableDocument() for Payment Request Document
0219:             * 
0220:             * @param preq Payment Request document to cancel
0221:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesCancelAccountsPayableDocument(org.kuali.module.purap.document.AccountsPayableDocument)
0222:             */
0223:            private void generateEntriesCancelPaymentRequest(
0224:                    PaymentRequestDocument preq) {
0225:                LOG.debug("generateEntriesCreatePaymentRequest() started");
0226:                List encumbrances = reencumberEncumbrance(preq);
0227:                List accountingLines = purapAccountingService
0228:                        .generateSummaryWithNoZeroTotals(preq.getItems());
0229:                generateEntriesPaymentRequest(preq, encumbrances,
0230:                        accountingLines, CANCEL_PAYMENT_REQUEST);
0231:            }
0232:
0233:            /**
0234:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesModifyPaymentRequest(org.kuali.module.purap.document.PaymentRequestDocument)
0235:             */
0236:            public void generateEntriesModifyPaymentRequest(
0237:                    PaymentRequestDocument preq) {
0238:                LOG.debug("generateEntriesModifyPaymentRequest() started");
0239:
0240:                Map actualsPositive = new HashMap();
0241:                List<SourceAccountingLine> newAccountingLines = purapAccountingService
0242:                        .generateSummaryWithNoZeroTotals(preq.getItems());
0243:                for (SourceAccountingLine newAccount : newAccountingLines) {
0244:                    actualsPositive.put(newAccount, newAccount.getAmount());
0245:                    LOG
0246:                            .debug("generateEntriesModifyPaymentRequest() actualsPositive: "
0247:                                    + newAccount.getAccountNumber()
0248:                                    + " = "
0249:                                    + newAccount.getAmount());
0250:                }
0251:
0252:                Map actualsNegative = new HashMap();
0253:                List<PaymentRequestSummaryAccount> oldAccountingLines = getPaymentRequestSummaryAccounts(preq
0254:                        .getPurapDocumentIdentifier());
0255:
0256:                for (PaymentRequestSummaryAccount oldAccount : oldAccountingLines) {
0257:                    actualsNegative.put(oldAccount
0258:                            .generateSourceAccountingLine(), oldAccount
0259:                            .getAmount());
0260:                    LOG
0261:                            .debug("generateEntriesModifyPaymentRequest() actualsNegative: "
0262:                                    + oldAccount.getAccountNumber()
0263:                                    + " = "
0264:                                    + oldAccount.getAmount());
0265:                }
0266:
0267:                // Add the positive entries and subtract the negative entries
0268:                Map glEntries = new HashMap();
0269:
0270:                // Combine the two maps (copy all the positive entries)
0271:                LOG
0272:                        .debug("generateEntriesModifyPaymentRequest() Combine positive/negative entries");
0273:                glEntries.putAll(actualsPositive);
0274:
0275:                for (Iterator iter = actualsNegative.keySet().iterator(); iter
0276:                        .hasNext();) {
0277:                    SourceAccountingLine key = (SourceAccountingLine) iter
0278:                            .next();
0279:
0280:                    KualiDecimal amt;
0281:                    if (glEntries.containsKey(key)) {
0282:                        amt = (KualiDecimal) glEntries.get(key);
0283:                        amt = amt.subtract((KualiDecimal) actualsNegative
0284:                                .get(key));
0285:                    } else {
0286:                        amt = ZERO;
0287:                        amt = amt.subtract((KualiDecimal) actualsNegative
0288:                                .get(key));
0289:                    }
0290:                    glEntries.put(key, amt);
0291:                }
0292:
0293:                List<SourceAccountingLine> accounts = new ArrayList();
0294:                for (Iterator iter = glEntries.keySet().iterator(); iter
0295:                        .hasNext();) {
0296:                    SourceAccountingLine account = (SourceAccountingLine) iter
0297:                            .next();
0298:                    KualiDecimal amount = (KualiDecimal) glEntries.get(account);
0299:                    if (ZERO.compareTo(amount) != 0) {
0300:                        account.setAmount(amount);
0301:                        accounts.add(account);
0302:                    }
0303:                }
0304:
0305:                LOG
0306:                        .debug("generateEntriesModifyPaymentRequest() Generate GL entries");
0307:                generateEntriesPaymentRequest(preq, null, accounts,
0308:                        MODIFY_PAYMENT_REQUEST);
0309:            }
0310:
0311:            /**
0312:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesCreateCreditMemo(org.kuali.module.purap.document.CreditMemoDocument)
0313:             */
0314:            public void generateEntriesCreateCreditMemo(CreditMemoDocument cm) {
0315:                LOG.debug("generateEntriesCreateCreditMemo() started");
0316:                generateEntriesCreditMemo(cm, CREATE_CREDIT_MEMO);
0317:            }
0318:
0319:            /**
0320:             * Called from generateEntriesCancelAccountsPayableDocument() for Payment Request Document
0321:             * 
0322:             * @param preq Payment Request document to cancel
0323:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesCancelAccountsPayableDocument(org.kuali.module.purap.document.AccountsPayableDocument)
0324:             */
0325:            private void generateEntriesCancelCreditMemo(CreditMemoDocument cm) {
0326:                LOG.debug("generateEntriesCancelCreditMemo() started");
0327:                generateEntriesCreditMemo(cm, CANCEL_CREDIT_MEMO);
0328:            }
0329:
0330:            /**
0331:             * Retrieves the next available sequence number from the general ledger pending entry table for this document
0332:             * 
0333:             * @param documentNumber Document number to find next sequence number
0334:             * @return Next available sequence number
0335:             */
0336:            private int getNextAvailableSequence(String documentNumber) {
0337:                LOG.debug("getNextAvailableSequence() started");
0338:                Map fieldValues = new HashMap();
0339:                fieldValues.put("financialSystemOriginationCode",
0340:                        PURAP_ORIGIN_CODE);
0341:                fieldValues.put("documentNumber", documentNumber);
0342:                int count = businessObjectService.countMatching(
0343:                        GeneralLedgerPendingEntry.class, fieldValues);
0344:                return count + 1;
0345:            }
0346:
0347:            /**
0348:             * Creates the general ledger entries for Payment Request actions.
0349:             * 
0350:             * @param preq Payment Request document to create entries
0351:             * @param encumbrances List of encumbrance accounts if applies
0352:             * @param accountingLines List of preq accounts to create entries
0353:             * @param processType Type of process (create, modify, cancel)
0354:             * @return Boolean returned indicating whether entry creation succeeded
0355:             */
0356:            private boolean generateEntriesPaymentRequest(
0357:                    PaymentRequestDocument preq, List encumbrances,
0358:                    List accountingLines, String processType) {
0359:                LOG.debug("generateEntriesPaymentRequest() started");
0360:                boolean success = true;
0361:                preq.setGeneralLedgerPendingEntries(new ArrayList());
0362:
0363:                /*
0364:                 * Can't let generalLedgerPendingEntryService just create all the entries because we need the sequenceHelper to carry over
0365:                 * from the encumbrances to the actuals and also because we need to tell the PaymentRequestDocumentRule customize entry
0366:                 * method how to customize differently based on if creating an encumbrance or actual.
0367:                 */
0368:                GeneralLedgerPendingEntrySequenceHelper sequenceHelper = new GeneralLedgerPendingEntrySequenceHelper(
0369:                        getNextAvailableSequence(preq.getDocumentNumber()));
0370:
0371:                if (encumbrances != null) {
0372:                    LOG
0373:                            .debug("generateEntriesPaymentRequest() generate encumbrance entries");
0374:                    if (CREATE_PAYMENT_REQUEST.equals(processType)) {
0375:                        // on create, use CREDIT code for encumbrances
0376:                        preq.setDebitCreditCodeForGLEntries(GL_CREDIT_CODE);
0377:                    } else if (CANCEL_PAYMENT_REQUEST.equals(processType)) {
0378:                        // on cancel, use DEBIT code
0379:                        preq.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
0380:                    } else if (MODIFY_PAYMENT_REQUEST.equals(processType)) {
0381:                        // no encumbrances for modify
0382:                    }
0383:
0384:                    preq.setGenerateEncumbranceEntries(true);
0385:                    for (Iterator iter = encumbrances.iterator(); iter
0386:                            .hasNext();) {
0387:                        AccountingLine accountingLine = (AccountingLine) iter
0388:                                .next();
0389:                        GenerateGeneralLedgerPendingEntriesEvent glEvent = new GenerateGeneralLedgerPendingEntriesEvent(
0390:                                preq, accountingLine, sequenceHelper);
0391:                        success &= kualiRuleService.applyRules(glEvent);
0392:                        sequenceHelper.increment(); // increment for the next line
0393:                    }
0394:                }
0395:
0396:                if (ObjectUtils.isNotNull(accountingLines)
0397:                        && !accountingLines.isEmpty()) {
0398:                    LOG
0399:                            .debug("generateEntriesPaymentRequest() now book the actuals");
0400:                    preq.setGenerateEncumbranceEntries(false);
0401:
0402:                    if (CREATE_PAYMENT_REQUEST.equals(processType)
0403:                            || MODIFY_PAYMENT_REQUEST.equals(processType)) {
0404:                        // on create and modify, use DEBIT code
0405:                        preq.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
0406:                    } else if (CANCEL_PAYMENT_REQUEST.equals(processType)) {
0407:                        // on cancel, use CREDIT code
0408:                        preq.setDebitCreditCodeForGLEntries(GL_CREDIT_CODE);
0409:                    }
0410:
0411:                    for (Iterator iter = accountingLines.iterator(); iter
0412:                            .hasNext();) {
0413:                        AccountingLine accountingLine = (AccountingLine) iter
0414:                                .next();
0415:                        GenerateGeneralLedgerPendingEntriesEvent glEvent = new GenerateGeneralLedgerPendingEntriesEvent(
0416:                                preq, accountingLine, sequenceHelper);
0417:                        success &= kualiRuleService.applyRules(glEvent);
0418:                        sequenceHelper.increment(); // increment for the next line
0419:                    }
0420:
0421:                    // Manually save summary accounts
0422:                    savePaymentRequestSummaryAccounts(accountingLines, preq
0423:                            .getPurapDocumentIdentifier());
0424:                }
0425:
0426:                // Manually save GL entries for Payment Request and encumbrances
0427:                saveGLEntries(preq.getGeneralLedgerPendingEntries());
0428:
0429:                return success;
0430:            }
0431:
0432:            /**
0433:             * Creates the general ledger entries for Credit Memo actions.
0434:             * 
0435:             * @param cm Credit Memo document to create entries
0436:             * @param isCancel Indicates if request is a cancel or create
0437:             * @return Boolean returned indicating whether entry creation succeeded
0438:             */
0439:            private boolean generateEntriesCreditMemo(CreditMemoDocument cm,
0440:                    boolean isCancel) {
0441:                LOG.debug("generateEntriesCreditMemo() started");
0442:
0443:                cm.setGeneralLedgerPendingEntries(new ArrayList());
0444:
0445:                boolean success = true;
0446:                GeneralLedgerPendingEntrySequenceHelper sequenceHelper = new GeneralLedgerPendingEntrySequenceHelper(
0447:                        getNextAvailableSequence(cm.getDocumentNumber()));
0448:
0449:                if (!cm.isSourceVendor()) {
0450:                    LOG
0451:                            .debug("generateEntriesCreditMemo() create encumbrance entries for CM against a PO or PREQ (not vendor)");
0452:                    PurchaseOrderDocument po = null;
0453:                    if (cm.isSourceDocumentPurchaseOrder()) {
0454:                        LOG.debug("generateEntriesCreditMemo() PO type");
0455:                        po = purchaseOrderService.getCurrentPurchaseOrder(cm
0456:                                .getPurchaseOrderIdentifier());
0457:                    } else if (cm.isSourceDocumentPaymentRequest()) {
0458:                        LOG.debug("generateEntriesCreditMemo() PREQ type");
0459:                        po = purchaseOrderService.getCurrentPurchaseOrder(cm
0460:                                .getPaymentRequestDocument()
0461:                                .getPurchaseOrderIdentifier());
0462:                    }
0463:
0464:                    List encumbrances = getCreditMemoEncumbrance(cm, po,
0465:                            isCancel);
0466:                    if (encumbrances != null) {
0467:                        cm.setGenerateEncumbranceEntries(true);
0468:
0469:                        // even if generating encumbrance entries on cancel, call is the same because the method gets negative amounts from
0470:                        // the map so Debits on negatives = a credit
0471:                        cm.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
0472:
0473:                        for (Iterator iter = encumbrances.iterator(); iter
0474:                                .hasNext();) {
0475:                            AccountingLine accountingLine = (AccountingLine) iter
0476:                                    .next();
0477:                            if (accountingLine.getAmount().compareTo(ZERO) != 0) {
0478:                                GenerateGeneralLedgerPendingEntriesEvent glEvent = new GenerateGeneralLedgerPendingEntriesEvent(
0479:                                        cm, accountingLine, sequenceHelper);
0480:                                success &= kualiRuleService.applyRules(glEvent);
0481:                                sequenceHelper.increment(); // increment for the next line
0482:                            }
0483:                        }
0484:                    }
0485:                }
0486:
0487:                List<SourceAccountingLine> accountingLines = purapAccountingService
0488:                        .generateSummaryWithNoZeroTotals(cm.getItems());
0489:                if (accountingLines != null) {
0490:                    LOG
0491:                            .debug("generateEntriesCreditMemo() now book the actuals");
0492:                    cm.setGenerateEncumbranceEntries(false);
0493:
0494:                    if (!isCancel) {
0495:                        // on create, use CREDIT code
0496:                        cm.setDebitCreditCodeForGLEntries(GL_CREDIT_CODE);
0497:                    } else {
0498:                        // on cancel, use DEBIT code
0499:                        cm.setDebitCreditCodeForGLEntries(GL_DEBIT_CODE);
0500:                    }
0501:
0502:                    for (Iterator iter = accountingLines.iterator(); iter
0503:                            .hasNext();) {
0504:                        AccountingLine accountingLine = (AccountingLine) iter
0505:                                .next();
0506:                        GenerateGeneralLedgerPendingEntriesEvent glEvent = new GenerateGeneralLedgerPendingEntriesEvent(
0507:                                cm, accountingLine, sequenceHelper);
0508:                        success &= kualiRuleService.applyRules(glEvent);
0509:                        sequenceHelper.increment(); // increment for the next line
0510:                    }
0511:                }
0512:
0513:                saveGLEntries(cm.getGeneralLedgerPendingEntries());
0514:
0515:                LOG.debug("generateEntriesCreditMemo() ended");
0516:                return success;
0517:            }
0518:
0519:            /**
0520:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesApproveAmendPurchaseOrder(org.kuali.module.purap.document.PurchaseOrderDocument)
0521:             */
0522:            public void generateEntriesApproveAmendPurchaseOrder(
0523:                    PurchaseOrderDocument po) {
0524:                LOG.debug("generateEntriesApproveAmendPurchaseOrder() started");
0525:
0526:                // Set outstanding encumbered quantity/amount on items
0527:                for (Iterator items = po.getItems().iterator(); items.hasNext();) {
0528:                    PurchaseOrderItem item = (PurchaseOrderItem) items.next();
0529:
0530:                    // if invoice fields are null (as would be for new items), set fields to zero
0531:                    item.setItemInvoicedTotalAmount(item
0532:                            .getItemInvoicedTotalAmount() == null ? ZERO : item
0533:                            .getItemInvoicedTotalAmount());
0534:                    item.setItemInvoicedTotalQuantity(item
0535:                            .getItemInvoicedTotalQuantity() == null ? ZERO
0536:                            : item.getItemInvoicedTotalQuantity());
0537:
0538:                    if (!item.isItemActiveIndicator()) {
0539:                        // set outstanding encumbrance amounts to zero for inactive items
0540:                        item.setItemOutstandingEncumberedQuantity(ZERO);
0541:                        item.setItemOutstandingEncumberedAmount(ZERO);
0542:
0543:                        for (Iterator iter = item.getSourceAccountingLines()
0544:                                .iterator(); iter.hasNext();) {
0545:                            PurchaseOrderAccount account = (PurchaseOrderAccount) iter
0546:                                    .next();
0547:                            account
0548:                                    .setItemAccountOutstandingEncumbranceAmount(ZERO);
0549:                            account.setAlternateAmountForGLEntryCreation(ZERO);
0550:                        }
0551:                    } else {
0552:                        // Set quantities
0553:                        if (item.getItemQuantity() != null) {
0554:                            item
0555:                                    .setItemOutstandingEncumberedQuantity(item
0556:                                            .getItemQuantity()
0557:                                            .subtract(
0558:                                                    item
0559:                                                            .getItemInvoicedTotalQuantity()));
0560:                        } else {
0561:                            // if order qty is null, outstanding encumbered qty should be null
0562:                            item.setItemOutstandingEncumberedQuantity(null);
0563:                        }
0564:
0565:                        // Set amount
0566:                        if (item.getItemOutstandingEncumberedQuantity() != null) {
0567:                            item.setItemOutstandingEncumberedAmount(item
0568:                                    .getItemOutstandingEncumberedQuantity()
0569:                                    .multiply(
0570:                                            new KualiDecimal(item
0571:                                                    .getItemUnitPrice())));
0572:                        } else {
0573:                            if (item.getItemUnitPrice() != null) {
0574:                                item
0575:                                        .setItemOutstandingEncumberedAmount(new KualiDecimal(
0576:                                                item
0577:                                                        .getItemUnitPrice()
0578:                                                        .subtract(
0579:                                                                item
0580:                                                                        .getItemInvoicedTotalAmount()
0581:                                                                        .bigDecimalValue())));
0582:                            }
0583:                        }
0584:
0585:                        for (Iterator iter = item.getSourceAccountingLines()
0586:                                .iterator(); iter.hasNext();) {
0587:                            PurchaseOrderAccount account = (PurchaseOrderAccount) iter
0588:                                    .next();
0589:                            BigDecimal percent = new BigDecimal(account
0590:                                    .getAccountLinePercent().toString());
0591:                            percent = percent.divide(new BigDecimal("100"), 3,
0592:                                    BigDecimal.ROUND_HALF_UP);
0593:                            account
0594:                                    .setItemAccountOutstandingEncumbranceAmount(item
0595:                                            .getItemOutstandingEncumberedAmount()
0596:                                            .multiply(new KualiDecimal(percent)));
0597:                            account
0598:                                    .setAlternateAmountForGLEntryCreation(account
0599:                                            .getItemAccountOutstandingEncumbranceAmount());
0600:                        }
0601:                    }
0602:                }
0603:
0604:                PurchaseOrderDocument oldPO = SpringContext.getBean(
0605:                        PurchaseOrderService.class).getCurrentPurchaseOrder(
0606:                        po.getPurapDocumentIdentifier());
0607:
0608:                if (oldPO == null) {
0609:                    throw new IllegalArgumentException(
0610:                            "Current Purchase Order not found - poId = "
0611:                                    + oldPO.getPurapDocumentIdentifier());
0612:                }
0613:
0614:                List newAccounts = SpringContext.getBean(
0615:                        PurapAccountingService.class)
0616:                        .generateSummaryWithNoZeroTotalsUsingAlternateAmount(
0617:                                po.getItemsActiveOnly());
0618:                List oldAccounts = SpringContext.getBean(
0619:                        PurapAccountingService.class)
0620:                        .generateSummaryWithNoZeroTotalsUsingAlternateAmount(
0621:                                oldPO.getItemsActiveOnlySetupAlternateAmount());
0622:
0623:                Map combination = new HashMap();
0624:
0625:                // Add amounts from the new PO
0626:                for (Iterator iter = newAccounts.iterator(); iter.hasNext();) {
0627:                    SourceAccountingLine newAccount = (SourceAccountingLine) iter
0628:                            .next();
0629:                    combination.put(newAccount, newAccount.getAmount());
0630:                }
0631:
0632:                LOG
0633:                        .info("generateEntriesApproveAmendPurchaseOrder() combination after the add");
0634:                for (Iterator iter = combination.keySet().iterator(); iter
0635:                        .hasNext();) {
0636:                    SourceAccountingLine element = (SourceAccountingLine) iter
0637:                            .next();
0638:                    LOG.info("generateEntriesApproveAmendPurchaseOrder() "
0639:                            + element
0640:                            + " = "
0641:                            + ((KualiDecimal) combination.get(element))
0642:                                    .floatValue());
0643:                }
0644:
0645:                // Subtract the amounts from the old PO
0646:                for (Iterator iter = oldAccounts.iterator(); iter.hasNext();) {
0647:                    SourceAccountingLine oldAccount = (SourceAccountingLine) iter
0648:                            .next();
0649:                    if (combination.containsKey(oldAccount)) {
0650:                        KualiDecimal amount = (KualiDecimal) combination
0651:                                .get(oldAccount);
0652:                        amount = amount.subtract(oldAccount.getAmount());
0653:                        combination.put(oldAccount, amount);
0654:                    } else {
0655:                        combination.put(oldAccount, ZERO.subtract(oldAccount
0656:                                .getAmount()));
0657:                    }
0658:                }
0659:
0660:                LOG
0661:                        .debug("generateEntriesApproveAmendPurchaseOrder() combination after the subtract");
0662:                for (Iterator iter = combination.keySet().iterator(); iter
0663:                        .hasNext();) {
0664:                    SourceAccountingLine element = (SourceAccountingLine) iter
0665:                            .next();
0666:                    LOG.info("generateEntriesApproveAmendPurchaseOrder() "
0667:                            + element
0668:                            + " = "
0669:                            + ((KualiDecimal) combination.get(element))
0670:                                    .floatValue());
0671:                }
0672:
0673:                List<SourceAccountingLine> encumbranceAccounts = new ArrayList();
0674:                for (Iterator iter = combination.keySet().iterator(); iter
0675:                        .hasNext();) {
0676:                    SourceAccountingLine account = (SourceAccountingLine) iter
0677:                            .next();
0678:                    KualiDecimal amount = (KualiDecimal) combination
0679:                            .get(account);
0680:                    if (ZERO.compareTo(amount) != 0) {
0681:                        account.setAmount(amount);
0682:                        encumbranceAccounts.add(account);
0683:                    }
0684:                }
0685:
0686:                po.setSourceAccountingLines(encumbranceAccounts);
0687:                generalLedgerPendingEntryService
0688:                        .generateGeneralLedgerPendingEntries(po);
0689:                saveGLEntries(po.getGeneralLedgerPendingEntries());
0690:                LOG
0691:                        .debug("generateEntriesApproveAmendPo() gl entries created; exit method");
0692:            }
0693:
0694:            /**
0695:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesClosePurchaseOrder(org.kuali.module.purap.document.PurchaseOrderDocument)
0696:             */
0697:            public void generateEntriesClosePurchaseOrder(
0698:                    PurchaseOrderDocument po) {
0699:                LOG.debug("generateEntriesClosePurchaseOrder() started");
0700:
0701:                // Set outstanding encumbered quantity/amount on items
0702:                for (Iterator items = po.getItems().iterator(); items.hasNext();) {
0703:                    PurchaseOrderItem item = (PurchaseOrderItem) items.next();
0704:
0705:                    String logItmNbr = "Item # " + item.getItemLineNumber();
0706:
0707:                    if (!item.isItemActiveIndicator()) {
0708:                        continue;
0709:                    }
0710:
0711:                    KualiDecimal itemAmount = null;
0712:                    if (!item.getItemType()
0713:                            .isQuantityBasedGeneralLedgerIndicator()) {
0714:                        LOG.debug("generateEntriesClosePurchaseOrder() "
0715:                                + logItmNbr + " Calculate based on amounts");
0716:                        itemAmount = item.getItemOutstandingEncumberedAmount() == null ? ZERO
0717:                                : item.getItemOutstandingEncumberedAmount();
0718:                    } else {
0719:                        LOG.debug("generateEntriesClosePurchaseOrder() "
0720:                                + logItmNbr + " Calculate based on quantities");
0721:                        itemAmount = item
0722:                                .getItemOutstandingEncumberedQuantity()
0723:                                .multiply(
0724:                                        new KualiDecimal(item
0725:                                                .getItemUnitPrice()));
0726:                    }
0727:
0728:                    KualiDecimal accountTotal = ZERO;
0729:                    PurchaseOrderAccount lastAccount = null;
0730:                    if (itemAmount.compareTo(ZERO) != 0) {
0731:                        // Sort accounts
0732:                        Collections
0733:                                .sort((List) item.getSourceAccountingLines());
0734:
0735:                        for (Iterator iterAcct = item
0736:                                .getSourceAccountingLines().iterator(); iterAcct
0737:                                .hasNext();) {
0738:                            PurchaseOrderAccount acct = (PurchaseOrderAccount) iterAcct
0739:                                    .next();
0740:                            if (!acct.isEmpty()) {
0741:                                KualiDecimal acctAmount = itemAmount.multiply(
0742:                                        new KualiDecimal(acct
0743:                                                .getAccountLinePercent()
0744:                                                .toString())).divide(
0745:                                        PurapConstants.HUNDRED);
0746:                                accountTotal = accountTotal.add(acctAmount);
0747:                                acct
0748:                                        .setAlternateAmountForGLEntryCreation(acctAmount);
0749:                                lastAccount = acct;
0750:                            }
0751:                        }
0752:
0753:                        // account for rounding by adjusting last account as needed
0754:                        if (lastAccount != null) {
0755:                            KualiDecimal difference = itemAmount
0756:                                    .subtract(accountTotal);
0757:                            LOG
0758:                                    .debug("generateEntriesClosePurchaseOrder() difference: "
0759:                                            + logItmNbr + " " + difference);
0760:
0761:                            KualiDecimal amount = lastAccount
0762:                                    .getAlternateAmountForGLEntryCreation();
0763:                            if (ObjectUtils.isNotNull(amount)) {
0764:                                lastAccount
0765:                                        .setAlternateAmountForGLEntryCreation(amount
0766:                                                .add(difference));
0767:                            } else {
0768:                                lastAccount
0769:                                        .setAlternateAmountForGLEntryCreation(difference);
0770:                            }
0771:                        }
0772:
0773:                    }
0774:                }// endfor
0775:
0776:                po.setSourceAccountingLines(purapAccountingService
0777:                        .generateSummaryWithNoZeroTotalsUsingAlternateAmount(po
0778:                                .getItemsActiveOnly()));
0779:                generalLedgerPendingEntryService
0780:                        .generateGeneralLedgerPendingEntries(po);
0781:                saveGLEntries(po.getGeneralLedgerPendingEntries());
0782:                LOG
0783:                        .debug("generateEntriesClosePurchaseOrder() gl entries created; exit method");
0784:            }
0785:
0786:            /**
0787:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesReopenPurchaseOrder(org.kuali.module.purap.document.PurchaseOrderDocument)
0788:             */
0789:            public void generateEntriesReopenPurchaseOrder(
0790:                    PurchaseOrderDocument po) {
0791:                LOG.debug("generateEntriesReopenPurchaseOrder() started");
0792:
0793:                // Set outstanding encumbered quantity/amount on items
0794:                for (Iterator items = po.getItems().iterator(); items.hasNext();) {
0795:                    PurchaseOrderItem item = (PurchaseOrderItem) items.next();
0796:
0797:                    String logItmNbr = "Item # " + item.getItemLineNumber();
0798:
0799:                    if (!item.isItemActiveIndicator()) {
0800:                        continue;
0801:                    }
0802:
0803:                    KualiDecimal itemAmount = null;
0804:                    if (!item.getItemType()
0805:                            .isQuantityBasedGeneralLedgerIndicator()) {
0806:                        LOG.debug("generateEntriesReopenPurchaseOrder() "
0807:                                + logItmNbr + " Calculate based on amounts");
0808:                        itemAmount = item.getItemOutstandingEncumberedAmount() == null ? ZERO
0809:                                : item.getItemOutstandingEncumberedAmount();
0810:                    } else {
0811:                        LOG.debug("generateEntriesReopenPurchaseOrder() "
0812:                                + logItmNbr + " Calculate based on quantities");
0813:                        itemAmount = item
0814:                                .getItemOutstandingEncumberedQuantity()
0815:                                .multiply(
0816:                                        new KualiDecimal(item
0817:                                                .getItemUnitPrice()));
0818:                    }
0819:
0820:                    KualiDecimal accountTotal = ZERO;
0821:                    PurchaseOrderAccount lastAccount = null;
0822:                    if (itemAmount.compareTo(ZERO) != 0) {
0823:                        // Sort accounts
0824:                        Collections
0825:                                .sort((List) item.getSourceAccountingLines());
0826:
0827:                        for (Iterator iterAcct = item
0828:                                .getSourceAccountingLines().iterator(); iterAcct
0829:                                .hasNext();) {
0830:                            PurchaseOrderAccount acct = (PurchaseOrderAccount) iterAcct
0831:                                    .next();
0832:                            if (!acct.isEmpty()) {
0833:                                KualiDecimal acctAmount = itemAmount.multiply(
0834:                                        new KualiDecimal(acct
0835:                                                .getAccountLinePercent()
0836:                                                .toString())).divide(
0837:                                        PurapConstants.HUNDRED);
0838:                                accountTotal = accountTotal.add(acctAmount);
0839:                                acct
0840:                                        .setAlternateAmountForGLEntryCreation(acctAmount);
0841:                                lastAccount = acct;
0842:                            }
0843:                        }
0844:
0845:                        // account for rounding by adjusting last account as needed
0846:                        if (lastAccount != null) {
0847:                            KualiDecimal difference = itemAmount
0848:                                    .subtract(accountTotal);
0849:                            LOG
0850:                                    .debug("generateEntriesReopenPurchaseOrder() difference: "
0851:                                            + logItmNbr + " " + difference);
0852:
0853:                            KualiDecimal amount = lastAccount
0854:                                    .getAlternateAmountForGLEntryCreation();
0855:                            if (ObjectUtils.isNotNull(amount)) {
0856:                                lastAccount
0857:                                        .setAlternateAmountForGLEntryCreation(amount
0858:                                                .add(difference));
0859:                            } else {
0860:                                lastAccount
0861:                                        .setAlternateAmountForGLEntryCreation(difference);
0862:                            }
0863:                        }
0864:
0865:                    }
0866:                }// endfor
0867:
0868:                po.setSourceAccountingLines(purapAccountingService
0869:                        .generateSummaryWithNoZeroTotalsUsingAlternateAmount(po
0870:                                .getItemsActiveOnly()));
0871:                generalLedgerPendingEntryService
0872:                        .generateGeneralLedgerPendingEntries(po);
0873:                saveGLEntries(po.getGeneralLedgerPendingEntries());
0874:                LOG
0875:                        .debug("generateEntriesReopenPurchaseOrder() gl entries created; exit method");
0876:            }
0877:
0878:            /**
0879:             * @see org.kuali.module.purap.service.PurapGeneralLedgerService#generateEntriesVoidPurchaseOrder(org.kuali.module.purap.document.PurchaseOrderDocument)
0880:             */
0881:            public void generateEntriesVoidPurchaseOrder(
0882:                    PurchaseOrderDocument po) {
0883:                LOG.debug("generateEntriesVoidPurchaseOrder() started");
0884:
0885:                // Set outstanding encumbered quantity/amount on items
0886:                for (Iterator items = po.getItems().iterator(); items.hasNext();) {
0887:                    PurchaseOrderItem item = (PurchaseOrderItem) items.next();
0888:
0889:                    String logItmNbr = "Item # " + item.getItemLineNumber();
0890:
0891:                    if (!item.isItemActiveIndicator()) {
0892:                        continue;
0893:                    }
0894:
0895:                    KualiDecimal itemAmount = null;
0896:                    if (!item.getItemType()
0897:                            .isQuantityBasedGeneralLedgerIndicator()) {
0898:                        LOG.debug("generateEntriesVoidPurchaseOrder() "
0899:                                + logItmNbr + " Calculate based on amounts");
0900:                        itemAmount = item.getItemOutstandingEncumberedAmount() == null ? ZERO
0901:                                : item.getItemOutstandingEncumberedAmount();
0902:                    } else {
0903:                        LOG.debug("generateEntriesVoidPurchaseOrder() "
0904:                                + logItmNbr + " Calculate based on quantities");
0905:                        itemAmount = item
0906:                                .getItemOutstandingEncumberedQuantity()
0907:                                .multiply(
0908:                                        new KualiDecimal(item
0909:                                                .getItemUnitPrice()));
0910:                    }
0911:
0912:                    KualiDecimal accountTotal = ZERO;
0913:                    PurchaseOrderAccount lastAccount = null;
0914:                    if (itemAmount.compareTo(ZERO) != 0) {
0915:                        // Sort accounts
0916:                        Collections
0917:                                .sort((List) item.getSourceAccountingLines());
0918:
0919:                        for (Iterator iterAcct = item
0920:                                .getSourceAccountingLines().iterator(); iterAcct
0921:                                .hasNext();) {
0922:                            PurchaseOrderAccount acct = (PurchaseOrderAccount) iterAcct
0923:                                    .next();
0924:                            if (!acct.isEmpty()) {
0925:                                KualiDecimal acctAmount = itemAmount.multiply(
0926:                                        new KualiDecimal(acct
0927:                                                .getAccountLinePercent()
0928:                                                .toString())).divide(
0929:                                        PurapConstants.HUNDRED);
0930:                                accountTotal = accountTotal.add(acctAmount);
0931:                                acct
0932:                                        .setAlternateAmountForGLEntryCreation(acctAmount);
0933:                                lastAccount = acct;
0934:                            }
0935:                        }
0936:
0937:                        // account for rounding by adjusting last account as needed
0938:                        if (lastAccount != null) {
0939:                            KualiDecimal difference = itemAmount
0940:                                    .subtract(accountTotal);
0941:                            LOG
0942:                                    .debug("generateEntriesVoidPurchaseOrder() difference: "
0943:                                            + logItmNbr + " " + difference);
0944:
0945:                            KualiDecimal amount = lastAccount
0946:                                    .getAlternateAmountForGLEntryCreation();
0947:                            if (ObjectUtils.isNotNull(amount)) {
0948:                                lastAccount
0949:                                        .setAlternateAmountForGLEntryCreation(amount
0950:                                                .add(difference));
0951:                            } else {
0952:                                lastAccount
0953:                                        .setAlternateAmountForGLEntryCreation(difference);
0954:                            }
0955:                        }
0956:
0957:                    }
0958:                }// endfor
0959:
0960:                po.setSourceAccountingLines(purapAccountingService
0961:                        .generateSummaryWithNoZeroTotalsUsingAlternateAmount(po
0962:                                .getItemsActiveOnly()));
0963:                generalLedgerPendingEntryService
0964:                        .generateGeneralLedgerPendingEntries(po);
0965:                saveGLEntries(po.getGeneralLedgerPendingEntries());
0966:                LOG
0967:                        .debug("generateEntriesVoidPurchaseOrder() gl entries created; exit method");
0968:            }
0969:
0970:            /**
0971:             * Relieve the Encumbrance on a PO based on values in a PREQ. This is to be called when a PREQ is created. Note: This modifies
0972:             * the encumbrance values on the PO and saves the PO
0973:             * 
0974:             * @param preq PREQ for invoice
0975:             * @return List of accounting lines to use to create the pending general ledger entries
0976:             */
0977:            private List<SourceAccountingLine> relieveEncumbrance(
0978:                    PaymentRequestDocument preq) {
0979:                LOG.debug("relieveEncumbrance() started");
0980:
0981:                Map encumbranceAccountMap = new HashMap();
0982:                PurchaseOrderDocument po = purchaseOrderService
0983:                        .getCurrentPurchaseOrder(preq
0984:                                .getPurchaseOrderIdentifier());
0985:
0986:                // Get each item one by one
0987:                for (Iterator items = preq.getItems().iterator(); items
0988:                        .hasNext();) {
0989:                    PaymentRequestItem preqItem = (PaymentRequestItem) items
0990:                            .next();
0991:                    PurchaseOrderItem poItem = getPoItem(po, preqItem
0992:                            .getItemLineNumber(), preqItem.getItemType());
0993:
0994:                    boolean takeAll = false; // Set this true if we relieve the entire encumbrance
0995:                    KualiDecimal itemDisEncumber = null; // Amount to disencumber for this item
0996:
0997:                    String logItmNbr = "Item # " + preqItem.getItemLineNumber();
0998:                    LOG.debug("relieveEncumbrance() " + logItmNbr);
0999:
1000:                    // If there isn't a PO item or the extended price is 0, we don't need encumbrances
1001:                    if (poItem == null) {
1002:                        LOG
1003:                                .debug("relieveEncumbrance() "
1004:                                        + logItmNbr
1005:                                        + " No encumbrances required because po item is null");
1006:                    } else if (ZERO.compareTo(preqItem.getExtendedPrice()) == 0) {
1007:                        /*
1008:                         * This is a specialized case where PREQ item being processed must adjust the PO item's outstanding encumbered
1009:                         * quantity. This kind of scenario is mostly seen on warranty type items. The following must be true to do this:
1010:                         * PREQ item Extended Price must be ZERO, PREQ item invoice quantity must be not empty and not ZERO, and PO item is
1011:                         * quantity based PO item unit cost is ZERO
1012:                         */
1013:                        LOG
1014:                                .debug("relieveEncumbrance() "
1015:                                        + logItmNbr
1016:                                        + " No GL encumbrances required because extended price is ZERO");
1017:                        if ((poItem.getItemQuantity() != null)
1018:                                && ((BigDecimal.ZERO.compareTo(poItem
1019:                                        .getItemUnitPrice())) == 0)) {
1020:                            // po has order quantity and unit price is ZERO... reduce outstanding encumbered quantity
1021:                            LOG.debug("relieveEncumbrance() " + logItmNbr
1022:                                    + " Calculate po oustanding encumbrance");
1023:
1024:                            // Do encumbrance calculations based on quantity
1025:                            if ((preqItem.getItemQuantity() != null)
1026:                                    && ((ZERO.compareTo(preqItem
1027:                                            .getItemQuantity())) != 0)) {
1028:                                KualiDecimal invoiceQuantity = preqItem
1029:                                        .getItemQuantity();
1030:                                KualiDecimal outstandingEncumberedQuantity = poItem
1031:                                        .getItemOutstandingEncumberedQuantity() == null ? ZERO
1032:                                        : poItem
1033:                                                .getItemOutstandingEncumberedQuantity();
1034:
1035:                                KualiDecimal encumbranceQuantity;
1036:                                if (invoiceQuantity
1037:                                        .compareTo(outstandingEncumberedQuantity) > 0) {
1038:                                    // We bought more than the quantity on the PO
1039:                                    LOG
1040:                                            .debug("relieveEncumbrance() "
1041:                                                    + logItmNbr
1042:                                                    + " we bought more than the qty on the PO");
1043:                                    encumbranceQuantity = outstandingEncumberedQuantity;
1044:                                    poItem
1045:                                            .setItemOutstandingEncumberedQuantity(ZERO);
1046:                                } else {
1047:                                    encumbranceQuantity = invoiceQuantity;
1048:                                    poItem
1049:                                            .setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity
1050:                                                    .subtract(encumbranceQuantity));
1051:                                    LOG
1052:                                            .debug("relieveEncumbrance() "
1053:                                                    + logItmNbr
1054:                                                    + " adjusting oustanding encunbrance qty - encumbranceQty "
1055:                                                    + encumbranceQuantity
1056:                                                    + " outstandingEncumberedQty "
1057:                                                    + poItem
1058:                                                            .getItemOutstandingEncumberedQuantity());
1059:                                }
1060:
1061:                                if (poItem.getItemInvoicedTotalQuantity() == null) {
1062:                                    poItem
1063:                                            .setItemInvoicedTotalQuantity(invoiceQuantity);
1064:                                } else {
1065:                                    poItem.setItemInvoicedTotalQuantity(poItem
1066:                                            .getItemInvoicedTotalQuantity()
1067:                                            .add(invoiceQuantity));
1068:                                }
1069:                            }
1070:                        }
1071:
1072:                    } else {
1073:                        LOG.debug("relieveEncumbrance() " + logItmNbr
1074:                                + " Calculate encumbrance GL entries");
1075:
1076:                        // Do we calculate the encumbrance amount based on quantity or amount?
1077:                        if (poItem.getItemType()
1078:                                .isQuantityBasedGeneralLedgerIndicator()) {
1079:                            LOG
1080:                                    .debug("relieveEncumbrance() "
1081:                                            + logItmNbr
1082:                                            + " Calculate encumbrance based on quantity");
1083:
1084:                            // Do encumbrance calculations based on quantity
1085:                            KualiDecimal invoiceQuantity = preqItem
1086:                                    .getItemQuantity() == null ? ZERO
1087:                                    : preqItem.getItemQuantity();
1088:                            KualiDecimal outstandingEncumberedQuantity = poItem
1089:                                    .getItemOutstandingEncumberedQuantity() == null ? ZERO
1090:                                    : poItem
1091:                                            .getItemOutstandingEncumberedQuantity();
1092:
1093:                            KualiDecimal encumbranceQuantity;
1094:                            if (invoiceQuantity
1095:                                    .compareTo(outstandingEncumberedQuantity) > 0) {
1096:                                // We bought more than the quantity on the PO
1097:                                LOG
1098:                                        .debug("relieveEncumbrance() "
1099:                                                + logItmNbr
1100:                                                + " we bought more than the qty on the PO");
1101:                                encumbranceQuantity = outstandingEncumberedQuantity;
1102:                                poItem
1103:                                        .setItemOutstandingEncumberedQuantity(ZERO);
1104:                                takeAll = true;
1105:                            } else {
1106:                                encumbranceQuantity = invoiceQuantity;
1107:                                poItem
1108:                                        .setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity
1109:                                                .subtract(encumbranceQuantity));
1110:                                if (ZERO
1111:                                        .compareTo(poItem
1112:                                                .getItemOutstandingEncumberedQuantity()) == 0) {
1113:                                    takeAll = true;
1114:                                }
1115:                                LOG
1116:                                        .debug("relieveEncumbrance() "
1117:                                                + logItmNbr
1118:                                                + " encumbranceQty "
1119:                                                + encumbranceQuantity
1120:                                                + " outstandingEncumberedQty "
1121:                                                + poItem
1122:                                                        .getItemOutstandingEncumberedQuantity());
1123:                            }
1124:
1125:                            if (poItem.getItemInvoicedTotalQuantity() == null) {
1126:                                poItem
1127:                                        .setItemInvoicedTotalQuantity(invoiceQuantity);
1128:                            } else {
1129:                                poItem.setItemInvoicedTotalQuantity(poItem
1130:                                        .getItemInvoicedTotalQuantity().add(
1131:                                                invoiceQuantity));
1132:                            }
1133:
1134:                            itemDisEncumber = encumbranceQuantity
1135:                                    .multiply(new KualiDecimal(poItem
1136:                                            .getItemUnitPrice()));
1137:                        } else {
1138:                            LOG.debug("relieveEncumbrance() " + logItmNbr
1139:                                    + " Calculate encumbrance based on amount");
1140:
1141:                            // Do encumbrance calculations based on amount only
1142:                            if ((poItem.getItemOutstandingEncumberedAmount()
1143:                                    .bigDecimalValue().signum() == -1)
1144:                                    && (preqItem.getExtendedPrice()
1145:                                            .bigDecimalValue().signum() == -1)) {
1146:                                LOG
1147:                                        .debug("relieveEncumbrance() "
1148:                                                + logItmNbr
1149:                                                + " Outstanding Encumbered amount is negative: "
1150:                                                + poItem
1151:                                                        .getItemOutstandingEncumberedAmount());
1152:                                if (preqItem
1153:                                        .getExtendedPrice()
1154:                                        .compareTo(
1155:                                                poItem
1156:                                                        .getItemOutstandingEncumberedAmount()) >= 0) {
1157:                                    // extended price is equal to or greater than outstanding encumbered
1158:                                    itemDisEncumber = preqItem
1159:                                            .getExtendedPrice();
1160:                                } else {
1161:                                    // extended price is less than outstanding encumbered
1162:                                    takeAll = true;
1163:                                    itemDisEncumber = poItem
1164:                                            .getItemOutstandingEncumberedAmount();
1165:                                }
1166:                            } else {
1167:                                LOG
1168:                                        .debug("relieveEncumbrance() "
1169:                                                + logItmNbr
1170:                                                + " Outstanding Encumbered amount is positive or ZERO: "
1171:                                                + poItem
1172:                                                        .getItemOutstandingEncumberedAmount());
1173:                                if (poItem.getItemOutstandingEncumberedAmount()
1174:                                        .compareTo(preqItem.getExtendedPrice()) >= 0) {
1175:                                    // outstanding amount is equal to or greater than extended price
1176:                                    itemDisEncumber = preqItem
1177:                                            .getExtendedPrice();
1178:                                } else {
1179:                                    // outstanding amount is less than extended price
1180:                                    takeAll = true;
1181:                                    itemDisEncumber = poItem
1182:                                            .getItemOutstandingEncumberedAmount();
1183:                                }
1184:                            }
1185:                        }
1186:
1187:                        LOG.debug("relieveEncumbrance() " + logItmNbr
1188:                                + " Amount to disencumber: " + itemDisEncumber);
1189:
1190:                        KualiDecimal newOutstandingEncumberedAmount = poItem
1191:                                .getItemOutstandingEncumberedAmount().subtract(
1192:                                        itemDisEncumber);
1193:                        LOG.debug("relieveEncumbrance() " + logItmNbr
1194:                                + " New Outstanding Encumbered amount is : "
1195:                                + newOutstandingEncumberedAmount);
1196:                        poItem
1197:                                .setItemOutstandingEncumberedAmount(newOutstandingEncumberedAmount);
1198:
1199:                        KualiDecimal newInvoicedTotalAmount = poItem
1200:                                .getItemInvoicedTotalAmount().add(
1201:                                        preqItem.getExtendedPrice());
1202:                        LOG.debug("relieveEncumbrance() " + logItmNbr
1203:                                + " New Invoiced Total Amount is: "
1204:                                + newInvoicedTotalAmount);
1205:                        poItem
1206:                                .setItemInvoicedTotalAmount(newInvoicedTotalAmount);
1207:
1208:                        // Sort accounts
1209:                        Collections.sort((List) poItem
1210:                                .getSourceAccountingLines());
1211:
1212:                        // make the list of accounts for the disencumbrance entry
1213:                        PurchaseOrderAccount lastAccount = null;
1214:                        KualiDecimal accountTotal = ZERO;
1215:                        for (Iterator accountIter = poItem
1216:                                .getSourceAccountingLines().iterator(); accountIter
1217:                                .hasNext();) {
1218:                            PurchaseOrderAccount account = (PurchaseOrderAccount) accountIter
1219:                                    .next();
1220:                            if (!account.isEmpty()) {
1221:                                KualiDecimal encumbranceAmount = null;
1222:                                SourceAccountingLine acctString = account
1223:                                        .generateSourceAccountingLine();
1224:                                if (takeAll) {
1225:                                    // fully paid; remove remaining encumbrance
1226:                                    encumbranceAmount = account
1227:                                            .getItemAccountOutstandingEncumbranceAmount();
1228:                                    account
1229:                                            .setItemAccountOutstandingEncumbranceAmount(ZERO);
1230:                                    LOG.debug("relieveEncumbrance() "
1231:                                            + logItmNbr + " take all");
1232:                                } else {
1233:                                    // amount = item disencumber * account percent / 100
1234:                                    encumbranceAmount = itemDisEncumber
1235:                                            .multiply(
1236:                                                    new KualiDecimal(
1237:                                                            account
1238:                                                                    .getAccountLinePercent()
1239:                                                                    .toString()))
1240:                                            .divide(HUNDRED);
1241:
1242:                                    account
1243:                                            .setItemAccountOutstandingEncumbranceAmount(account
1244:                                                    .getItemAccountOutstandingEncumbranceAmount()
1245:                                                    .subtract(encumbranceAmount));
1246:
1247:                                    // For rounding check at the end
1248:                                    accountTotal = accountTotal
1249:                                            .add(encumbranceAmount);
1250:
1251:                                    // If we are zeroing out the encumbrance, we don't need to adjust for rounding
1252:                                    if (!takeAll) {
1253:                                        lastAccount = account;
1254:                                    }
1255:                                }
1256:
1257:                                LOG.debug("relieveEncumbrance() " + logItmNbr
1258:                                        + " " + acctString + " = "
1259:                                        + encumbranceAmount);
1260:                                if (ObjectUtils.isNull(encumbranceAccountMap
1261:                                        .get(acctString))) {
1262:                                    encumbranceAccountMap.put(acctString,
1263:                                            encumbranceAmount);
1264:                                } else {
1265:                                    KualiDecimal amt = (KualiDecimal) encumbranceAccountMap
1266:                                            .get(acctString);
1267:                                    encumbranceAccountMap.put(acctString, amt
1268:                                            .add(encumbranceAmount));
1269:                                }
1270:
1271:                            }
1272:                        }
1273:
1274:                        // account for rounding by adjusting last account as needed
1275:                        if (lastAccount != null) {
1276:                            KualiDecimal difference = itemDisEncumber
1277:                                    .subtract(accountTotal);
1278:                            LOG.debug("relieveEncumbrance() difference: "
1279:                                    + logItmNbr + " " + difference);
1280:
1281:                            SourceAccountingLine acctString = lastAccount
1282:                                    .generateSourceAccountingLine();
1283:                            KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1284:                                    .get(acctString);
1285:                            if (ObjectUtils.isNull(amount)) {
1286:                                encumbranceAccountMap.put(acctString,
1287:                                        difference);
1288:                            } else {
1289:                                encumbranceAccountMap.put(acctString, amount
1290:                                        .add(difference));
1291:                            }
1292:
1293:                            lastAccount
1294:                                    .setItemAccountOutstandingEncumbranceAmount(lastAccount
1295:                                            .getItemAccountOutstandingEncumbranceAmount()
1296:                                            .subtract(difference));
1297:                        }
1298:                    }
1299:                }// endfor
1300:
1301:                List<SourceAccountingLine> encumbranceAccounts = new ArrayList();
1302:                for (Iterator iter = encumbranceAccountMap.keySet().iterator(); iter
1303:                        .hasNext();) {
1304:                    SourceAccountingLine acctString = (SourceAccountingLine) iter
1305:                            .next();
1306:                    KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1307:                            .get(acctString);
1308:                    if (amount.doubleValue() != 0) {
1309:                        acctString.setAmount(amount);
1310:                        encumbranceAccounts.add(acctString);
1311:                    }
1312:                }
1313:
1314:                purchaseOrderService.saveDocumentNoValidation(po);
1315:
1316:                return encumbranceAccounts;
1317:            }
1318:
1319:            /**
1320:             * Re-encumber the Encumbrance on a PO based on values in a PREQ. This is used when a PREQ is cancelled. Note: This modifies the
1321:             * encumbrance values on the PO and saves the PO
1322:             * 
1323:             * @param preq PREQ for invoice
1324:             * @return List of accounting lines to use to create the pending general ledger entries
1325:             */
1326:            private List reencumberEncumbrance(PaymentRequestDocument preq) {
1327:                LOG.debug("reencumberEncumbrance() started");
1328:
1329:                PurchaseOrderDocument po = purchaseOrderService
1330:                        .getCurrentPurchaseOrder(preq
1331:                                .getPurchaseOrderIdentifier());
1332:                Map encumbranceAccountMap = new HashMap();
1333:
1334:                // Get each item one by one
1335:                for (Iterator items = preq.getItems().iterator(); items
1336:                        .hasNext();) {
1337:                    PaymentRequestItem payRequestItem = (PaymentRequestItem) items
1338:                            .next();
1339:                    PurchaseOrderItem poItem = getPoItem(po, payRequestItem
1340:                            .getItemLineNumber(), payRequestItem.getItemType());
1341:
1342:                    KualiDecimal itemReEncumber = null; // Amount to reencumber for this item
1343:
1344:                    String logItmNbr = "Item # "
1345:                            + payRequestItem.getItemLineNumber();
1346:                    LOG.debug("reencumberEncumbrance() " + logItmNbr);
1347:
1348:                    // If there isn't a PO item or the extended price is 0, we don't need encumbrances
1349:                    if ((poItem == null)
1350:                            || (payRequestItem.getExtendedPrice().doubleValue() == 0)) {
1351:                        LOG.debug("reencumberEncumbrance() " + logItmNbr
1352:                                + " No encumbrances required");
1353:                    } else {
1354:                        LOG.debug("reencumberEncumbrance() " + logItmNbr
1355:                                + " Calculate encumbrance GL entries");
1356:
1357:                        // Do we calculate the encumbrance amount based on quantity or amount?
1358:                        if (poItem.getItemType()
1359:                                .isQuantityBasedGeneralLedgerIndicator()) {
1360:                            LOG
1361:                                    .debug("reencumberEncumbrance() "
1362:                                            + logItmNbr
1363:                                            + " Calculate encumbrance based on quantity");
1364:
1365:                            // Do disencumbrance calculations based on quantity
1366:                            KualiDecimal preqQuantity = payRequestItem
1367:                                    .getItemQuantity() == null ? ZERO
1368:                                    : payRequestItem.getItemQuantity();
1369:                            KualiDecimal outstandingEncumberedQuantity = poItem
1370:                                    .getItemOutstandingEncumberedQuantity() == null ? ZERO
1371:                                    : poItem
1372:                                            .getItemOutstandingEncumberedQuantity();
1373:                            KualiDecimal invoicedTotal = poItem
1374:                                    .getItemInvoicedTotalQuantity() == null ? ZERO
1375:                                    : poItem.getItemInvoicedTotalQuantity();
1376:
1377:                            poItem.setItemInvoicedTotalQuantity(invoicedTotal
1378:                                    .subtract(preqQuantity));
1379:                            poItem
1380:                                    .setItemOutstandingEncumberedQuantity(outstandingEncumberedQuantity
1381:                                            .add(preqQuantity));
1382:
1383:                            itemReEncumber = preqQuantity
1384:                                    .multiply(new KualiDecimal(poItem
1385:                                            .getItemUnitPrice()));
1386:                        } else {
1387:                            LOG.debug("reencumberEncumbrance() " + logItmNbr
1388:                                    + " Calculate encumbrance based on amount");
1389:
1390:                            itemReEncumber = payRequestItem.getExtendedPrice();
1391:                            // if re-encumber amount is more than original PO ordered amount... do not exceed ordered amount
1392:                            // this prevents negative encumbrance
1393:                            if ((poItem.getExtendedPrice() != null)
1394:                                    && (poItem.getExtendedPrice()
1395:                                            .bigDecimalValue().signum() < 0)) {
1396:                                // po item extended cost is negative
1397:                                if ((poItem.getExtendedPrice()
1398:                                        .compareTo(itemReEncumber)) > 0) {
1399:                                    itemReEncumber = poItem.getExtendedPrice();
1400:                                }
1401:                            } else if ((poItem.getExtendedPrice() != null)
1402:                                    && (poItem.getExtendedPrice()
1403:                                            .bigDecimalValue().signum() >= 0)) {
1404:                                // po item extended cost is positive
1405:                                if ((poItem.getExtendedPrice()
1406:                                        .compareTo(itemReEncumber)) < 0) {
1407:                                    itemReEncumber = poItem.getExtendedPrice();
1408:                                }
1409:                            }
1410:                        }
1411:
1412:                        LOG.debug("reencumberEncumbrance() " + logItmNbr
1413:                                + " Amount to reencumber: " + itemReEncumber);
1414:
1415:                        KualiDecimal outstandingEncumberedAmount = poItem
1416:                                .getItemOutstandingEncumberedAmount() == null ? ZERO
1417:                                : poItem.getItemOutstandingEncumberedAmount();
1418:                        LOG
1419:                                .debug("reencumberEncumbrance() "
1420:                                        + logItmNbr
1421:                                        + " PO Item Outstanding Encumbrance Amount set to: "
1422:                                        + outstandingEncumberedAmount);
1423:                        KualiDecimal newOutstandingEncumberedAmount = outstandingEncumberedAmount
1424:                                .add(itemReEncumber);
1425:                        LOG
1426:                                .debug("reencumberEncumbrance() "
1427:                                        + logItmNbr
1428:                                        + " New PO Item Outstanding Encumbrance Amount to set: "
1429:                                        + newOutstandingEncumberedAmount);
1430:                        poItem
1431:                                .setItemOutstandingEncumberedAmount(newOutstandingEncumberedAmount);
1432:
1433:                        KualiDecimal invoicedTotalAmount = poItem
1434:                                .getItemInvoicedTotalAmount() == null ? ZERO
1435:                                : poItem.getItemInvoicedTotalAmount();
1436:                        LOG.debug("reencumberEncumbrance() " + logItmNbr
1437:                                + " PO Item Invoiced Total Amount set to: "
1438:                                + invoicedTotalAmount);
1439:                        KualiDecimal newInvoicedTotalAmount = invoicedTotalAmount
1440:                                .subtract(payRequestItem.getExtendedPrice());
1441:                        LOG.debug("reencumberEncumbrance() " + logItmNbr
1442:                                + " New PO Item Invoiced Total Amount to set: "
1443:                                + newInvoicedTotalAmount);
1444:                        poItem
1445:                                .setItemInvoicedTotalAmount(newInvoicedTotalAmount);
1446:
1447:                        // make the list of accounts for the reencumbrance entry
1448:                        PurchaseOrderAccount lastAccount = null;
1449:                        KualiDecimal accountTotal = ZERO;
1450:
1451:                        // Sort accounts
1452:                        Collections.sort((List) poItem
1453:                                .getSourceAccountingLines());
1454:
1455:                        for (Iterator accountIter = poItem
1456:                                .getSourceAccountingLines().iterator(); accountIter
1457:                                .hasNext();) {
1458:                            PurchaseOrderAccount account = (PurchaseOrderAccount) accountIter
1459:                                    .next();
1460:                            if (!account.isEmpty()) {
1461:                                SourceAccountingLine acctString = account
1462:                                        .generateSourceAccountingLine();
1463:
1464:                                // amount = item reencumber * account percent / 100
1465:                                KualiDecimal reencumbranceAmount = itemReEncumber
1466:                                        .multiply(
1467:                                                new KualiDecimal(
1468:                                                        account
1469:                                                                .getAccountLinePercent()
1470:                                                                .toString()))
1471:                                        .divide(HUNDRED);
1472:
1473:                                account
1474:                                        .setItemAccountOutstandingEncumbranceAmount(account
1475:                                                .getItemAccountOutstandingEncumbranceAmount()
1476:                                                .add(reencumbranceAmount));
1477:
1478:                                // For rounding check at the end
1479:                                accountTotal = accountTotal
1480:                                        .add(reencumbranceAmount);
1481:
1482:                                lastAccount = account;
1483:
1484:                                LOG.debug("reencumberEncumbrance() "
1485:                                        + logItmNbr + " " + acctString + " = "
1486:                                        + reencumbranceAmount);
1487:                                if (encumbranceAccountMap
1488:                                        .containsKey(acctString)) {
1489:                                    KualiDecimal currentAmount = (KualiDecimal) encumbranceAccountMap
1490:                                            .get(acctString);
1491:                                    encumbranceAccountMap.put(acctString,
1492:                                            reencumbranceAmount
1493:                                                    .add(currentAmount));
1494:                                } else {
1495:                                    encumbranceAccountMap.put(acctString,
1496:                                            reencumbranceAmount);
1497:                                }
1498:                            }
1499:                        }
1500:
1501:                        // account for rounding by adjusting last account as needed
1502:                        if (lastAccount != null) {
1503:                            KualiDecimal difference = itemReEncumber
1504:                                    .subtract(accountTotal);
1505:                            LOG.debug("reencumberEncumbrance() difference: "
1506:                                    + logItmNbr + " " + difference);
1507:
1508:                            SourceAccountingLine acctString = lastAccount
1509:                                    .generateSourceAccountingLine();
1510:                            KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1511:                                    .get(acctString);
1512:                            if (amount == null) {
1513:                                encumbranceAccountMap.put(acctString,
1514:                                        difference);
1515:                            } else {
1516:                                encumbranceAccountMap.put(acctString, amount
1517:                                        .add(difference));
1518:                            }
1519:                            lastAccount
1520:                                    .setItemAccountOutstandingEncumbranceAmount(lastAccount
1521:                                            .getItemAccountOutstandingEncumbranceAmount()
1522:                                            .add(difference));
1523:                        }
1524:                    }
1525:                }
1526:
1527:                purchaseOrderService.saveDocumentNoValidation(po);
1528:
1529:                List<SourceAccountingLine> encumbranceAccounts = new ArrayList();
1530:                for (Iterator iter = encumbranceAccountMap.keySet().iterator(); iter
1531:                        .hasNext();) {
1532:                    SourceAccountingLine acctString = (SourceAccountingLine) iter
1533:                            .next();
1534:                    KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1535:                            .get(acctString);
1536:                    if (amount.doubleValue() != 0) {
1537:                        acctString.setAmount(amount);
1538:                        encumbranceAccounts.add(acctString);
1539:                    }
1540:                }
1541:
1542:                return encumbranceAccounts;
1543:            }
1544:
1545:            /**
1546:             * Re-encumber the Encumbrance on a PO based on values in a PREQ. This is used when a PREQ is cancelled. Note: This modifies the
1547:             * encumbrance values on the PO and saves the PO
1548:             * 
1549:             * @param cm Credit Memo document
1550:             * @param po Purchase Order document modify encumbrances
1551:             * @return List of accounting lines to use to create the pending general ledger entries
1552:             */
1553:            private List<SourceAccountingLine> getCreditMemoEncumbrance(
1554:                    CreditMemoDocument cm, PurchaseOrderDocument po,
1555:                    boolean cancel) {
1556:                LOG.debug("getCreditMemoEncumbrance() started");
1557:
1558:                if (ObjectUtils.isNull(po)) {
1559:                    return null;
1560:                }
1561:
1562:                if (cancel) {
1563:                    LOG
1564:                            .debug("getCreditMemoEncumbrance() Receiving items back from vendor (cancelled CM)");
1565:                } else {
1566:                    LOG
1567:                            .debug("getCreditMemoEncumbrance() Returning items to vendor");
1568:                }
1569:
1570:                Map encumbranceAccountMap = new HashMap();
1571:
1572:                // Get each item one by one
1573:                for (Iterator items = cm.getItems().iterator(); items.hasNext();) {
1574:                    CreditMemoItem cmItem = (CreditMemoItem) items.next();
1575:                    PurchaseOrderItem poItem = getPoItem(po, cmItem
1576:                            .getItemLineNumber(), cmItem.getItemType());
1577:
1578:                    KualiDecimal itemDisEncumber = null; // Amount to disencumber for this item
1579:
1580:                    String logItmNbr = "Item # " + cmItem.getItemLineNumber();
1581:                    LOG.debug("getCreditMemoEncumbrance() " + logItmNbr);
1582:
1583:                    // If there isn't a PO item or the extended price is 0, we don't need encumbrances
1584:                    if ((poItem == null) || (cmItem.getExtendedPrice() == null)
1585:                            || (cmItem.getExtendedPrice().doubleValue() == 0)) {
1586:                        LOG.debug("getCreditMemoEncumbrance() " + logItmNbr
1587:                                + " No encumbrances required");
1588:                    } else {
1589:                        LOG.debug("getCreditMemoEncumbrance() " + logItmNbr
1590:                                + " Calculate encumbrance GL entries");
1591:
1592:                        // Do we calculate the encumbrance amount based on quantity or amount?
1593:                        if (poItem.getItemType()
1594:                                .isQuantityBasedGeneralLedgerIndicator()) {
1595:                            LOG
1596:                                    .debug("getCreditMemoEncumbrance() "
1597:                                            + logItmNbr
1598:                                            + " Calculate encumbrance based on quantity");
1599:
1600:                            // Do encumbrance calculations based on quantity
1601:                            KualiDecimal cmQuantity = cmItem.getItemQuantity() == null ? ZERO
1602:                                    : cmItem.getItemQuantity();
1603:
1604:                            KualiDecimal encumbranceQuantityChange = calculateQuantityChange(
1605:                                    cancel, poItem, cmQuantity);
1606:
1607:                            LOG
1608:                                    .debug("getCreditMemoEncumbrance() "
1609:                                            + logItmNbr
1610:                                            + " encumbranceQtyChange "
1611:                                            + encumbranceQuantityChange
1612:                                            + " outstandingEncumberedQty "
1613:                                            + poItem
1614:                                                    .getItemOutstandingEncumberedQuantity()
1615:                                            + " invoicedTotalQuantity "
1616:                                            + poItem
1617:                                                    .getItemInvoicedTotalQuantity());
1618:
1619:                            itemDisEncumber = encumbranceQuantityChange
1620:                                    .multiply(new KualiDecimal(poItem
1621:                                            .getItemUnitPrice()));
1622:                        } else {
1623:                            LOG.debug("getCreditMemoEncumbrance() " + logItmNbr
1624:                                    + " Calculate encumbrance based on amount");
1625:
1626:                            // Do encumbrance calculations based on amount only
1627:                            if (cancel) {
1628:                                // Decrease encumbrance
1629:                                itemDisEncumber = cmItem.getExtendedPrice()
1630:                                        .multiply(new KualiDecimal("-1"));
1631:
1632:                                if (poItem.getItemOutstandingEncumberedAmount()
1633:                                        .add(itemDisEncumber).doubleValue() < 0) {
1634:                                    LOG
1635:                                            .debug("getCreditMemoEncumbrance() Cancel overflow");
1636:
1637:                                    itemDisEncumber = poItem
1638:                                            .getItemOutstandingEncumberedAmount();
1639:                                }
1640:                            } else {
1641:                                // Increase encumbrance
1642:                                itemDisEncumber = cmItem.getExtendedPrice();
1643:
1644:                                if (poItem.getItemOutstandingEncumberedAmount()
1645:                                        .add(itemDisEncumber).doubleValue() > poItem
1646:                                        .getExtendedPrice().doubleValue()) {
1647:                                    LOG
1648:                                            .debug("getCreditMemoEncumbrance() Create overflow");
1649:
1650:                                    itemDisEncumber = poItem
1651:                                            .getExtendedPrice()
1652:                                            .subtract(
1653:                                                    poItem
1654:                                                            .getItemOutstandingEncumberedAmount());
1655:                                }
1656:                            }
1657:                        }
1658:
1659:                        poItem.setItemOutstandingEncumberedAmount(poItem
1660:                                .getItemOutstandingEncumberedAmount().add(
1661:                                        itemDisEncumber));
1662:                        poItem.setItemInvoicedTotalAmount(poItem
1663:                                .getItemInvoicedTotalAmount().subtract(
1664:                                        itemDisEncumber));
1665:
1666:                        LOG.debug("getCreditMemoEncumbrance() " + logItmNbr
1667:                                + " Amount to disencumber: " + itemDisEncumber);
1668:
1669:                        // Sort accounts
1670:                        Collections.sort((List) poItem
1671:                                .getSourceAccountingLines());
1672:
1673:                        // make the list of accounts for the disencumbrance entry
1674:                        PurchaseOrderAccount lastAccount = null;
1675:                        KualiDecimal accountTotal = ZERO;
1676:                        // Collections.sort((List)poItem.getSourceAccountingLines());
1677:                        for (Iterator accountIter = poItem
1678:                                .getSourceAccountingLines().iterator(); accountIter
1679:                                .hasNext();) {
1680:                            PurchaseOrderAccount account = (PurchaseOrderAccount) accountIter
1681:                                    .next();
1682:                            if (!account.isEmpty()) {
1683:                                KualiDecimal encumbranceAmount = null;
1684:
1685:                                SourceAccountingLine acctString = account
1686:                                        .generateSourceAccountingLine();
1687:                                // amount = item disencumber * account percent / 100
1688:                                encumbranceAmount = itemDisEncumber.multiply(
1689:                                        new KualiDecimal(account
1690:                                                .getAccountLinePercent()
1691:                                                .toString())).divide(
1692:                                        new KualiDecimal(100));
1693:
1694:                                account
1695:                                        .setItemAccountOutstandingEncumbranceAmount(account
1696:                                                .getItemAccountOutstandingEncumbranceAmount()
1697:                                                .add(encumbranceAmount));
1698:
1699:                                // For rounding check at the end
1700:                                accountTotal = accountTotal
1701:                                        .add(encumbranceAmount);
1702:
1703:                                lastAccount = account;
1704:
1705:                                LOG.debug("getCreditMemoEncumbrance() "
1706:                                        + logItmNbr + " " + acctString + " = "
1707:                                        + encumbranceAmount);
1708:
1709:                                if (encumbranceAccountMap.get(acctString) == null) {
1710:                                    encumbranceAccountMap.put(acctString,
1711:                                            encumbranceAmount);
1712:                                } else {
1713:                                    KualiDecimal amt = (KualiDecimal) encumbranceAccountMap
1714:                                            .get(acctString);
1715:                                    encumbranceAccountMap.put(acctString, amt
1716:                                            .add(encumbranceAmount));
1717:                                }
1718:                            }
1719:                        }
1720:
1721:                        // account for rounding by adjusting last account as needed
1722:                        if (lastAccount != null) {
1723:                            KualiDecimal difference = itemDisEncumber
1724:                                    .subtract(accountTotal);
1725:                            LOG.debug("getCreditMemoEncumbrance() difference: "
1726:                                    + logItmNbr + " " + difference);
1727:
1728:                            SourceAccountingLine acctString = lastAccount
1729:                                    .generateSourceAccountingLine();
1730:                            KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1731:                                    .get(acctString);
1732:                            if (amount == null) {
1733:                                encumbranceAccountMap.put(acctString,
1734:                                        difference);
1735:                            } else {
1736:                                encumbranceAccountMap.put(acctString, amount
1737:                                        .add(difference));
1738:                            }
1739:                            lastAccount
1740:                                    .setItemAccountOutstandingEncumbranceAmount(lastAccount
1741:                                            .getItemAccountOutstandingEncumbranceAmount()
1742:                                            .add(difference));
1743:                        }
1744:                    }
1745:                }
1746:
1747:                List<SourceAccountingLine> encumbranceAccounts = new ArrayList();
1748:                for (Iterator iter = encumbranceAccountMap.keySet().iterator(); iter
1749:                        .hasNext();) {
1750:                    SourceAccountingLine acctString = (SourceAccountingLine) iter
1751:                            .next();
1752:                    KualiDecimal amount = (KualiDecimal) encumbranceAccountMap
1753:                            .get(acctString);
1754:                    if (amount.doubleValue() != 0) {
1755:                        acctString.setAmount(amount);
1756:                        encumbranceAccounts.add(acctString);
1757:                    }
1758:                }
1759:
1760:                purchaseOrderService.saveDocumentNoValidation(po);
1761:
1762:                return encumbranceAccounts;
1763:            }
1764:
1765:            /**
1766:             * Save the given general ledger entries
1767:             * 
1768:             * @param glEntries List of GeneralLedgerPendingEntries to be saved
1769:             */
1770:            private void saveGLEntries(List<GeneralLedgerPendingEntry> glEntries) {
1771:                LOG.debug("saveGLEntries() started");
1772:                businessObjectService.save(glEntries);
1773:            }
1774:
1775:            /**
1776:             * Save the given accounts for the given document.
1777:             * 
1778:             * @param sourceLines Accounts to be saved
1779:             * @param purapDocumentIdentifier Purap document id for accounts
1780:             */
1781:            private void savePaymentRequestSummaryAccounts(
1782:                    List<SourceAccountingLine> sourceLines,
1783:                    Integer purapDocumentIdentifier) {
1784:                LOG.debug("savePaymentRequestSummaryAccounts() started");
1785:                paymentRequestService
1786:                        .deleteSummaryAccounts(purapDocumentIdentifier);
1787:                List<PaymentRequestSummaryAccount> summaryAccounts = new ArrayList();
1788:                for (SourceAccountingLine account : sourceLines) {
1789:                    summaryAccounts.add(new PaymentRequestSummaryAccount(
1790:                            account, purapDocumentIdentifier));
1791:                }
1792:                businessObjectService.save(summaryAccounts);
1793:            }
1794:
1795:            /**
1796:             * Retrieve summary accounts based on given purap document id
1797:             * 
1798:             * @param purapDocumentIdentifier Purap document id for accounts
1799:             * @return List of summary accounts
1800:             */
1801:            private List getPaymentRequestSummaryAccounts(
1802:                    Integer purapDocumentIdentifier) {
1803:                LOG.debug("getPaymentRequestSummaryAccounts() started");
1804:                Map fieldValues = new HashMap();
1805:                fieldValues.put(PurapPropertyConstants.PURAP_DOC_ID,
1806:                        purapDocumentIdentifier);
1807:                return new ArrayList(businessObjectService.findMatching(
1808:                        PaymentRequestSummaryAccount.class, fieldValues));
1809:            }
1810:
1811:            /**
1812:             * Find item in PO based on given parameters. Must send either the line # or item type.
1813:             * 
1814:             * @param po Purchase Order containing list of items
1815:             * @param nbr Line # of desired item (could be null)
1816:             * @param itemType Item type of desired item
1817:             * @return PurcahseOrderItem found matching given criteria
1818:             */
1819:            private PurchaseOrderItem getPoItem(PurchaseOrderDocument po,
1820:                    Integer nbr, ItemType itemType) {
1821:                LOG.debug("getPoItem() started");
1822:                for (Iterator iter = po.getItems().iterator(); iter.hasNext();) {
1823:                    PurchaseOrderItem element = (PurchaseOrderItem) iter.next();
1824:                    if (itemType.isItemTypeAboveTheLineIndicator()) {
1825:                        if (ObjectUtils.isNotNull(nbr)
1826:                                && ObjectUtils.isNotNull(element
1827:                                        .getItemLineNumber())
1828:                                && (nbr.compareTo(element.getItemLineNumber()) == 0)) {
1829:                            return element;
1830:                        }
1831:                    } else {
1832:                        if (element.getItemTypeCode().equals(
1833:                                itemType.getItemTypeCode())) {
1834:                            return element;
1835:                        }
1836:                    }
1837:                }
1838:                return null;
1839:            }
1840:
1841:            /**
1842:             * Format description for general ledger entry. Currently making sure length is less than 40 char.
1843:             * 
1844:             * @param description String to be formatted
1845:             * @return Formatted String
1846:             */
1847:            private String entryDescription(String description) {
1848:                if (description != null && description.length() > 40) {
1849:                    return description.toString().substring(0, 39);
1850:                } else {
1851:                    return description;
1852:                }
1853:            }
1854:
1855:            /**
1856:             * Calculate quantity change for creating Credit Memo entries
1857:             * 
1858:             * @param cancel Boolean indicating whether entries are for creation or cancellation of credit memo
1859:             * @param poItem Purchase Order Item
1860:             * @param cmQuantity Quantity on credit memo item
1861:             * @return Calculated change
1862:             */
1863:            private KualiDecimal calculateQuantityChange(boolean cancel,
1864:                    PurchaseOrderItem poItem, KualiDecimal cmQuantity) {
1865:                LOG.debug("calculateQuantityChange() started");
1866:
1867:                // Calculate quantity change & adjust invoiced quantity & outstanding encumbered quantity
1868:                KualiDecimal encumbranceQuantityChange = null;
1869:                if (cancel) {
1870:                    encumbranceQuantityChange = cmQuantity
1871:                            .multiply(new KualiDecimal("-1"));
1872:                } else {
1873:                    encumbranceQuantityChange = cmQuantity;
1874:                }
1875:                poItem.setItemInvoicedTotalQuantity(poItem
1876:                        .getItemInvoicedTotalQuantity().subtract(
1877:                                encumbranceQuantityChange));
1878:                poItem.setItemOutstandingEncumberedQuantity(poItem
1879:                        .getItemOutstandingEncumberedQuantity().add(
1880:                                encumbranceQuantityChange));
1881:
1882:                // Check for overflows
1883:                if (cancel) {
1884:                    if (poItem.getItemOutstandingEncumberedQuantity()
1885:                            .doubleValue() < 0) {
1886:                        LOG.debug("calculateQuantityChange() Cancel overflow");
1887:                        KualiDecimal difference = poItem
1888:                                .getItemOutstandingEncumberedQuantity().abs();
1889:                        poItem.setItemOutstandingEncumberedQuantity(ZERO);
1890:                        poItem.setItemInvoicedTotalQuantity(poItem
1891:                                .getItemQuantity());
1892:                        encumbranceQuantityChange = encumbranceQuantityChange
1893:                                .add(difference);
1894:                    }
1895:                } else {
1896:                    if (poItem.getItemInvoicedTotalQuantity().doubleValue() < 0) {
1897:                        LOG.debug("calculateQuantityChange() Create overflow");
1898:                        KualiDecimal difference = poItem
1899:                                .getItemInvoicedTotalQuantity().abs();
1900:                        poItem.setItemOutstandingEncumberedQuantity(poItem
1901:                                .getItemQuantity());
1902:                        poItem.setItemInvoicedTotalQuantity(ZERO);
1903:                        encumbranceQuantityChange = encumbranceQuantityChange
1904:                                .add(difference);
1905:                    }
1906:                }
1907:                return encumbranceQuantityChange;
1908:            }
1909:
1910:            public void setDateTimeService(DateTimeService dateTimeService) {
1911:                this .dateTimeService = dateTimeService;
1912:            }
1913:
1914:            public void setBusinessObjectService(
1915:                    BusinessObjectService businessObjectService) {
1916:                this .businessObjectService = businessObjectService;
1917:            }
1918:
1919:            public void setGeneralLedgerPendingEntryService(
1920:                    GeneralLedgerPendingEntryService generalLedgerPendingEntryService) {
1921:                this .generalLedgerPendingEntryService = generalLedgerPendingEntryService;
1922:            }
1923:
1924:            public void setKualiRuleService(KualiRuleService kualiRuleService) {
1925:                this .kualiRuleService = kualiRuleService;
1926:            }
1927:
1928:            public void setPurapAccountingService(
1929:                    PurapAccountingService purapAccountingService) {
1930:                this .purapAccountingService = purapAccountingService;
1931:            }
1932:
1933:            public void setKualiConfigurationService(
1934:                    KualiConfigurationService kualiConfigurationService) {
1935:                this .kualiConfigurationService = kualiConfigurationService;
1936:            }
1937:
1938:            public void setUniversityDateService(
1939:                    UniversityDateService universityDateService) {
1940:                this .universityDateService = universityDateService;
1941:            }
1942:
1943:            public void setPaymentRequestService(
1944:                    PaymentRequestService paymentRequestService) {
1945:                this .paymentRequestService = paymentRequestService;
1946:            }
1947:
1948:            public void setPurchaseOrderService(
1949:                    PurchaseOrderService purchaseOrderService) {
1950:                this.purchaseOrderService = purchaseOrderService;
1951:            }
1952:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.