View Javadoc
1   /*
2    * Copyright 2011 The Kuali Foundation.
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.select.document.service.impl;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.ArrayUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.ole.DataCarrierService;
22  import org.kuali.ole.batch.bo.OLEBatchProcessProfileBo;
23  import org.kuali.ole.batch.bo.OLEBatchProcessProfileConstantsBo;
24  import org.kuali.ole.batch.bo.OLEBatchProcessProfileDataMappingOptionsBo;
25  import org.kuali.ole.batch.bo.OLEBatchProcessProfileMappingOptionsBo;
26  import org.kuali.ole.coa.businessobject.Account;
27  import org.kuali.ole.coa.businessobject.ObjectCode;
28  import org.kuali.ole.docstore.common.document.content.bib.marc.BibMarcRecord;
29  import org.kuali.ole.module.purap.PurapConstants;
30  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderDocTypes;
31  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses;
32  import org.kuali.ole.module.purap.PurapKeyConstants;
33  import org.kuali.ole.module.purap.PurapParameterConstants;
34  import org.kuali.ole.module.purap.PurapPropertyConstants;
35  import org.kuali.ole.module.purap.businessobject.*;
36  import org.kuali.ole.module.purap.document.InvoiceDocument;
37  import org.kuali.ole.module.purap.document.PurchaseOrderAmendmentDocument;
38  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
39  import org.kuali.ole.module.purap.document.service.*;
40  import org.kuali.ole.module.purap.document.service.impl.InvoiceServiceImpl;
41  import org.kuali.ole.module.purap.document.validation.event.AttributedCalculateAccountsPayableEvent;
42  import org.kuali.ole.module.purap.service.PurapAccountingService;
43  import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
44  import org.kuali.ole.pojo.OleInvoiceRecord;
45  import org.kuali.ole.select.OleSelectConstant;
46  import org.kuali.ole.select.OleSelectNotificationConstant;
47  import org.kuali.ole.select.bo.OleInvoiceEncumbranceNotification;
48  import org.kuali.ole.select.businessobject.*;
49  import org.kuali.ole.select.document.OleInvoiceDocument;
50  import org.kuali.ole.select.document.OlePaymentRequestDocument;
51  import org.kuali.ole.select.document.OlePurchaseOrderDocument;
52  import org.kuali.ole.select.document.OleVendorCreditMemoDocument;
53  import org.kuali.ole.select.document.service.OleCreditMemoService;
54  import org.kuali.ole.select.document.service.OleInvoiceService;
55  import org.kuali.ole.select.document.service.OlePurapAccountingService;
56  import org.kuali.ole.select.form.OLEInvoiceForm;
57  import org.kuali.ole.service.OleOrderRecordService;
58  import org.kuali.ole.sys.OLEConstants;
59  import org.kuali.ole.sys.OLEKeyConstants;
60  import org.kuali.ole.sys.OLEPropertyConstants;
61  import org.kuali.ole.sys.businessobject.AccountingLine;
62  import org.kuali.ole.sys.businessobject.Bank;
63  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
64  import org.kuali.ole.sys.context.SpringContext;
65  import org.kuali.ole.sys.service.BankService;
66  import org.kuali.ole.sys.service.impl.OleParameterConstants;
67  import org.kuali.ole.vnd.businessobject.OleCurrencyType;
68  import org.kuali.ole.vnd.businessobject.OleExchangeRate;
69  import org.kuali.ole.vnd.businessobject.VendorAddress;
70  import org.kuali.ole.vnd.businessobject.VendorDetail;
71  import org.kuali.rice.core.api.config.property.ConfigurationService;
72  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
73  import org.kuali.rice.core.api.util.type.AbstractKualiDecimal;
74  import org.kuali.rice.core.api.util.type.KualiDecimal;
75  import org.kuali.rice.core.web.format.CurrencyFormatter;
76  import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
77  import org.kuali.rice.coreservice.api.parameter.Parameter;
78  import org.kuali.rice.coreservice.api.parameter.ParameterKey;
79  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
80  import org.kuali.rice.kew.api.exception.WorkflowException;
81  import org.kuali.rice.kim.api.identity.Person;
82  import org.kuali.rice.kns.util.KNSGlobalVariables;
83  import org.kuali.rice.krad.UserSession;
84  import org.kuali.rice.krad.bo.Note;
85  import org.kuali.rice.krad.exception.ValidationException;
86  import org.kuali.rice.krad.service.*;
87  import org.kuali.rice.krad.util.ErrorMessage;
88  import org.kuali.rice.krad.util.GlobalVariables;
89  import org.kuali.rice.krad.util.KRADConstants;
90  import org.kuali.rice.krad.util.ObjectUtils;
91  import org.springframework.util.AutoPopulatingList;
92  
93  import java.math.BigDecimal;
94  import java.math.RoundingMode;
95  import java.text.ParseException;
96  import java.text.SimpleDateFormat;
97  import java.util.*;
98  
99  /**
100  * This class has implementation for PaymentRequest with respect to OLE.
101  */
102 public class OleInvoiceServiceImpl extends InvoiceServiceImpl implements OleInvoiceService {
103 
104     protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OleInvoiceServiceImpl.class);
105 
106     protected PurchaseOrderService purchaseOrderService;
107     protected PurapService purapService;
108     protected DocumentService documentService;
109     protected NoteService noteService;
110     private OlePurapAccountingService olePurapAccountingService;
111     private PurapAccountingService purapAccountingService;
112     protected ConfigurationService kualiConfigurationService;
113     List<OleInvoiceEncumbranceNotification> invoiceEncumbranceNotificationList;
114     private OLEBatchProcessProfileBo oleBatchProcessProfileBo;
115     private OleOrderRecordService oleOrderRecordService;
116     DataCarrierService dataCarrierService = GlobalResourceLoader.getService(org.kuali.ole.OLEConstants.DATA_CARRIER_SERVICE);
117 
118     public void setOleBatchProcessProfileBo(OLEBatchProcessProfileBo oleBatchProcessProfileBo) {
119         this.oleBatchProcessProfileBo = oleBatchProcessProfileBo;
120     }
121 
122     protected BusinessObjectService getBusinessObjectService() {
123         if (businessObjectService == null) {
124             businessObjectService = SpringContext.getBean(BusinessObjectService.class);
125         }
126         return businessObjectService;
127     }
128 
129     public OleOrderRecordService getOleOrderRecordService() {
130         if (oleOrderRecordService == null) {
131             oleOrderRecordService = SpringContext.getBean(OleOrderRecordService.class);
132         }
133         return oleOrderRecordService;
134     }
135 
136 
137     @Override
138     public void setPurapService(PurapService purapService) {
139         this.purapService = purapService;
140     }
141 
142     @Override
143     public void setPurchaseOrderService(PurchaseOrderService purchaseOrderService) {
144         this.purchaseOrderService = purchaseOrderService;
145     }
146 
147     @Override
148     public void setDocumentService(DocumentService documentService) {
149         this.documentService = documentService;
150     }
151 
152     @Override
153     public void setNoteService(NoteService noteService) {
154         this.noteService = noteService;
155     }
156 
157 
158     @Override
159     public void setPurapAccountingService(PurapAccountingService purapAccountingService) {
160         this.purapAccountingService = purapAccountingService;
161     }
162 
163     public void setOlePurapAccountingService(OlePurapAccountingService olePurapAccountingService) {
164         this.olePurapAccountingService = olePurapAccountingService;
165     }
166 
167     /**
168      * This method deletes unneeded items and updates the totals on the po and does any additional processing based on items
169      *
170      * @see org.kuali.ole.select.document.service.OleInvoiceService#completePaymentDocument(org.kuali.ole.select.document.OleInvoiceDocument)
171      */
172     @Override
173     public void completePaymentDocument(OleInvoiceDocument invoiceDocument) {
174         LOG.debug("Inside CompletePaymentDocument");
175 
176         PurchaseOrderDocument poDoc = null;
177 
178         if (invoiceDocument != null && invoiceDocument instanceof InvoiceDocument) {
179             // delete unentered items
180             purapService.deleteUnenteredItems(invoiceDocument);
181 
182             //     poDoc = invoiceDocument.getPurchaseOrderDocument(invoiceDocument.getPurchaseOrderIdentifier());
183         }
184         updatePaymentTotalsOnPurchaseOrder(invoiceDocument);
185 
186 
187         //poDoc.setVendorName(invoiceDocument.getVendorDetail().getVendorName());
188 
189         // spawnPoAmendmentForUnorderedItems(invoiceDocument, poDoc);
190 
191         purapService.saveDocumentNoValidation(invoiceDocument);
192 
193         LOG.debug("Leaving CompletePaymentDocument");
194     }
195 
196     protected void updatePaymentTotalsOnPurchaseOrder(OleInvoiceDocument invoiceDocument) {
197         LOG.debug("Inside updatePaymentTotalsOnPurchaseOrder");
198         List<Integer> poList = new ArrayList();
199         Integer invPoId = 0;
200         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
201             if (!(poList.contains(invoiceItem.getPurchaseOrderIdentifier()))) {
202                 poList.add(invoiceItem.getPurchaseOrderIdentifier());
203             }
204         }
205         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
206             for (Integer purchaseOrderId : poList) {
207                 if (invoiceItem.getItemType() != null && invoiceItem.getItemType().getItemTypeCode() != null && StringUtils.equalsIgnoreCase(invoiceItem.getItemType().getItemTypeCode(), PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE) &&
208                         purchaseOrderId != null && invPoId != null && invPoId.compareTo(purchaseOrderId) != 0 && invoiceItem.getPurchaseOrderIdentifier().compareTo(purchaseOrderId) == '0') {
209                     PurchaseOrderDocument poDoc = invoiceDocument.getPurchaseOrderDocument(purchaseOrderId);
210                     OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) poDoc.getItemByLineNumber(invoiceItem.getItemLineNumber());
211 
212                     if (ObjectUtils.isNotNull(poItem)) {
213 
214                         KualiDecimal poItemReceivedTotal = poItem.getOutstandingQuantity();
215 
216                         KualiDecimal itemQuantity = invoiceItem.getItemQuantity();
217 
218                         if (ObjectUtils.isNull(itemQuantity)) {
219                             itemQuantity = KualiDecimal.ZERO;
220                         }
221                         if (ObjectUtils.isNull(poItemReceivedTotal)) {
222                             poItemReceivedTotal = KualiDecimal.ZERO;
223                         }
224                     /* Modified for OLE - 2516
225                       poItem.setItemQuantity(itemQuantity);
226                     */
227                         // poItem.setItemUnitPrice(invoiceItem.getItemUnitPrice());
228                     }
229                     purapService.saveDocumentNoValidation(poDoc);
230                 }
231                 invPoId = purchaseOrderId;
232             }
233 
234         }
235         LOG.debug("Leaving updatePaymentTotalsOnPurchaseOrder");
236     }
237 
238 
239     /**
240      * Spawns PO amendments for new unordered items on a Invoice document.
241      *
242      * @param invoice Document
243      * @param po
244      */
245     protected void spawnPoAmendmentForUnorderedItems(OleInvoiceDocument invoice, PurchaseOrderDocument po) {
246 
247         LOG.debug("Inside spawnPoAmendmentForUnorderedItems");
248         if (invoice != null && invoice instanceof OleInvoiceDocument) {
249             OleInvoiceDocument rlDoc = invoice;
250 
251             //if a new item has been added spawn a purchase order amendment
252             if (hasNewUnorderedItem(invoice)) {
253                 String newSessionUserId = OLEConstants.SYSTEM_USER;
254                 try {
255 
256                     LogicContainer logicToRun = new LogicContainer() {
257                         @Override
258                         public Object runLogic(Object[] objects) throws Exception {
259                             OleInvoiceDocument rlDoc = (OleInvoiceDocument) objects[0];
260                             String poDocNumber = (String) objects[1];
261 
262                             //create a PO amendment
263                             PurchaseOrderAmendmentDocument amendmentPo = (PurchaseOrderAmendmentDocument) purchaseOrderService.createAndSavePotentialChangeDocument(poDocNumber, PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT, PurchaseOrderStatuses.APPDOC_AMENDMENT);
264 
265                             //add new lines to amendement
266                             addUnorderedItemsToAmendment(amendmentPo, rlDoc);
267 
268                             //route amendment
269                             documentService.routeDocument(amendmentPo, null, null);
270 
271                             //add note to amendment po document
272                             String note = "Purchase Order Amendment " + amendmentPo.getPurapDocumentIdentifier() + " (document id " + amendmentPo.getDocumentNumber() + ") created for new unordered line items (document id " + rlDoc.getDocumentNumber() + ")";
273 
274                             Note noteObj = documentService.createNoteFromDocument(amendmentPo, note);
275                             amendmentPo.addNote(noteObj);
276                             documentService.saveDocumentNotes(amendmentPo);
277                             noteService.save(noteObj);
278 
279                             return null;
280                         }
281                     };
282 
283                     purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, rlDoc, po.getDocumentNumber());
284                 } catch (WorkflowException e) {
285                     String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
286                     throw new RuntimeException(errorMsg, e);
287                 } catch (Exception e) {
288                     throw new RuntimeException(e);
289                 }
290             }
291         }
292         LOG.debug("Leaving spawnPoAmendmentForUnorderedItems");
293     }
294 
295     /**
296      * Checks the item list for newly added items.
297      *
298      * @param paymentDoc
299      * @return
300      */
301     protected boolean hasNewUnorderedItem(OleInvoiceDocument paymentDoc) {
302         LOG.debug("Inside hasNewUnorderedItem");
303         boolean itemAdded = false;
304 
305         for (OleInvoiceItem prItem : (List<OleInvoiceItem>) paymentDoc.getItems()) {
306             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(prItem.getItemTypeCode())) {
307                 itemAdded = true;
308                 break;
309             }
310         }
311         LOG.debug("Leaving hasNewUnorderedItem");
312         return itemAdded;
313     }
314 
315     /**
316      * Adds an unordered item to a po amendment document.
317      *
318      * @param amendment
319      * @param rlDoc
320      */
321     protected void addUnorderedItemsToAmendment(PurchaseOrderAmendmentDocument amendment, OleInvoiceDocument rlDoc) {
322 
323         LOG.debug("Inside addUnorderedItemsToAmendment");
324         OlePurchaseOrderItem poi = null;
325 
326         for (OleInvoiceItem rlItem : (List<OleInvoiceItem>) rlDoc.getItems()) {
327             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(rlItem.getItemTypeCode())) {
328                 poi = createPoItemFromPaymentLine(rlItem);
329                 poi.setDocumentNumber(amendment.getDocumentNumber());
330                 poi.refreshNonUpdateableReferences();
331                 amendment.addItem(poi);
332             }
333         }
334         LOG.debug("Leaving addUnorderedItemsToAmendment");
335 
336     }
337 
338     /**
339      * Creates a PO item from invoice Line item.
340      *
341      * @param rlItem
342      * @return
343      */
344     protected OlePurchaseOrderItem createPoItemFromPaymentLine(OleInvoiceItem rlItem) {
345         LOG.debug("Inside createPoItemFromPaymentLine");
346         OlePurchaseOrderItem poi = new OlePurchaseOrderItem();
347         poi.setItemActiveIndicator(true);
348         poi.setItemTypeCode(rlItem.getItemTypeCode());
349         poi.setItemLineNumber(rlItem.getItemLineNumber());
350         poi.setItemCatalogNumber(rlItem.getItemCatalogNumber());
351         poi.setItemDescription(rlItem.getItemDescription());
352         poi.setItemQuantity(rlItem.getItemQuantity());
353         poi.setItemUnitOfMeasureCode(rlItem.getItemUnitOfMeasureCode());
354         poi.setItemUnitPrice(rlItem.getItemUnitPrice());
355 //        poi.setSourceAccountingLines(rlItem.getSourceAccountingLines());
356         poi.setItemNoOfParts(rlItem.getItemNoOfParts());
357         poi.setItemListPrice(rlItem.getItemListPrice());
358         poi.setItemDiscount(rlItem.getItemDiscount());
359         poi.setItemDiscountType(rlItem.getItemDiscountType());
360         poi.setFormatTypeId(rlItem.getFormatTypeId());
361 
362         //Foreign Currency
363         poi.setItemCurrencyType(rlItem.getItemCurrencyType());
364         poi.setItemForeignListPrice((rlItem.getItemForeignListPrice()));
365         poi.setItemForeignDiscount((rlItem.getItemForeignDiscount()));
366         poi.setItemForeignDiscountAmt((rlItem.getItemForeignDiscountAmt()));
367         poi.setItemForeignDiscountType(rlItem.getItemForeignDiscountType());
368         poi.setItemForeignUnitCost((rlItem.getItemForeignUnitCost()));
369         poi.setItemExchangeRate((rlItem.getItemExchangeRate()));
370         poi.setItemUnitCostUSD((rlItem.getItemUnitCostUSD()));
371         poi.setItemInvoicedTotalAmount(rlItem.getTotalAmount());
372         poi.setBibInfoBean(rlItem.getBibInfoBean());
373         poi.setItemTitleId(rlItem.getItemTitleId());
374         setAccountingLinesFromPayment(rlItem, poi);
375 
376         LOG.debug("Leaving createPoItemFromPaymentLine");
377         return poi;
378     }
379 
380     /**
381      * Setting Accounting Lines For POA from newLineItem
382      *
383      * @param payItem
384      * @param purItem
385      */
386 
387     public void setAccountingLinesFromPayment(OleInvoiceItem payItem, OlePurchaseOrderItem purItem) {
388         LOG.debug("Inside setAccountingLinesFromPayment");
389         for (int i = 0; i < payItem.getSourceAccountingLines().size(); i++) {
390             // OLE-3669 : Ensuring that the purchasing document has enough accounting lines
391             // for copying from the payment
392             while (purItem.getSourceAccountingLines().size() < i + 1) {
393                 PurchaseOrderAccount poAccount = new PurchaseOrderAccount();
394                 poAccount.setPurchaseOrderItem(purItem);
395                 purItem.getSourceAccountingLines().add(poAccount);
396             }
397             purItem.getSourceAccountingLine(i).copyFrom(payItem.getSourceAccountingLine(i));
398             purItem.getSourceAccountingLine(i).setAccountLinePercent(payItem.getSourceAccountingLine(i).getAccountLinePercent());
399         }
400         LOG.debug("Leaving setAccountingLinesFromPayment");
401     }
402 
403     /**
404      * @see org.kuali.ole.select.document.service.OleInvoiceService#calculateProrateItemSurcharge(org.kuali.ole.select.document.OleInvoiceDocument)
405      */
406     @Override
407     public void calculateProrateItemSurcharge(OleInvoiceDocument invoiceDocument) {
408         LOG.debug("Inside Calculation for ProrateItemSurcharge");
409         //  KualiDecimal addChargeItem = invoiceDocument.getGrandPreTaxTotalExcludingDiscount().subtract(invoiceDocument.getLineItemPreTaxTotal());
410         BigDecimal addChargeItem = BigDecimal.ZERO;
411         List<OleInvoiceItem> item = invoiceDocument.getItems();
412         for (OleInvoiceItem items : item) {
413             if (items.getItemType().isAdditionalChargeIndicator() && items.getExtendedPrice() != null) {
414                 addChargeItem = addChargeItem.add(items.getExtendedPrice().bigDecimalValue());
415             }
416         }
417         List<PurApItem> items = new ArrayList<>();
418         /*List<OlePurchaseOrderDocument> olePurchaseOrderDocuments = invoiceDocument.getPurchaseOrderDocuments();
419         for (OlePurchaseOrderDocument olePurchaseOrderDocument : olePurchaseOrderDocuments) {
420             for (OlePurchaseOrderItem purItem : (List<OlePurchaseOrderItem>) olePurchaseOrderDocument.getItems()) {
421                 purItem.setItemListPrice(new KualiDecimal(purItem.getInvoiceItemListPrice()));
422                 if (purItem.isItemForInvoice() && purItem.getItemListPrice().compareTo(KualiDecimal.ZERO) >= 0) {
423                     items.add(purItem);
424                 } else {
425                     purItem.setItemSurcharge(BigDecimal.ZERO);
426                 }
427                 if (purItem.getItemListPrice().compareTo(KualiDecimal.ZERO) < 0) {
428                     purItem.setItemUnitPrice(SpringContext.getBean(OlePurapService.class).calculateDiscount(purItem));
429                 }
430             }
431 
432         }
433         if (items.size() == 0) {*/
434         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
435                /* if(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && invoiceItem.getRelatedViews() != null) {
436                     invoiceItem.setRelatedViews(null);
437                 }*/
438             items.add(invoiceItem);
439         }
440        /* }
441         else {
442             for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
443                 if (!(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator())) {
444                     items.add(invoiceItem);
445                 }
446             }
447         }*/
448         List<BigDecimal> newUnitPriceList = new ArrayList<>();
449         BigDecimal totalExtPrice = new BigDecimal(0);
450         BigDecimal newUnitPrice = new BigDecimal(0);
451         BigDecimal extPrice = new BigDecimal(0);
452         BigDecimal unitPricePercent = new BigDecimal(0);
453         BigDecimal hundred = new BigDecimal(100);
454         BigDecimal one = new BigDecimal(1);
455         BigDecimal totalSurCharge = new BigDecimal(0);
456         BigDecimal totalItemQuantity = new BigDecimal(0);
457         BigDecimal itemSurchargeCons = new BigDecimal(0);
458         for (PurApItem purItem : items) {
459             if(purItem instanceof OlePurchaseOrderItem) {
460                 OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) purItem;
461                 //  purItem.setItemListPrice(new KualiDecimal(purItem.getInvoiceItemListPrice()));
462                 if ((poItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) && !ObjectUtils.isNull(poItem.getNoOfCopiesInvoiced()) && poItem.getItemListPrice().compareTo(KualiDecimal.ZERO) >= 0) {
463                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
464                         totalItemQuantity = totalItemQuantity.add(poItem.getNoOfCopiesInvoiced().bigDecimalValue());
465                     }
466                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR) || invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) || invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
467                         if (poItem.getItemDiscount() == null) {
468                             poItem.setItemDiscount(KualiDecimal.ZERO);
469                         }
470                         if (poItem.getItemDiscountType() != null && poItem.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
471                             newUnitPrice = (hundred.subtract(poItem.getItemDiscount().bigDecimalValue())).divide(hundred).multiply(poItem.getItemListPrice().bigDecimalValue());
472                         } else {
473                             newUnitPrice = poItem.getItemListPrice().bigDecimalValue().subtract(poItem.getItemDiscount().bigDecimalValue());
474                         }
475                         newUnitPriceList.add(newUnitPrice);
476                         extPrice = newUnitPrice.multiply(poItem.getNoOfCopiesInvoiced().bigDecimalValue());
477                         totalExtPrice = totalExtPrice.add(extPrice);
478                     }
479                     if (invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE)) {
480                         if (poItem.getItemSurcharge() == null) {
481                             poItem.setItemSurcharge(BigDecimal.ZERO);
482                         }
483                         totalSurCharge = totalSurCharge.add(poItem.getNoOfCopiesInvoiced().bigDecimalValue().multiply(poItem.getItemSurcharge()));
484                     }
485                 }
486             }
487 
488             else if(purItem instanceof OleInvoiceItem)   {
489                 OleInvoiceItem invItem = (OleInvoiceItem) purItem;
490                 if ((invItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) && !ObjectUtils.isNull(invItem.getItemQuantity()) && invItem.getItemListPrice().compareTo(KualiDecimal.ZERO) >= 0) {
491                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
492                         totalItemQuantity = totalItemQuantity.add(invItem.getItemQuantity().bigDecimalValue());
493                     }
494                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR) || invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) || invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
495                         if (invItem.getItemDiscount() == null) {
496                             invItem.setItemDiscount(KualiDecimal.ZERO);
497                         }
498                         if (invItem.getItemDiscountType() != null && invItem.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
499                             newUnitPrice = (hundred.subtract(invItem.getItemDiscount().bigDecimalValue())).divide(hundred).multiply(invItem.getItemListPrice().bigDecimalValue());
500                         } else {
501                             newUnitPrice = invItem.getItemListPrice().bigDecimalValue().subtract(invItem.getItemDiscount().bigDecimalValue());
502                         }
503                         newUnitPriceList.add(newUnitPrice);
504                         extPrice = newUnitPrice.multiply(invItem.getItemQuantity().bigDecimalValue());
505                         totalExtPrice = totalExtPrice.add(extPrice);
506                     }
507                     if (invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE)) {
508                         if (invItem.getItemSurcharge() == null) {
509                             invItem.setItemSurcharge(BigDecimal.ZERO);
510                         }
511                         totalSurCharge = totalSurCharge.add(invItem.getItemQuantity().bigDecimalValue().multiply(invItem.getItemSurcharge()));
512                     }
513                 }
514             }
515         }
516 
517         if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
518             if (totalItemQuantity.compareTo(BigDecimal.ZERO) != 0) {
519                 itemSurchargeCons = one.divide(totalItemQuantity, 8, RoundingMode.HALF_UP);
520             }
521         }
522         for (int i = 0, j = 0; items.size() > i; i++) {
523             PurApItem purItem = items.get(i);
524             if(purItem instanceof OlePurchaseOrderItem) {
525                 OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) purItem;
526 
527                 if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && newUnitPriceList.size() > j && !ObjectUtils.isNull(poItem.getNoOfCopiesInvoiced())) {
528                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR)) {
529                         if (totalExtPrice.compareTo(BigDecimal.ZERO) != 0) {
530                             unitPricePercent = newUnitPriceList.get(j).divide(totalExtPrice, 8, RoundingMode.HALF_UP);
531                         }
532                         poItem.setItemSurcharge(unitPricePercent.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
533                         poItem.setItemUnitPrice(newUnitPriceList.get(j).add(poItem.getItemSurcharge()));
534                     }
535                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
536                         poItem.setItemSurcharge(itemSurchargeCons.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
537                         poItem.setItemUnitPrice(newUnitPriceList.get(j).add(poItem.getItemSurcharge()));
538                     }
539                     if (invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) && poItem.getItemSurcharge() != null) {
540                         poItem.setItemUnitPrice(newUnitPriceList.get(j).add(poItem.getItemSurcharge()));
541                     }
542                     j++;
543                 }
544             }
545             else if(purItem instanceof OleInvoiceItem)   {
546                 OleInvoiceItem invItem = (OleInvoiceItem) purItem;
547                 if (invItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && newUnitPriceList.size() > j && !ObjectUtils.isNull(invItem.getItemQuantity())) {
548                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR)) {
549                         if (totalExtPrice.compareTo(BigDecimal.ZERO) != 0) {
550                             unitPricePercent = newUnitPriceList.get(j).divide(totalExtPrice, 8, RoundingMode.HALF_UP);
551                         }
552                         invItem.setItemSurcharge(unitPricePercent.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
553                         invItem.setItemUnitPrice(newUnitPriceList.get(j).add(invItem.getItemSurcharge()));
554                     }
555                     if (invoiceDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
556                         invItem.setItemSurcharge(itemSurchargeCons.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
557                         invItem.setItemUnitPrice(newUnitPriceList.get(j).add(invItem.getItemSurcharge()));
558                     }
559                     if (invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) && invItem.getItemSurcharge() != null) {
560                         invItem.setItemUnitPrice(newUnitPriceList.get(j).add(invItem.getItemSurcharge()));
561                     }
562                     j++;
563                 }
564 
565             }
566         }
567         if (invoiceDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE)) {
568             if (totalSurCharge.compareTo(addChargeItem) != 0) {
569                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, OLEKeyConstants.ERROR_PAYMENT_REQUEST_TOTAL_MISMATCH);
570             }
571         }
572         LOG.debug("Leaving Calculation for ProrateItemSurcharge");
573     }
574 
575     @Override
576     public void calculateInvoice(InvoiceDocument invoice, boolean updateDiscount) {
577         LOG.debug("calculateInvoice() started");
578 
579         // general calculation, i.e. for the whole preq document
580         if (ObjectUtils.isNull(invoice.getInvoicePayDate())) {
581             invoice.setInvoicePayDate(calculatePayDate(invoice.getInvoiceDate(), invoice.getVendorPaymentTerms()));
582         }
583 
584         distributeAccounting(invoice);
585 
586         //   purapService.calculateTax(invoice);
587 
588         // do proration for full order and trade in
589         purapService.prorateForTradeInAndFullOrderDiscount(invoice);
590 
591         // do proration for payment terms discount
592         if (updateDiscount) {
593             //  calculateDiscount(invoice);
594         }
595 
596         //    distributeAccounting(invoice);
597     }
598 
599     @Override
600     protected void distributeAccounting(InvoiceDocument invoiceDocument)  {
601         // update the account amounts before doing any distribution
602         purapAccountingService.updateAccountAmounts(invoiceDocument);
603         OleInvoiceDocument oleInvoiceDocument = (OleInvoiceDocument) invoiceDocument;
604         for (InvoiceItem item : (List<InvoiceItem>) invoiceDocument.getItems()) {
605             KualiDecimal totalAmount = KualiDecimal.ZERO;
606             KualiDecimal totalQty = KualiDecimal.ZERO;
607             KualiDecimal totalSurcharge = KualiDecimal.ZERO;
608             List<PurApAccountingLine> distributedAccounts = null;
609             List<SourceAccountingLine> summaryAccounts = null;
610             Set excludedItemTypeCodes = new HashSet();
611             boolean canProrate = false;
612             excludedItemTypeCodes.add(PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE);
613 
614             // skip above the line
615             if (item.getItemType().isLineItemIndicator()) {
616                 continue;
617             }
618             /*if (item.getExtendedPrice() == null || item.getExtendedPrice().compareTo(KualiDecimal.ZERO) == 0) {
619                 item.setSourceAccountingLines(new ArrayList<PurApAccountingLine>());
620             }*/
621             if ((ObjectUtils.isNotNull(item.getExtendedPrice())) && (KualiDecimal.ZERO.compareTo(item.getExtendedPrice()) != 0) && !"DISC".equals(item.getItemTypeCode())) {
622                 if ((StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE, item.getItemType().getItemTypeCode())) && (invoiceDocument.getGrandTotal() != null) && ((KualiDecimal.ZERO.compareTo(invoiceDocument.getGrandTotal()) != 0))) {
623 
624                     // No discount is applied to other item types other than item line
625                     // See KFSMI-5210 for details
626 
627                     // total amount should be the line item total, not the grand total
628                     totalAmount = invoiceDocument.getLineItemTotal();
629 
630                     // prorate item line accounts only
631                     Set includedItemTypeCodes = new HashSet();
632                     includedItemTypeCodes.add(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE);
633                     summaryAccounts = olePurapAccountingService.generateSummaryIncludeItemTypesAndNoZeroTotals(invoiceDocument.getItems(), includedItemTypeCodes);
634                     distributedAccounts = olePurapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, PurapConstants.PRORATION_SCALE, InvoiceAccount.class);
635 
636                     // update amounts on distributed accounts
637                     purapAccountingService.updateAccountAmountsWithTotal(distributedAccounts, item.getTotalAmount());
638                 } else {
639                     OleInvoiceItem poi = null;
640                     if (item.getItemType().isLineItemIndicator()) {
641                         List<OleInvoiceItem> items = invoiceDocument.getItems();
642                         poi = items.get(item.getItemLineNumber() - 1);
643                         // throw error if line numbers don't match
644                         // MSU Contribution DTT-3014 OLEMI-8483 OLECNTRB-974
645                 /*
646                  * List items = po.getItems(); if (items != null) { for (Object object : items) { PurchaseOrderItem item =
647                  * (PurchaseOrderItem) object; if (item != null && item.getItemLineNumber().equals(this.getItemLineNumber())) { poi
648                  * = item; break; } } }
649                  */
650                     } else {
651                         poi = (OleInvoiceItem) SpringContext.getBean(PurapService.class).getBelowTheLineByType(invoiceDocument, item.getItemType());
652                     }
653 
654                     List<PurApItem> items = new ArrayList<>();
655 /*
656                     for (OlePurchaseOrderDocument olePurchaseOrderDocument : invoiceDocument.getPurchaseOrderDocuments()) {
657                         for (OlePurchaseOrderItem purItem : (List<OlePurchaseOrderItem>) olePurchaseOrderDocument.getItems()) {
658                             if (purItem.isItemForInvoice()) {
659                                 items.add(purItem);
660                                 if (purItem.getItemQuantity() != null) {
661                                     totalQty = totalQty.add(purItem.getItemQuantity());
662                                 }
663                             }
664                         }
665                     }*/
666                     if (items.size() == 0) {
667                         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
668                             if(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator() ) {
669                                 //     invoiceItem.setRelatedViews(null);
670                                 if (invoiceItem.getItemQuantity() != null) {
671                                     totalQty = totalQty.add(invoiceItem.getItemQuantity());
672                                 }
673                                 if (invoiceItem.getItemListPrice().isNonZero()) {
674                                     canProrate = true;
675                                 }
676                             }
677 
678                             if (!(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) && invoiceItem.getExtendedPrice()!=null) {
679                                 totalSurcharge = totalSurcharge.add(invoiceItem.getExtendedPrice());
680                             }
681                             if (invoiceItem.getItemUnitPrice() != null ) {
682                                 if (invoiceItem.getItemUnitPrice().compareTo(BigDecimal.ZERO) != 0 || oleInvoiceDocument.isProrateQty()) {
683                                     items.add(invoiceItem);
684                                 }
685 
686                             }
687                         }
688                     }
689                     else {
690                         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
691                             if (!(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator())) {
692                                 if (invoiceItem.getItemUnitPrice() != null && invoiceItem.getItemUnitPrice().compareTo(BigDecimal.ZERO) != 0) {
693                                     items.add(invoiceItem);
694                                 }
695                                 if(invoiceItem.getExtendedPrice()!=null){
696                                     totalSurcharge = totalSurcharge.add(invoiceItem.getExtendedPrice());
697                                 }
698                             }
699                         }
700                     }
701 
702                     totalAmount = getTotalDollarAmountWithExclusionsSubsetItems(null, true, items);//invoiceDocument.getTotalDollarAmountAboveLineItems();
703                     totalAmount = totalAmount.subtract(totalSurcharge);
704                     purapAccountingService.updateAccountAmounts(invoiceDocument);
705                     if(oleInvoiceDocument.isProrateManual()){
706                         summaryAccounts = olePurapAccountingService.generateSummaryForManual(items);
707                         distributedAccounts = olePurapAccountingService.generateAccountDistributionForProrationByManual(summaryAccounts,InvoiceAccount.class);
708                     }
709 
710                     if(oleInvoiceDocument.isProrateDollar() || oleInvoiceDocument.isProrateQty()){
711                         summaryAccounts = olePurapAccountingService.generateSummary(items);
712                     }
713                     if(oleInvoiceDocument.isProrateDollar() && totalAmount.isNonZero()){
714                         distributedAccounts = olePurapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, PurapConstants.PRORATION_SCALE, InvoiceAccount.class);
715                     }else if(oleInvoiceDocument.isProrateQty() && totalQty.isNonZero()) {
716                         distributedAccounts = olePurapAccountingService.generateAccountDistributionForProrationByQty(summaryAccounts, totalQty, PurapConstants.PRORATION_SCALE, InvoiceAccount.class);
717                     }
718                 }
719                 if (CollectionUtils.isNotEmpty(distributedAccounts) && !oleInvoiceDocument.isProrateManual()) {
720                         item.setSourceAccountingLines(distributedAccounts);
721                 }
722                 else if (!oleInvoiceDocument.isNoProrate() && !oleInvoiceDocument.isProrateManual()) {
723                     item.setSourceAccountingLines(new ArrayList<PurApAccountingLine>());
724                 }
725             }
726             // update the item
727             purapAccountingService.updateItemAccountAmounts(item);
728 
729         }
730         // update again now that distribute is finished. (Note: we may not need this anymore now that I added updateItem line above
731         purapAccountingService.updateAccountAmounts(invoiceDocument);
732 
733     }
734 
735 
736     /**
737      * This method...
738      *
739      * @param excludedTypes
740      * @param includeBelowTheLine
741      * @param itemsForTotal
742      * @return
743      */
744     public KualiDecimal getTotalDollarAmountWithExclusionsSubsetItems(String[] excludedTypes, boolean includeBelowTheLine, List<PurApItem> itemsForTotal) {
745         if (excludedTypes == null) {
746             excludedTypes = new String[]{};
747         }
748 
749         KualiDecimal total = new KualiDecimal(BigDecimal.ZERO);
750         for (PurApItem item : itemsForTotal) {
751             item.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
752             ItemType it = item.getItemType();
753             if ((includeBelowTheLine || it.isLineItemIndicator()) && !ArrayUtils.contains(excludedTypes, it.getItemTypeCode())) {
754                 KualiDecimal totalAmount = item.getTotalAmount();
755                 KualiDecimal itemTotal = (totalAmount != null) ? totalAmount : KualiDecimal.ZERO;
756                 total = total.add(itemTotal);
757             }
758         }
759         return total;
760     }
761 
762     /**
763      * @see org.kuali.ole.module.purap.document.service.InvoiceService#getInvoiceByDocumentNumber(String)
764      */
765     @Override
766     public OleInvoiceDocument getInvoiceByDocumentNumber(String documentNumber) {
767         LOG.debug("getInvoiceByDocumentNumber() started");
768 
769         if (ObjectUtils.isNotNull(documentNumber)) {
770             try {
771                 OleInvoiceDocument doc = (OleInvoiceDocument) documentService.getByDocumentHeaderId(documentNumber);
772                 return doc;
773             } catch (WorkflowException e) {
774                 String errorMessage = "Error getting invoice document from document service";
775                 LOG.error("Exception While getting invoice document based on document number " + errorMessage, e);
776                 throw new RuntimeException(errorMessage, e);
777             }
778         }
779         return null;
780     }
781 
782     /**
783      * This method is validates the prorate surchanges if prorate by manual
784      *
785      * @see org.kuali.ole.select.document.service.OleInvoiceService#validateProratedSurcharge(org.kuali.ole.select.document.OleInvoiceDocument)
786      */
787     @Override
788     public boolean validateProratedSurcharge(OleInvoiceDocument invoiceDocument) {
789 
790         List<OleInvoiceItem> items = invoiceDocument.getItems();
791         boolean manuvalProrateValidFlag = false;
792         BigDecimal proratedSurchargeAmount = new BigDecimal(0);
793         for (int i = 0; items.size() > i; i++) {
794             OleInvoiceItem item = (OleInvoiceItem) invoiceDocument.getItem(i);
795             if ("".equals(item.getItemTitleId()) || item.getItemTitleId() == null) {
796                 if (item.getItemUnitPrice() != null && !"".equals(item.getItemUnitPrice())) {
797                     manuvalProrateValidFlag = true;
798                 }
799             }
800         }
801         if (manuvalProrateValidFlag) {
802             for (int i = 0; items.size() > i; i++) {
803                 OleInvoiceItem item = (OleInvoiceItem) invoiceDocument.getItem(i);
804                 if (!"".equals(item.getItemTitleId()) && item.getItemTitleId() != null) {
805                     if (item.getItemSurcharge() != null && item.getItemSurcharge().compareTo(new BigDecimal(0)) != 0) {
806                         proratedSurchargeAmount = proratedSurchargeAmount.add(item.getItemSurcharge());
807                     }
808                 }
809             }
810             if (proratedSurchargeAmount.compareTo(new BigDecimal(0)) == 0) {
811                 manuvalProrateValidFlag = false;
812                 invoiceDocument.setProrateBy(null);
813                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, OLEKeyConstants.ERROR_PAYMENT_REQUEST_TOTAL_MISMATCH);
814             }
815         }
816         return manuvalProrateValidFlag;
817     }
818 
819     /**
820      * This method is for caluclate the total amount without select proprate by Quantity,doller and manual
821      *
822      * @see org.kuali.ole.select.document.service.OleInvoiceService#calculateWithoutProrates(org.kuali.ole.select.document.OleInvoiceDocument)
823      */
824     @Override
825     public void calculateWithoutProrates(OleInvoiceDocument invoiceDocument) {
826         LOG.debug("Inside Calculation for with out  prorate");
827         BigDecimal addChargeItem = BigDecimal.ZERO;
828         List<OleInvoiceItem> items = invoiceDocument.getItems();
829 
830         for (OleInvoiceItem item : items) {
831             if (item.getItemTitleId() != null && !"".equals(item.getItemTitleId())) {
832                 if (!item.getItemListPrice().equals(item.getExtendedPrice())) {
833                     item.setItemUnitPrice(item.getItemListPrice().bigDecimalValue());
834                     item.setExtendedPrice(item.getItemListPrice());
835                     item.setItemSurcharge(BigDecimal.ZERO);
836                 }
837             }
838         }
839 
840         for (OleInvoiceItem item : items) {
841             if (!item.getItemType().isQuantityBasedGeneralLedgerIndicator()
842                     && !item.getItemTypeCode().equalsIgnoreCase(
843                     PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE)
844                     && item.getItemUnitPrice() != null) {
845                 addChargeItem = addChargeItem.add(item.getItemUnitPrice());
846             }
847         }
848         List<BigDecimal> newUnitPriceList = new ArrayList<>();
849         BigDecimal totalExtPrice = new BigDecimal(0);
850         BigDecimal newUnitPrice = new BigDecimal(0);
851         BigDecimal extPrice = new BigDecimal(0);
852         BigDecimal unitPricePercent = new BigDecimal(0);
853         BigDecimal hundred = new BigDecimal(100);
854         BigDecimal one = new BigDecimal(1);
855         BigDecimal totalSurCharge = new BigDecimal(0);
856         BigDecimal totalItemQuantity = new BigDecimal(0);
857         BigDecimal itemSurchargeCons = new BigDecimal(0);
858         for (int i = 0; items.size() > i; i++) {
859             OleInvoiceItem item = (OleInvoiceItem) invoiceDocument.getItem(i);
860             if ((item.getItemType().isQuantityBasedGeneralLedgerIndicator())
861                     && !ObjectUtils.isNull(item.getItemQuantity())) {
862                 if (item.getItemSurcharge() == null) {
863                     item.setItemSurcharge(BigDecimal.ZERO);
864                 }
865                 if (invoiceDocument.getProrateBy() == null) {
866                     if (item.getItemDiscount() == null) {
867                         item.setItemDiscount(KualiDecimal.ZERO);
868                     }
869                     if (item.getItemDiscountType() != null
870                             && item.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
871                         newUnitPrice =SpringContext.getBean(OlePurapService.class).calculateDiscount(item).setScale(2, BigDecimal.ROUND_HALF_UP);
872                     } else {
873                         newUnitPrice = SpringContext.getBean(OlePurapService.class).calculateDiscount(item).setScale(2, BigDecimal.ROUND_HALF_UP);
874                     }
875                     newUnitPriceList.add(newUnitPrice);
876                     extPrice = newUnitPrice.multiply(item.getItemQuantity().bigDecimalValue());
877                     totalExtPrice = totalExtPrice.add(extPrice);
878                 }
879                 totalSurCharge = totalSurCharge.add(item.getItemQuantity().bigDecimalValue()
880                         .multiply(item.getItemSurcharge()));
881             }
882         }
883         for (int i = 0, j = 0; items.size() > i; i++) {
884             OleInvoiceItem item = (OleInvoiceItem) invoiceDocument.getItem(i);
885             if (item.getItemType().isQuantityBasedGeneralLedgerIndicator() && newUnitPriceList.size() > j
886                     && !ObjectUtils.isNull(item.getItemQuantity())) {
887                 if (item.getItemSurcharge() != null) {
888                     item.setItemUnitPrice(newUnitPriceList.get(j).add(item.getItemSurcharge()));
889                 }
890                 j++;
891             }
892         }
893         LOG.debug("Leaving Calculation for with out  prorate");
894     }
895 
896     public void createPaymentRequestOrCreditMemoDocument(OleInvoiceDocument inv) {
897         List<OleInvoiceItem> negativeItems = new ArrayList<>();
898         List<OleInvoiceItem> positiveItems = new ArrayList<>();
899         List<OleInvoiceItem> lineItems = new ArrayList<>();
900         List<OleInvoiceItem> positiveLineItems = new ArrayList<>();
901         List<OleInvoiceItem> negativeLineItems = new ArrayList<>();
902         Boolean isItemLevelDebit = null;
903         Boolean isAdditionalChargeLevelDebit = null;
904         Boolean isItemLevelCredit = null;
905         Boolean isAdditionalChargeLevelCredit = null;
906         BigDecimal firstPOTotalUnitPrice=BigDecimal.ZERO;
907         for (OleInvoiceItem item : (List<OleInvoiceItem>) inv.getItems()) {
908             if (item.isDebitItem()  &&
909                     (item.getItemListPrice().isNonZero() ||
910                     (item.getItemUnitPrice()!=null && item.getItemUnitPrice().compareTo(BigDecimal.ZERO)!=0))){
911 
912                 if(lineItems.size()==0 && item.getPurchaseOrderIdentifier()!=null){
913                     lineItems.add(item);
914                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.add(item.getItemUnitPrice());
915                 }else if(lineItems.size()>0 && item.getPurchaseOrderIdentifier()!=null &&
916                         lineItems.get(0).getPurchaseOrderIdentifier().compareTo(item.getPurchaseOrderIdentifier())==0){
917                     lineItems.add(item);
918                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.add(item.getItemUnitPrice());
919                 }
920 
921                 if(item.getItemType().isQuantityBasedGeneralLedgerIndicator()){
922                     if(isItemLevelDebit==null){
923                         isItemLevelDebit = true;
924                     }
925                     isItemLevelDebit &= item.isDebitItem();
926 
927                     if(lineItems.size()>0 && item.getItemListPrice().isNonZero()){
928                         positiveLineItems.add(item);
929                     }
930                 }
931                 if(item.getItemType().isAdditionalChargeIndicator()){
932                     if(isAdditionalChargeLevelDebit==null){
933                         isAdditionalChargeLevelDebit = true;
934                     }
935                     isAdditionalChargeLevelDebit &= item.isDebitItem();
936                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.add(item.getItemUnitPrice());
937 
938                 }
939                 if(item.getItemListPrice().isNonZero()){
940                     positiveItems.add(item);
941                 }
942 
943             }
944             else if(!item.isDebitItem() &&
945                     (item.getItemListPrice().isNonZero() ||
946                     (item.getItemUnitPrice()!=null && item.getItemUnitPrice().compareTo(BigDecimal.ZERO)!=0))){
947 
948                 if(lineItems.size()==0 && item.getPurchaseOrderIdentifier()!=null){
949                     lineItems.add(item);
950                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.subtract(item.getItemUnitPrice());
951                 }else if(lineItems.size()>0 && item.getPurchaseOrderIdentifier()!=null &&
952                         lineItems.get(0).getPurchaseOrderIdentifier().compareTo(item.getPurchaseOrderIdentifier())==0){
953                     lineItems.add(item);
954                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.add(item.getItemUnitPrice());
955                 }
956 
957                 if(item.getItemType().isQuantityBasedGeneralLedgerIndicator()){
958                     if(isItemLevelCredit==null){
959                         isItemLevelCredit = true;
960                     }
961                     isItemLevelCredit &= !item.isDebitItem();
962 
963                     if(lineItems.size()>0 && item.getItemListPrice().isNonZero()){
964                         negativeLineItems.add(item);
965                     }
966                 }
967                 if(item.getItemType().isAdditionalChargeIndicator()){
968                     if(isAdditionalChargeLevelCredit==null){
969                         isAdditionalChargeLevelCredit = true;
970                     }
971                     isAdditionalChargeLevelCredit &= !item.isDebitItem();
972                     firstPOTotalUnitPrice = firstPOTotalUnitPrice.subtract(item.getItemUnitPrice());
973 
974                 }
975                 if(item.getItemListPrice().isNonZero()){
976                     negativeItems.add(item);
977                 }
978             }
979         }
980         positiveLineItems.removeAll(lineItems);
981         negativeLineItems.removeAll(lineItems);
982         if((isItemLevelDebit == null && isAdditionalChargeLevelDebit!=null && isAdditionalChargeLevelDebit) ||
983                 (isAdditionalChargeLevelDebit == null && isItemLevelDebit!=null && isItemLevelDebit) ||
984                 (isItemLevelCredit == null && isAdditionalChargeLevelCredit!=null && isAdditionalChargeLevelCredit) ||
985                 (isAdditionalChargeLevelCredit == null && isItemLevelCredit!=null && isItemLevelCredit)
986                         && !(isItemLevelCredit!=null && isItemLevelCredit && isItemLevelDebit!=null && isItemLevelDebit)){
987             if(new KualiDecimal(firstPOTotalUnitPrice).isNegative()){
988                 createCreditMemoDocument(inv, lineItems,true);
989             }else{
990                 createPaymentRequestDocument(inv, lineItems,true);
991             }
992             if (positiveLineItems.size() > 0) {
993                 createPaymentRequestDocument(inv, positiveLineItems,false);
994             }
995             if (negativeLineItems.size() > 0) {
996                 createCreditMemoDocument(inv, negativeLineItems,false);
997             }
998         }else{
999             if (positiveItems.size() > 0) {
1000                 createPaymentRequestDocument(inv, positiveItems,false);
1001             }
1002             if (negativeItems.size() > 0) {
1003                 createCreditMemoDocument(inv, negativeItems,false);
1004             }
1005         }
1006     }
1007 
1008     public void createPaymentRequestDocument(OleInvoiceDocument inv, List<OleInvoiceItem> items,boolean flag) {
1009 
1010         if (LOG.isDebugEnabled()) {
1011             LOG.debug("Creating Payment Request document");
1012         }
1013 
1014         KNSGlobalVariables.getMessageList().clear();
1015 
1016         //   validateInvoiceOrderValidForPREQCreation(inv);
1017 
1018         if (LOG.isDebugEnabled()) {
1019             if (inv.isInvoiceCancelIndicator()) {
1020                 LOG.debug("Not possible to convert cancelled Invoice details into payment request");
1021             } else {
1022                 LOG.debug("Payment request document creation validation succeeded");
1023             }
1024         }
1025 
1026         if (inv.isInvoiceCancelIndicator()) {
1027             LOG.debug("Invoice Cancelled, Payment Request not created");
1028         }
1029         if (LOG.isDebugEnabled()) {
1030             LOG.debug("Total Dollar Amount above line items >>>>" + inv.getTotalDollarAmountAboveLineItems());
1031         }
1032         Integer invId = inv.getPurapDocumentIdentifier();
1033         Integer poId = 0;
1034         List<Integer> poList = new ArrayList();
1035 
1036         List<OleInvoiceItem> oleInvoiceItemList = items;
1037         KualiDecimal invItemCount = new KualiDecimal(0);
1038         for (OleInvoiceItem oleInvoiceItem : oleInvoiceItemList) {
1039             if (oleInvoiceItem.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE)) {
1040                 invItemCount = invItemCount.add(oleInvoiceItem.getItemQuantity());
1041             }
1042             if ((!(poList.contains(oleInvoiceItem.getPurchaseOrderIdentifier()))) && oleInvoiceItem.getExtendedPrice().isNonZero()) {
1043                 poList.add(oleInvoiceItem.getPurchaseOrderIdentifier());
1044             }
1045         }
1046 
1047         String prorateBy = inv.getProrateBy();
1048 
1049         OlePaymentRequestDocument preqDoc = null;
1050         Integer invPoId = 0;
1051         for (Integer purchaseOrderId : poList) {
1052             if (purchaseOrderId != null && invPoId.compareTo(purchaseOrderId) != 0) {
1053                 try {
1054                     preqDoc = (OlePaymentRequestDocument) SpringContext.getBean(DocumentService.class).getNewDocument("OLE_PREQ");
1055                     preqDoc.setImmediatePaymentIndicator(inv.getImmediatePaymentIndicator());
1056                     preqDoc.setInvoiceDate(inv.getInvoiceDate());
1057                     preqDoc.setInvoiceNumber(inv.getInvoiceNumber());
1058                     preqDoc.setVendorInvoiceAmount(inv.getVendorInvoiceAmount().abs());
1059                     preqDoc.setVendorDetail(inv.getVendorDetail());
1060                     preqDoc.setVendorName(inv.getVendorName());
1061                     preqDoc.setVendorHeaderGeneratedIdentifier(inv.getVendorHeaderGeneratedIdentifier());
1062                     preqDoc.setVendorDetailAssignedIdentifier(inv.getVendorDetailAssignedIdentifier());
1063                     preqDoc.setVendorNumber(inv.getVendorNumber());
1064                     preqDoc.setVendorHeaderGeneratedIdentifier(inv.getVendorHeaderGeneratedIdentifier());
1065                     preqDoc.setVendorDetailAssignedIdentifier(inv.getVendorDetailAssignedIdentifier());
1066                     preqDoc.setVendorPaymentTerms(inv.getVendorPaymentTerms());
1067                     if (inv.getVendorPaymentTerms() != null) {
1068                         preqDoc.setVendorPaymentTermsCode(inv.getVendorPaymentTerms().getVendorPaymentTermsCode());
1069                     }
1070                     preqDoc.setVendorShippingTitleCode(inv.getVendorShippingTitleCode());
1071                     preqDoc.setVendorShippingPaymentTerms(inv.getVendorShippingPaymentTerms());
1072                     preqDoc.setVendorCityName(inv.getVendorCityName());
1073                     preqDoc.setVendorLine1Address(inv.getVendorLine1Address());
1074                     preqDoc.setVendorLine2Address(inv.getVendorLine2Address());
1075                     preqDoc.setVendorAttentionName(inv.getVendorAttentionName());
1076                     preqDoc.setVendorPostalCode(inv.getVendorPostalCode());
1077                     preqDoc.setVendorStateCode(inv.getVendorStateCode());
1078                     preqDoc.setVendorAttentionName(inv.getVendorAttentionName());
1079                     preqDoc.setVendorAddressInternationalProvinceName(inv.getVendorAddressInternationalProvinceName());
1080                     preqDoc.setVendorCountryCode(inv.getVendorCountryCode());
1081                     preqDoc.setVendorCountry(inv.getVendorCountry());
1082                     preqDoc.setVendorCustomerNumber(inv.getVendorCustomerNumber());
1083                     preqDoc.setAccountsPayableProcessorIdentifier(inv.getAccountsPayableProcessorIdentifier());
1084                     preqDoc.setProcessingCampusCode(inv.getProcessingCampusCode());
1085                     preqDoc.setPurchaseOrderIdentifier(purchaseOrderId);
1086                     //
1087                     //preqDoc.setClosePurchaseOrderIndicator(oleInvoiceItem.isClosePurchaseOrderIndicator());
1088                     preqDoc.setPaymentRequestPayDate(inv.getInvoicePayDate());
1089                     preqDoc.setImmediatePaymentIndicator(inv.getImmediatePaymentIndicator());
1090                     preqDoc.setPaymentRequestCostSource(inv.getInvoiceCostSource());
1091                     preqDoc.setProrateBy(inv.getProrateBy());
1092                     preqDoc.setProrateDollar(inv.isProrateDollar());
1093                     preqDoc.setProrateQty(inv.isProrateQty());
1094                     preqDoc.setProrateManual(inv.isProrateManual());
1095                     preqDoc.setNoProrate(inv.isNoProrate());
1096                     preqDoc.setForeignVendorInvoiceAmount(inv.getForeignVendorInvoiceAmount());
1097 
1098 
1099                     if (inv.getPaymentMethodId() != null) {
1100                         OlePaymentMethod olePaymentMethod = SpringContext.getBean(BusinessObjectService.class)
1101                                 .findBySinglePrimaryKey(OlePaymentMethod.class, inv.getPaymentMethodId());
1102                         preqDoc.setPaymentMethod(olePaymentMethod);
1103                         preqDoc.getPaymentMethod().setPaymentMethodId(olePaymentMethod.getPaymentMethodId());
1104                         preqDoc.setPaymentMethodId(olePaymentMethod.getPaymentMethodId());
1105                     }
1106 
1107                     preqDoc.setInvoiceIdentifier(inv.getPurapDocumentIdentifier());
1108                     preqDoc.setBankCode(inv.getBankCode());
1109                     preqDoc.setBank(inv.getBank());
1110                 } catch (WorkflowException e) {
1111                     String extraDescription = "Error=" + e.getMessage();
1112                     LOG.error("Exception creating Payment request document - " + e.getMessage());
1113                 }
1114 
1115                 Map invItemMap = new HashMap();
1116                 invItemMap.put(PurapConstants.PRQSDocumentsStrings.PUR_ID, inv.getPurapDocumentIdentifier());
1117                 invItemMap.put(PurapConstants.PRQSDocumentsStrings.PO_ID, purchaseOrderId);
1118                 List<OleInvoiceItem> invoiceItems = (List<OleInvoiceItem>) businessObjectService.findMatchingOrderBy(OleInvoiceItem.class, invItemMap, PurapConstants.PRQSDocumentsStrings.PO_ID, true);
1119 
1120                 KualiDecimal itemCount = new KualiDecimal(0);
1121                 KualiDecimal itemPrice = new KualiDecimal(0);
1122                 PurchaseOrderDocument poDoc = inv.getPurchaseOrderDocument(purchaseOrderId);
1123                 if (poDoc == null) {
1124                     throw new RuntimeException("Purchase Order document (invPoId=" + invPoId + ") does not exist in the system");
1125                 }
1126 
1127                 preqDoc.getDocumentHeader().setDocumentDescription(createPreqDocumentDescription(poDoc.getPurapDocumentIdentifier(), inv.getVendorName()));
1128 
1129                 try {
1130                     preqDoc.updateAndSaveAppDocStatus(PurapConstants.PaymentRequestStatuses.APPDOC_IN_PROCESS);
1131                 } catch (WorkflowException we) {
1132                     throw new RuntimeException("Unable to save route status data for document: " + preqDoc.getDocumentNumber(), we);
1133                 }
1134 
1135                 SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedCalculateAccountsPayableEvent(preqDoc));
1136 
1137                 SpringContext.getBean(PaymentRequestService.class).calculatePaymentRequest(preqDoc, false);
1138                 HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = SpringContext.getBean(AccountsPayableService.class).expiredOrClosedAccountsList(poDoc);
1139                 if (expiredOrClosedAccountList == null) {
1140                     expiredOrClosedAccountList = new HashMap();
1141                 }
1142 
1143                 if (LOG.isDebugEnabled()) {
1144                     LOG.debug(expiredOrClosedAccountList.size() + " accounts has been found as Expired or Closed");
1145                 }
1146                 List<OlePaymentRequestItem> olePaymentRequestItems = new ArrayList<>();
1147                 // int itemLineNumberCount = 0;
1148                 for (OleInvoiceItem invoiceItem : invoiceItems) {
1149                     if ((flag || invoiceItem.isDebitItem()) && invoiceItem.getExtendedPrice().isNonZero()) {
1150                         OlePaymentRequestItem olePaymentRequestItem = new OlePaymentRequestItem(invoiceItem, preqDoc, expiredOrClosedAccountList);
1151                         if(flag && !invoiceItem.isDebitItem()){
1152                             olePaymentRequestItem.setItemListPrice(olePaymentRequestItem.getItemListPrice().negated());
1153                             olePaymentRequestItem.setItemUnitPrice(olePaymentRequestItem.getItemUnitPrice().negate());
1154                             olePaymentRequestItem.setExtendedPrice(olePaymentRequestItem.getExtendedPrice().negated());
1155                             for(PurApAccountingLine purApAccountingLine : olePaymentRequestItem.getSourceAccountingLines()){
1156                                 purApAccountingLine.setAmount(purApAccountingLine.getAmount().negated());
1157                             }
1158                         }
1159                         olePaymentRequestItems.add(olePaymentRequestItem);
1160                         if (invoiceItem.isReopenPurchaseOrderIndicator()) {
1161                             preqDoc.setReopenPurchaseOrderIndicator(invoiceItem.isReopenPurchaseOrderIndicator());
1162                         }
1163                         if (invoiceItem.isClosePurchaseOrderIndicator()) {
1164                             preqDoc.setClosePurchaseOrderIndicator(invoiceItem.isClosePurchaseOrderIndicator());
1165                         }
1166                         if (preqDoc.getAccountsPayablePurchasingDocumentLinkIdentifier() == null) {
1167                             preqDoc.setAccountsPayablePurchasingDocumentLinkIdentifier(invoiceItem.getAccountsPayablePurchasingDocumentLinkIdentifier());
1168                         }
1169                         preqDoc.setReceivingDocumentRequiredIndicator(invoiceItem.isReceivingDocumentRequiredIndicator());
1170                     }
1171                 }
1172 
1173                 invPoId = purchaseOrderId;
1174                 preqDoc.setItems(olePaymentRequestItems);
1175 
1176                 try {
1177                     SpringContext.getBean(PaymentRequestService.class).populateAndSavePaymentRequest(preqDoc);
1178 
1179                     SpringContext.getBean(PaymentRequestService.class).autoApprovePaymentRequest(preqDoc);
1180                 } catch (WorkflowException e) {
1181                     e.printStackTrace();
1182                 } catch (ValidationException e) {
1183                     String extraDescription = GlobalVariables.getMessageMap().toString();
1184                 }
1185             }
1186 
1187 
1188             if (GlobalVariables.getMessageMap().hasErrors()) {
1189 
1190                 LOG.error("***************Error in rules processing - " + GlobalVariables.getMessageMap());
1191                 Map<String, AutoPopulatingList<ErrorMessage>> errorMessages = GlobalVariables.getMessageMap().getErrorMessages();
1192 
1193                 String errors = errorMessages.toString();
1194             }
1195 
1196             if (KNSGlobalVariables.getMessageList().size() > 0) {
1197                 if (LOG.isDebugEnabled()) {
1198                     LOG.debug("Payment request contains " + KNSGlobalVariables.getMessageList().size() + " warning message(s)");
1199                     for (int i = 0; i < KNSGlobalVariables.getMessageList().size(); i++) {
1200                         LOG.debug("Warning " + i + "  - " + KNSGlobalVariables.getMessageList().get(i));
1201                     }
1202                 }
1203             }
1204 
1205 
1206             String routingAnnotation = null;
1207             if (!inv.isInvoiceCancelIndicator()) {
1208                 routingAnnotation = "Routed by New Invoice Creation";
1209             }
1210         }
1211     }
1212 
1213 
1214     public void populateInvoice(OleInvoiceDocument invoiceDocument) {
1215 
1216         PurchaseOrderDocument purchaseOrderDocument = invoiceDocument.getPurchaseOrderDocument();
1217 
1218         // make a call to search for expired/closed accounts
1219         HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = getAccountsPayableService().getExpiredOrClosedAccountList(invoiceDocument);
1220 
1221         //SpringContext.getBean(OleInvoiceService.class).populateInvoiceFromPurchaseOrders(invoiceDocument,expiredOrClosedAccountList);
1222 
1223         // invoiceDocument.getDocumentHeader().setDocumentDescription(createPreqDocumentDescription(invoiceDocument.getPurchaseOrderIdentifier(), invoiceDocument.getVendorName()));
1224 
1225         // write a note for expired/closed accounts if any exist and add a message stating there were expired/closed accounts at the
1226         // top of the document
1227         getAccountsPayableService().generateExpiredOrClosedAccountNote(invoiceDocument, expiredOrClosedAccountList);
1228 
1229         // set indicator so a message is displayed for accounts that were replaced due to expired/closed status
1230         if (!expiredOrClosedAccountList.isEmpty()) {
1231             invoiceDocument.setContinuationAccountIndicator(true);
1232         }
1233 
1234         // add discount item
1235         calculateDiscount(invoiceDocument);
1236         // distribute accounts (i.e. proration)
1237         distributeAccounting(invoiceDocument);
1238 
1239         // set bank code to default bank code in the system parameter
1240         Bank defaultBank = bankService.getDefaultBankByDocType(invoiceDocument.getClass());
1241         if (defaultBank != null) {
1242             invoiceDocument.setBankCode(defaultBank.getBankCode());
1243             invoiceDocument.setBank(defaultBank);
1244         }
1245     }
1246 
1247     /*
1248     * This method is overridden to populate Ole InvoiceDocument from PurchaseOrder Document
1249     * @see org.kuali.ole.module.purap.document.InvoiceDocument#populateInvoiceFromPurchaseOrder(org.kuali.ole.module.purap.document.PurchaseOrderDocument, java.util.HashMap)
1250     */
1251     public OleInvoiceDocument populateInvoiceFromPurchaseOrders(OleInvoiceDocument invoiceDocument,
1252                                                                 HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
1253         LOG.debug("Inside populateInvoiceFromPurchaseOrders method ");
1254         List<OleInvoiceItem> items = new ArrayList<>();
1255         if (expiredOrClosedAccountList == null) {
1256             expiredOrClosedAccountList = new HashMap<>();
1257         }
1258 
1259         List<OleInvoiceItem> invoiceItemList = new ArrayList<>();
1260         OleInvoiceItem oleInvoiceItem;
1261 
1262         for (int count = 0; count < invoiceDocument.getItems().size(); count++) {
1263             OleInvoiceItem invoiceditem = (OleInvoiceItem) invoiceDocument.getItems().get(count);
1264             if (!(invoiceditem.getItemType().getItemTypeCode().equals("ITEM"))) {
1265                 invoiceItemList.add(invoiceditem);
1266             }
1267         }
1268         invoiceDocument.setItems(invoiceItemList);
1269         if (invoiceDocument.getPurchaseOrderDocuments() != null && invoiceDocument.getPurchaseOrderDocuments().size() > 0) {
1270             for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
1271                 if (invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getItemUnitPrice() != null)
1272                     invoiceItem.setPurchaseOrderIdentifier(invoiceDocument.getPurchaseOrderDocuments().get(0).getPurapDocumentIdentifier());
1273             }
1274         }
1275 
1276         for (OlePurchaseOrderDocument po : invoiceDocument.getPurchaseOrderDocuments()) {
1277            /* if(this.encumberedItemExistsForInvoicing(po))
1278             {*/
1279             for (OlePurchaseOrderItem poi : (List<OlePurchaseOrderItem>) po.getItems()) {
1280                 // check to make sure it's eligible for payment (i.e. active and has encumbrance available
1281                 //if (this.poItemEligibleForAp(invoiceDocument, poi)) {
1282                 if (poi.isItemForInvoice()) {
1283                     OleInvoiceItem invoiceItem = new OleInvoiceItem(poi, invoiceDocument, expiredOrClosedAccountList);
1284 
1285                     invoiceItem.setClosePurchaseOrderIndicator(po.isClosePO());
1286                     invoiceItem.setReopenPurchaseOrderIndicator(po.getIsReOpenPO());
1287                     PurchasingCapitalAssetItem purchasingCAMSItem = po.getPurchasingCapitalAssetItemByItemIdentifier(poi.getItemIdentifier());
1288                     if (purchasingCAMSItem != null) {
1289                         invoiceItem.setCapitalAssetTransactionTypeCode(purchasingCAMSItem.getCapitalAssetTransactionTypeCode());
1290                     }
1291                     invoiceItem.setUseTaxIndicator(po.isUseTaxIndicator());
1292                     invoiceItem.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
1293                     invoiceItem.setPostingYear(po.getPostingYear());
1294                     invoiceItem.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
1295                     // copy usetaxitems over
1296                     invoiceItem.getUseTaxItems().clear();
1297                     for (PurApItemUseTax useTax : poi.getUseTaxItems()) {
1298                         invoiceItem.getUseTaxItems().add(useTax);
1299                     }
1300                     invoiceDocument.getItems().add(invoiceItem);
1301                     if (LOG.isDebugEnabled()) {
1302                         LOG.debug("Size**********************" + invoiceDocument.getItems().size());
1303                     }
1304                 }
1305 
1306 
1307                 //}
1308             }
1309             //}
1310             invoiceDocument.setInvoicePayDate(calculatePayDate(invoiceDocument.getInvoiceDate(), invoiceDocument.getVendorPaymentTerms()));
1311             invoiceDocument.setTotalDollarAmount(invoiceDocument.getTotalDollarAmount().add(po.getTotalDollarAmount()));
1312 
1313             if (invoiceDocument.getInvoiceTypeHdnId() != null && !invoiceDocument.getInvoiceTypeHdnId().isEmpty()) {
1314                 invoiceDocument.setInvoiceTypeId(Integer.valueOf(invoiceDocument.getInvoiceTypeHdnId()));
1315             }
1316             if (invoiceDocument.getPaymentMethodIdentifier() != null  && !invoiceDocument.getPaymentMethodIdentifier().isEmpty()) {
1317                 invoiceDocument.setPaymentMethodId(Integer.valueOf(invoiceDocument.getPaymentMethodIdentifier()));
1318             }
1319             if (invoiceDocument.getInvoiceSubTypeHdnId() != null && !invoiceDocument.getInvoiceSubTypeHdnId().isEmpty()) {
1320                 invoiceDocument.setInvoiceSubTypeId(Integer.valueOf(invoiceDocument.getInvoiceSubTypeHdnId()));
1321             }
1322 
1323             if (invoiceDocument.getInvoiceAmount() != null && !invoiceDocument.getInvoiceAmount().isEmpty()) {
1324                 invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getInvoiceAmount()));
1325             }
1326 
1327             if (invoiceDocument.getForeignInvoiceAmount() != null && !invoiceDocument.getForeignInvoiceAmount().isEmpty()) {
1328                 invoiceDocument.setForeignVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignInvoiceAmount()).bigDecimalValue());
1329                 if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyType())) {
1330                     if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyExchangeRate())) {
1331                         try {
1332                             Double.parseDouble(invoiceDocument.getInvoiceCurrencyExchangeRate());
1333                             invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(new BigDecimal(invoiceDocument.getInvoiceCurrencyExchangeRate()), 4, RoundingMode.HALF_UP)));
1334                         }
1335                         catch (NumberFormatException nfe) {
1336                             throw new RuntimeException("Invalid Exchange Rate", nfe);
1337                         }
1338                     }   else {
1339                         BigDecimal exchangeRate = getExchangeRate(invoiceDocument.getInvoiceCurrencyType()).getExchangeRate();
1340                         invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(exchangeRate, 4, RoundingMode.HALF_UP)));
1341                     }
1342                 }
1343             }
1344 
1345             Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(invoiceDocument.getClass());
1346             if (defaultBank != null) {
1347                 invoiceDocument.setBankCode(defaultBank.getBankCode());
1348                 invoiceDocument.setBank(defaultBank);
1349             }
1350         }
1351 
1352 
1353         invoiceDocument.setInvoicePayDate(this.calculatePayDate(invoiceDocument.getInvoiceDate(), invoiceDocument.getVendorPaymentTerms()));
1354 
1355 
1356          /* invoice total */
1357 
1358         BigDecimal addChargeItem=BigDecimal.ZERO;
1359         List<OleInvoiceItem> item = invoiceDocument.getItems();
1360         for(OleInvoiceItem invoiceditem : item){
1361             if(invoiceditem.getItemType().isAdditionalChargeIndicator() && invoiceditem.getExtendedPrice()!=null){
1362                 addChargeItem =addChargeItem.add(invoiceditem.getExtendedPrice().bigDecimalValue());
1363             }
1364         }
1365         if (invoiceDocument.getTotalDollarAmount() != null ) {
1366             invoiceDocument.setInvoiceItemTotal(invoiceDocument.getTotalDollarAmount().subtract(new KualiDecimal(addChargeItem)).toString());
1367             invoiceDocument.setDocumentTotalAmount(invoiceDocument.getTotalDollarAmount().toString());
1368         }
1369         /* invoice total */
1370 
1371         // add missing below the line
1372         //getPurapService().addBelowLineItems(invoiceDocument);
1373         //invoiceDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
1374 
1375         //fix up below the line items
1376         //getInvoiceService().removeIneligibleAdditionalCharges(invoiceDocument);
1377         LOG.debug("Leaving populateInvoiceFromPurchaseOrders method ");
1378         return invoiceDocument;
1379     }
1380 
1381     public String saveInvoiceDocument(OleInvoiceDocument invoiceDocument) throws WorkflowException {
1382         /*invoiceDocument = populateInvoiceFromPurchaseOrders(invoiceDocument, null);*/
1383         Long nextLinkIdentifier = SpringContext.getBean(SequenceAccessorService.class).getNextAvailableSequenceNumber("AP_PUR_DOC_LNK_ID");
1384         invoiceDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(nextLinkIdentifier.intValue());
1385 
1386         Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(invoiceDocument.getClass());
1387         if (defaultBank != null) {
1388             invoiceDocument.setBankCode(defaultBank.getBankCode());
1389             invoiceDocument.setBank(defaultBank);
1390         }
1391         Person currentUser = GlobalVariables.getUserSession().getPerson();
1392         invoiceDocument.setAccountsPayableProcessorIdentifier(currentUser.getPrincipalId());
1393         invoiceDocument.setProcessingCampusCode(currentUser.getCampusCode());
1394         DocumentService documentService = GlobalResourceLoader.getService(org.kuali.ole.OLEConstants.DOCUMENT_HEADER_SERVICE);
1395         invoiceDocument = (OleInvoiceDocument) documentService.saveDocument(invoiceDocument);
1396 
1397 
1398         return invoiceDocument.getDocumentNumber();
1399 
1400     }
1401 
1402     public String routeInvoiceDocument(OleInvoiceDocument invoiceDocument) throws WorkflowException {
1403         // invoiceDocument = populateInvoiceFromPurchaseOrders(invoiceDocument,null);
1404         Long nextLinkIdentifier = SpringContext.getBean(SequenceAccessorService.class).getNextAvailableSequenceNumber("AP_PUR_DOC_LNK_ID");
1405         invoiceDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(nextLinkIdentifier.intValue());
1406 
1407         Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(invoiceDocument.getClass());
1408         if (defaultBank != null) {
1409             invoiceDocument.setBankCode(defaultBank.getBankCode());
1410             invoiceDocument.setBank(defaultBank);
1411         }
1412         Person currentUser = GlobalVariables.getUserSession().getPerson();
1413         invoiceDocument.setAccountsPayableProcessorIdentifier(currentUser.getPrincipalId());
1414         invoiceDocument.setProcessingCampusCode(currentUser.getCampusCode());
1415 
1416         DocumentService documentService = GlobalResourceLoader.getService(org.kuali.ole.OLEConstants.DOCUMENT_HEADER_SERVICE);
1417         invoiceDocument = (OleInvoiceDocument) documentService.routeDocument(invoiceDocument, null, null);
1418 
1419 
1420         return invoiceDocument.getDocumentNumber();
1421 
1422     }
1423 
1424 
1425     public OleInvoiceDocument populateVendorDetail(String vendorNumber, OleInvoiceDocument oleInvoiceDocument) {
1426         Map<String, String> criteria = new HashMap<>();
1427         String[] vendorIds = vendorNumber != null ? vendorNumber.split("-") : new String[0];
1428         criteria.put(OLEConstants.InvoiceDocument.VENDOR_HEADER_IDENTIFIER, vendorIds.length > 0 ? vendorIds[0] : "");
1429         criteria.put(OLEConstants.InvoiceDocument.VENDOR_DETAIL_IDENTIFIER, vendorIds.length > 1 ? vendorIds[1] : "");
1430         VendorDetail vendorDetail = getBusinessObjectService().findByPrimaryKey(VendorDetail.class, criteria);
1431         if (vendorDetail != null) {
1432             oleInvoiceDocument.setVendorDetail(vendorDetail);
1433             oleInvoiceDocument.setVendorName(vendorDetail.getVendorName());
1434             oleInvoiceDocument.setVendorHeaderGeneratedIdentifier(vendorDetail.getVendorHeaderGeneratedIdentifier());
1435             oleInvoiceDocument.setVendorDetailAssignedIdentifier(vendorDetail.getVendorDetailAssignedIdentifier());
1436             oleInvoiceDocument.setVendorNumber(vendorDetail.getVendorNumber());
1437             oleInvoiceDocument.setVendorHeaderGeneratedIdentifier(vendorDetail.getVendorHeaderGeneratedIdentifier());
1438             oleInvoiceDocument.setVendorDetailAssignedIdentifier(vendorDetail.getVendorDetailAssignedIdentifier());
1439             oleInvoiceDocument.setVendorFaxNumber(vendorDetail.getDefaultFaxNumber());
1440             //oleInvoiceDocument.
1441             if (vendorDetail.getPaymentMethodId() != null) {
1442                 oleInvoiceDocument.setPaymentMethodIdentifier(vendorDetail.getPaymentMethodId().toString());
1443                 oleInvoiceDocument.setPaymentMethodId(vendorDetail.getPaymentMethodId());
1444             }
1445 
1446             if (vendorDetail.getVendorPaymentTerms() != null) {
1447                 oleInvoiceDocument.setVendorPaymentTerms(vendorDetail.getVendorPaymentTerms());
1448                 oleInvoiceDocument.setVendorPaymentTermsCode(vendorDetail.getVendorPaymentTerms().getVendorPaymentTermsCode());
1449 
1450             }
1451             if (vendorDetail.getVendorShippingTitle() != null) {
1452                 oleInvoiceDocument.setVendorShippingTitleCode(vendorDetail.getVendorShippingTitle().getVendorShippingTitleCode());
1453             }
1454             if (vendorDetail.getVendorShippingPaymentTerms() != null) {
1455                 oleInvoiceDocument.setVendorShippingPaymentTerms(vendorDetail.getVendorShippingPaymentTerms());
1456             }
1457 
1458             for (VendorAddress vendorAddress : vendorDetail.getVendorAddresses()) {
1459                 if (vendorAddress.isVendorDefaultAddressIndicator()) {
1460                     oleInvoiceDocument.setVendorCityName(vendorAddress.getVendorCityName());
1461                     oleInvoiceDocument.setVendorLine1Address(vendorAddress.getVendorLine1Address());
1462                     oleInvoiceDocument.setVendorLine2Address(vendorAddress.getVendorLine2Address());
1463                     oleInvoiceDocument.setVendorAttentionName(vendorAddress.getVendorAttentionName());
1464                     oleInvoiceDocument.setVendorPostalCode(vendorAddress.getVendorZipCode());
1465                     oleInvoiceDocument.setVendorStateCode(vendorAddress.getVendorStateCode());
1466                     oleInvoiceDocument.setVendorAttentionName(vendorAddress.getVendorAttentionName());
1467                     oleInvoiceDocument.setVendorAddressInternationalProvinceName(vendorAddress.getVendorAddressInternationalProvinceName());
1468                     oleInvoiceDocument.setVendorCountryCode(vendorAddress.getVendorCountryCode());
1469                     oleInvoiceDocument.setVendorCountry(vendorAddress.getVendorCountry());
1470                     //oleInvoiceDocument.setNoteLine1Text(vendorAddress.getNoteLine2Text
1471                 }
1472             }
1473         }
1474 
1475         return oleInvoiceDocument;
1476     }
1477 
1478 
1479     public void createCreditMemoDocument(OleInvoiceDocument invoiceDocument, List<OleInvoiceItem> items,boolean flag) {
1480         if (LOG.isDebugEnabled()) {
1481             LOG.debug("Creating Payment Request document");
1482         }
1483 
1484         KNSGlobalVariables.getMessageList().clear();
1485 
1486         //   validateInvoiceOrderValidForPREQCreation(inv);
1487 
1488         if (LOG.isDebugEnabled()) {
1489             if (invoiceDocument.isInvoiceCancelIndicator()) {
1490                 LOG.debug("Not possible to convert cancelled Invoice details into payment request");
1491             } else {
1492                 LOG.debug("Payment request document creation validation succeeded");
1493             }
1494         }
1495 
1496         if (invoiceDocument.isInvoiceCancelIndicator()) {
1497             LOG.debug("Invoice Cancelled, Payment Request not created");
1498         }
1499         if (LOG.isDebugEnabled()) {
1500             LOG.debug("Total Dollar Amount above line items >>>>" + invoiceDocument.getTotalDollarAmountAboveLineItems());
1501         }
1502         Integer invId = invoiceDocument.getPurapDocumentIdentifier();
1503         Integer poId = 0;
1504         List<Integer> poList = new ArrayList();
1505 
1506         List<OleInvoiceItem> oleInvoiceItemList = items;
1507         KualiDecimal invTotalAmount = new KualiDecimal(0);
1508         KualiDecimal invItemCount = new KualiDecimal(0);
1509         invTotalAmount = invoiceDocument.getTotalDollarAmountAboveLineItems();
1510         for (OleInvoiceItem oleInvoiceItem : oleInvoiceItemList) {
1511             if (oleInvoiceItem.getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE)) {
1512                 invItemCount = invItemCount.add(oleInvoiceItem.getItemQuantity());
1513             }
1514             if (!(poList.contains(oleInvoiceItem.getPurchaseOrderIdentifier()))) {
1515                 poList.add(oleInvoiceItem.getPurchaseOrderIdentifier());
1516             }
1517         }
1518 
1519         String prorateBy = invoiceDocument.getProrateBy();
1520         OleVendorCreditMemoDocument vendorCreditMemoDocument = null;
1521 
1522         Integer invoicePoId = 0;
1523         for (Integer purchaseOrderId : poList) {
1524             if (purchaseOrderId!=null && invoicePoId.compareTo(purchaseOrderId) != 0) {
1525 
1526                 try {
1527                     //GlobalVariables.setUserSession(new UserSession("ole-khuntley"));
1528                     String user = null;
1529                     if (GlobalVariables.getUserSession() == null) {
1530                         kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
1531                         user = kualiConfigurationService.getPropertyValueAsString(OleSelectNotificationConstant.ACCOUNT_DOCUMENT_INTIATOR);
1532                         GlobalVariables.setUserSession(new UserSession(user));
1533                     }
1534 
1535                     vendorCreditMemoDocument = (OleVendorCreditMemoDocument) SpringContext.getBean(DocumentService.class).getNewDocument("OLE_CM");
1536                     //  PaymentRequestDocument  preqDoc = new PaymentRequestDocument();
1537                     //vendorCreditMemoDocument.setCreditMemoDate(invoiceDocument.getInvoiceDate());
1538                     vendorCreditMemoDocument.setCreditMemoNumber(invoiceDocument.getInvoiceNumber());
1539                     //vendorCreditMemoDocument.setVendorInvoiceAmount(invoiceDocument.getVendorInvoiceAmount());
1540                     vendorCreditMemoDocument.setVendorDetail(invoiceDocument.getVendorDetail());
1541                     vendorCreditMemoDocument.setVendorName(invoiceDocument.getVendorName());
1542                     vendorCreditMemoDocument.setVendorHeaderGeneratedIdentifier(invoiceDocument.getVendorHeaderGeneratedIdentifier());
1543                     vendorCreditMemoDocument.setVendorDetailAssignedIdentifier(invoiceDocument.getVendorDetailAssignedIdentifier());
1544                     vendorCreditMemoDocument.setVendorNumber(invoiceDocument.getVendorNumber());
1545                     vendorCreditMemoDocument.setVendorHeaderGeneratedIdentifier(invoiceDocument.getVendorHeaderGeneratedIdentifier());
1546                     vendorCreditMemoDocument.setVendorDetailAssignedIdentifier(invoiceDocument.getVendorDetailAssignedIdentifier());
1547                     //vendorCreditMemoDocument.setVendorFaxNumber(invoiceDocument.getDefaultFaxNumber());
1548                     //oleInvoiceDocument.
1549                    /* vendorCreditMemoDocument.setVendorPaymentTerms(invoiceDocument.getVendorPaymentTerms());
1550                     vendorCreditMemoDocument.setVendorPaymentTermsCode(invoiceDocument.getVendorPaymentTerms().getVendorPaymentTermsCode());
1551                     vendorCreditMemoDocument.setVendorShippingTitleCode(invoiceDocument.getVendorShippingTitleCode());
1552                     vendorCreditMemoDocument.setVendorShippingPaymentTerms(invoiceDocument.getVendorShippingPaymentTerms());*/
1553                     vendorCreditMemoDocument.setVendorCityName(invoiceDocument.getVendorCityName());
1554                     vendorCreditMemoDocument.setVendorLine1Address(invoiceDocument.getVendorLine1Address());
1555                     vendorCreditMemoDocument.setVendorLine2Address(invoiceDocument.getVendorLine2Address());
1556                     vendorCreditMemoDocument.setVendorAttentionName(invoiceDocument.getVendorAttentionName());
1557                     vendorCreditMemoDocument.setVendorPostalCode(invoiceDocument.getVendorPostalCode());
1558                     vendorCreditMemoDocument.setVendorStateCode(invoiceDocument.getVendorStateCode());
1559                     vendorCreditMemoDocument.setVendorAttentionName(invoiceDocument.getVendorAttentionName());
1560                     vendorCreditMemoDocument.setVendorAddressInternationalProvinceName(invoiceDocument.getVendorAddressInternationalProvinceName());
1561                     vendorCreditMemoDocument.setVendorCountryCode(invoiceDocument.getVendorCountryCode());
1562                     vendorCreditMemoDocument.setVendorCountry(invoiceDocument.getVendorCountry());
1563                     vendorCreditMemoDocument.setVendorCustomerNumber(invoiceDocument.getVendorCustomerNumber());
1564                     vendorCreditMemoDocument.setAccountsPayableProcessorIdentifier(invoiceDocument.getAccountsPayableProcessorIdentifier());
1565                     vendorCreditMemoDocument.setProcessingCampusCode(invoiceDocument.getProcessingCampusCode());
1566                     vendorCreditMemoDocument.setPurchaseOrderIdentifier(purchaseOrderId);
1567                     // vendorCreditMemoDocument.setReopenPurchaseOrderIndicator(oleInvoiceItem.isReopenPurchaseOrderIndicator());
1568                     // vendorCreditMemoDocument.setClosePurchaseOrderIndicator(oleInvoiceItem.isClosePurchaseOrderIndicator());
1569                     vendorCreditMemoDocument.setCreditMemoDate(invoiceDocument.getInvoiceDate());
1570                     //  vendorCreditMemoDocument.setImmediatePaymentIndicator(invoiceDocument.getImmediatePaymentIndicator());
1571                     // vendorCreditMemoDocument.setPaymentRequestCostSource(invoiceDocument.getInvoiceCostSource());
1572                     //   LOG.info("invoiceDocument.getPaymentMethod().getPaymentMethodId() >>>>>>>>>" + invoiceDocument.getPaymentMethod().getPaymentMethodId());
1573 
1574                     // vendorCreditMemoDocument.setGrandTotal(invoiceDocument.getTotalDollarAmount());
1575                     vendorCreditMemoDocument.setVendorCustomerNumber(invoiceDocument.getVendorCustomerNumber());
1576                     vendorCreditMemoDocument.setAccountsPayableProcessorIdentifier(invoiceDocument.getAccountsPayableProcessorIdentifier());
1577                     vendorCreditMemoDocument.setProcessingCampusCode(invoiceDocument.getProcessingCampusCode());
1578                     vendorCreditMemoDocument.setPurchaseOrderIdentifier(purchaseOrderId);
1579                     vendorCreditMemoDocument.setProrateBy(invoiceDocument.getProrateBy());
1580                     vendorCreditMemoDocument.setProrateDollar(invoiceDocument.isProrateDollar());
1581                     vendorCreditMemoDocument.setProrateQty(invoiceDocument.isProrateQty());
1582                     vendorCreditMemoDocument.setProrateManual(invoiceDocument.isProrateManual());
1583                     vendorCreditMemoDocument.setNoProrate(invoiceDocument.isNoProrate());
1584 
1585 
1586                     if (invoiceDocument.getPaymentMethodId() != null) {
1587                         OlePaymentMethod olePaymentMethod = SpringContext.getBean(BusinessObjectService.class).findBySinglePrimaryKey(OlePaymentMethod.class, invoiceDocument.getPaymentMethodId());
1588                         vendorCreditMemoDocument.setOlePaymentMethod(olePaymentMethod);
1589                         //vendorCreditMemoDocument.getPaymentMethod().setPaymentMethodId(olePaymentMethod.getPaymentMethodId());
1590                         vendorCreditMemoDocument.setPaymentMethodId(olePaymentMethod.getPaymentMethodId());
1591                     }
1592 
1593                     vendorCreditMemoDocument.setInvoiceIdentifier(invoiceDocument.getPurapDocumentIdentifier());
1594                    /* if (invoiceDocument.getAccountsPayablePurchasingDocumentLinkIdentifier() != null) {
1595                         vendorCreditMemoDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(invoiceDocument.getAccountsPayablePurchasingDocumentLinkIdentifier());
1596                     } */
1597                     vendorCreditMemoDocument.setBankCode(invoiceDocument.getBankCode());
1598                     vendorCreditMemoDocument.setBank(invoiceDocument.getBank());
1599                     //vendorCreditMemoDocument.setProcessingCampusCode(invoiceDocument.getProcessingCampusCode());
1600                 } catch (WorkflowException e) {
1601                     String extraDescription = "Error=" + e.getMessage();
1602                     LOG.error("Exception creating Payment request document - " + e.getMessage());
1603                 }
1604 
1605                 Map invItemMap = new HashMap();
1606                 invItemMap.put(PurapConstants.PRQSDocumentsStrings.PUR_ID, invoiceDocument.getPurapDocumentIdentifier());
1607                 invItemMap.put(PurapConstants.PRQSDocumentsStrings.PO_ID, purchaseOrderId);
1608                 List<OleInvoiceItem> invoiceItems = (List<OleInvoiceItem>) businessObjectService.findMatchingOrderBy(OleInvoiceItem.class, invItemMap, PurapConstants.PRQSDocumentsStrings.PO_ID, true);
1609                 KualiDecimal itemCount = new KualiDecimal(0);
1610                 KualiDecimal itemPrice = new KualiDecimal(0);
1611                 PurchaseOrderDocument poDoc = invoiceDocument.getPurchaseOrderDocument(purchaseOrderId);
1612                 if (poDoc == null) {
1613                     throw new RuntimeException("Purchase Order document " + purchaseOrderId + " does not exist in the system");
1614                 }
1615                 if (vendorCreditMemoDocument.getDocumentHeader() != null) {
1616                     vendorCreditMemoDocument.getDocumentHeader().setDocumentDescription(createPreqDocumentDescription(poDoc.getPurapDocumentIdentifier(), invoiceDocument.getVendorName()));
1617                 }
1618 
1619                 try {
1620                     vendorCreditMemoDocument.updateAndSaveAppDocStatus(PurapConstants.PaymentRequestStatuses.APPDOC_IN_PROCESS);
1621                 } catch (WorkflowException we) {
1622                     throw new RuntimeException("Unable to save route status data for document: " + vendorCreditMemoDocument.getDocumentNumber(), we);
1623                 }
1624                 List<OleCreditMemoItem> creditMemoItems = new ArrayList<>();
1625 
1626                 HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = SpringContext.getBean(AccountsPayableService.class).expiredOrClosedAccountsList(poDoc);
1627                 //int itemLineNumberCount = 0;
1628                 for (OleInvoiceItem invoiceItem : invoiceItems) {
1629                     if ((flag || !invoiceItem.isDebitItem()) && invoiceItem.getExtendedPrice().isNonZero()) {
1630 
1631                         OleCreditMemoItem creditMemoItem = new OleCreditMemoItem(invoiceItem, vendorCreditMemoDocument, expiredOrClosedAccountList);
1632                         if(flag && invoiceItem.isDebitItem()){
1633                             creditMemoItem.setItemUnitPrice(creditMemoItem.getItemUnitPrice().negate());
1634                             creditMemoItem.setExtendedPrice(creditMemoItem.getExtendedPrice().negated());
1635                             for(PurApAccountingLine purApAccountingLine : creditMemoItem.getSourceAccountingLines()){
1636                                 purApAccountingLine.setAmount(purApAccountingLine.getAmount().negated());
1637                             }
1638                         }
1639                         creditMemoItems.add(creditMemoItem);
1640                         if (vendorCreditMemoDocument.getAccountsPayablePurchasingDocumentLinkIdentifier() == null) {
1641                             vendorCreditMemoDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(invoiceItem.getAccountsPayablePurchasingDocumentLinkIdentifier());
1642                         }
1643                     }
1644 
1645                 }
1646                 vendorCreditMemoDocument.setItems(creditMemoItems);
1647                 vendorCreditMemoDocument.setCreditMemoAmount(vendorCreditMemoDocument.getTotalDollarAmount());
1648                 SpringContext.getBean(OleCreditMemoService.class).calculateCreditMemo(vendorCreditMemoDocument);
1649 
1650                 SpringContext.getBean(KualiRuleService.class).applyRules(new AttributedCalculateAccountsPayableEvent(vendorCreditMemoDocument));
1651 
1652                 if (expiredOrClosedAccountList == null) {
1653                     expiredOrClosedAccountList = new HashMap();
1654                 }
1655 
1656                 if (LOG.isDebugEnabled()) {
1657                     LOG.debug(expiredOrClosedAccountList.size() + " accounts has been found as Expired or Closed");
1658                 }
1659 
1660                 invoicePoId = purchaseOrderId;
1661 
1662 
1663                 SpringContext.getBean(CreditMemoService.class).populateAndSaveCreditMemo(vendorCreditMemoDocument);
1664 
1665                 SpringContext.getBean(OleCreditMemoService.class).autoApproveCreditMemo(vendorCreditMemoDocument);
1666             }
1667         }
1668     }
1669 
1670     @Override
1671     public OleInvoiceDocument getInvoiceDocumentById(Integer invoiceIdentifier) {
1672         OleInvoiceDocument invoiceDocument = getInvoiceByDocumentNumber(invoiceDao.getDocumentNumberByInvoiceId(invoiceIdentifier));
1673         return invoiceDocument;
1674     }
1675 
1676 
1677     public boolean autoApprovePaymentRequest(OleInvoiceDocument doc) {
1678         try {
1679             // Much of the rice frameworks assumes that document instances that are saved via DocumentService.saveDocument are
1680             // those
1681             // that were dynamically created by PojoFormBase (i.e., the Document instance wasn't created from OJB). We need to
1682             // make
1683             // a deep copy and materialize collections to fulfill that assumption so that collection elements will delete
1684             // properly
1685 
1686             // TODO: maybe rewriting PurapService.calculateItemTax could be rewritten so that the a deep copy doesn't need to be
1687             // made
1688             // by taking advantage of OJB's managed array lists
1689             try {
1690                 ObjectUtils.materializeUpdateableCollections(doc);
1691                 for (OleInvoiceItem item : (List<OleInvoiceItem>) doc.getItems()) {
1692                     ObjectUtils.materializeUpdateableCollections(item);
1693                 }
1694             } catch (Exception ex) {
1695                 throw new RuntimeException(ex);
1696             }
1697             doc = (OleInvoiceDocument) ObjectUtils.deepCopy(doc);
1698             //purapService.updateStatus(doc, PaymentRequestStatuses.AUTO_APPROVED);
1699             //doc.updateAndSaveAppDocStatus(PurapConstants.PaymentRequestStatuses.APPDOC_INITIATE);
1700 
1701             // documentService.routeDocument(doc, "auto-approving: Document Created from Invoice.", null);
1702             saveInvoiceDocument(doc);
1703         } catch (WorkflowException we) {
1704             LOG.error("Exception encountered when approving document number " + doc.getDocumentNumber() + ".", we);
1705             // throw a runtime exception up so that we can force a rollback
1706             throw new RuntimeException("Exception encountered when approving document number " + doc.getDocumentNumber() + ".", we);
1707         }
1708         return true;
1709     }
1710 
1711     public OleInvoiceDocument populateInvoiceDocument (OleInvoiceDocument invoiceDocument) {
1712         Boolean isItemLevelDebit = null;
1713         Boolean isAdditionalChargeLevelDebit = null;
1714         Boolean isItemLevelCredit = null;
1715         Boolean isAdditionalChargeLevelCredit = null;
1716         if (invoiceDocument.getPurchaseOrderDocuments() != null && invoiceDocument.getPurchaseOrderDocuments().size() > 0) {
1717             for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
1718                 if (invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getItemUnitPrice() != null)
1719                     invoiceItem.setPurchaseOrderIdentifier(invoiceDocument.getPurchaseOrderDocuments().get(0).getPurapDocumentIdentifier());
1720             }
1721         }
1722         Integer poIdentifier=null;
1723         for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
1724             if (invoiceItem.isDebitItem()  &&
1725                     (invoiceItem.getItemListPrice().isNonZero() ||
1726                             (invoiceItem.getItemUnitPrice()!=null && invoiceItem.getItemUnitPrice().compareTo(BigDecimal.ZERO)!=0))){
1727                 if(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator()){
1728                     if(isItemLevelDebit==null){
1729                         isItemLevelDebit = true;
1730                     }
1731                     isItemLevelDebit &= invoiceItem.isDebitItem();
1732                 }
1733                 if(invoiceItem.getItemType().isAdditionalChargeIndicator()){
1734                     if(isAdditionalChargeLevelDebit==null){
1735                         isAdditionalChargeLevelDebit = true;
1736                     }
1737                     isAdditionalChargeLevelDebit &= invoiceItem.isDebitItem();
1738                 }
1739 
1740             }
1741             else if(!invoiceItem.isDebitItem() &&
1742                     (invoiceItem.getItemListPrice().isNonZero() ||
1743                             (invoiceItem.getItemUnitPrice()!=null && invoiceItem.getItemUnitPrice().compareTo(BigDecimal.ZERO)!=0))){
1744                 if(invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator()){
1745                     if(isItemLevelCredit==null){
1746                         isItemLevelCredit = true;
1747                     }
1748                     isItemLevelCredit &= !invoiceItem.isDebitItem();
1749                 }
1750                 if(invoiceItem.getItemType().isAdditionalChargeIndicator()){
1751                     if(isAdditionalChargeLevelCredit==null){
1752                         isAdditionalChargeLevelCredit = true;
1753                     }
1754                     isAdditionalChargeLevelCredit &= !invoiceItem.isDebitItem();
1755                 }
1756             }
1757             if (invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator() &&
1758                     invoiceItem.getItemListPrice().isNonZero() && poIdentifier==null) {
1759                 poIdentifier = invoiceItem.getPurchaseOrderIdentifier();
1760             }
1761         }
1762         boolean flag = (isItemLevelDebit == null && isAdditionalChargeLevelDebit!=null && isAdditionalChargeLevelDebit) ||
1763                 (isAdditionalChargeLevelDebit == null && isItemLevelDebit!=null && isItemLevelDebit) ||
1764                 (isItemLevelCredit == null && isAdditionalChargeLevelCredit!=null && isAdditionalChargeLevelCredit) ||
1765                 (isAdditionalChargeLevelCredit == null && isItemLevelCredit!=null && isItemLevelCredit) &&
1766                         !(isItemLevelCredit!=null && isItemLevelCredit && isItemLevelDebit!=null && isItemLevelDebit);
1767         if(!flag){
1768             Integer poIdentifierForCredit = null;
1769             Integer poIdentifierForDebit = null;
1770             if (invoiceDocument.getItems() != null && invoiceDocument.getItems().size() > 0) {
1771                 for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>)invoiceDocument.getItems()) {
1772                     if (invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && invoiceItem.isDebitItem() &&
1773                             invoiceItem.getItemListPrice().isNonZero()) {
1774                         poIdentifierForDebit = invoiceItem.getPurchaseOrderIdentifier();
1775                         break;
1776                     }
1777                 }
1778             }
1779             if (invoiceDocument.getItems() != null && invoiceDocument.getItems().size() > 0) {
1780                 for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>)invoiceDocument.getItems()) {
1781                     if (invoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && !invoiceItem.isDebitItem() &&
1782                             invoiceItem.getItemListPrice().isNonZero()) {
1783                         poIdentifierForCredit = invoiceItem.getPurchaseOrderIdentifier();
1784                         break;
1785                     }
1786                 }
1787             }
1788 
1789             //if (invoiceDocument.getPurchaseOrderDocuments() != null && invoiceDocument.getPurchaseOrderDocuments().size() > 0) {
1790             for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
1791                 if (invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getItemUnitPrice() != null && invoiceItem.isDebitItem()) {
1792                     invoiceItem.setPurchaseOrderIdentifier(poIdentifierForDebit);
1793                 }
1794                 if (invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getItemUnitPrice() != null && !invoiceItem.isDebitItem()) {
1795                     invoiceItem.setPurchaseOrderIdentifier(poIdentifierForCredit);
1796                 }
1797             }
1798         }else{
1799             for (OleInvoiceItem invoiceItem : (List<OleInvoiceItem>) invoiceDocument.getItems()) {
1800                 if (invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getItemUnitPrice() != null) {
1801                     invoiceItem.setPurchaseOrderIdentifier(poIdentifier);
1802                 }
1803             }
1804         }
1805         //}
1806 
1807         invoiceDocument.setInvoicePayDate(calculatePayDate(invoiceDocument.getInvoiceDate(), invoiceDocument.getVendorPaymentTerms()));
1808         //invoiceDocument.setTotalDollarAmount(invoiceDocument.getTotalDollarAmount().add(po.getTotalDollarAmount()));
1809 
1810         if (invoiceDocument.getInvoiceTypeHdnId() != null && !invoiceDocument.getInvoiceTypeHdnId().isEmpty()) {
1811             invoiceDocument.setInvoiceTypeId(Integer.valueOf(invoiceDocument.getInvoiceTypeHdnId()));
1812         }
1813         if (invoiceDocument.getPaymentMethodIdentifier() != null  && !invoiceDocument.getPaymentMethodIdentifier().isEmpty()) {
1814             invoiceDocument.setPaymentMethodId(Integer.valueOf(invoiceDocument.getPaymentMethodIdentifier()));
1815         }
1816         if (invoiceDocument.getInvoiceSubTypeHdnId() != null && !invoiceDocument.getInvoiceSubTypeHdnId().isEmpty()) {
1817             invoiceDocument.setInvoiceSubTypeId(Integer.valueOf(invoiceDocument.getInvoiceSubTypeHdnId()));
1818         }
1819 
1820         if (invoiceDocument.getInvoiceAmount() != null && !invoiceDocument.getInvoiceAmount().isEmpty()) {
1821             invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getInvoiceAmount()));
1822         }
1823 
1824         if (invoiceDocument.getForeignInvoiceAmount() != null && !invoiceDocument.getForeignInvoiceAmount().isEmpty()) {
1825             invoiceDocument.setForeignVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignInvoiceAmount()).bigDecimalValue());
1826             if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyType())) {
1827                 if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyExchangeRate())) {
1828                     try {
1829                         Double.parseDouble(invoiceDocument.getInvoiceCurrencyExchangeRate());
1830                     }
1831                     catch (NumberFormatException nfe) {
1832                         throw new RuntimeException("Invalid Exchange Rate", nfe);
1833                     }
1834                     invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(new BigDecimal(invoiceDocument.getInvoiceCurrencyExchangeRate()), 4, RoundingMode.HALF_UP)));
1835                     invoiceDocument.setInvoiceAmount(invoiceDocument.getVendorInvoiceAmount().toString());
1836                 }   else {
1837                     BigDecimal exchangeRate = getExchangeRate(invoiceDocument.getInvoiceCurrencyType()).getExchangeRate();
1838                     invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(exchangeRate, 4, RoundingMode.HALF_UP)));
1839                     invoiceDocument.setInvoiceAmount(invoiceDocument.getVendorInvoiceAmount().toString());
1840                 }
1841 
1842             }
1843         }
1844 
1845         Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(invoiceDocument.getClass());
1846         if (defaultBank != null) {
1847             invoiceDocument.setBankCode(defaultBank.getBankCode());
1848             invoiceDocument.setBank(defaultBank);
1849         }
1850 
1851 
1852         invoiceDocument.setInvoicePayDate(this.calculatePayDate(invoiceDocument.getInvoiceDate(), invoiceDocument.getVendorPaymentTerms()));
1853 
1854 
1855         /* invoice total */
1856 
1857         BigDecimal addChargeItem=BigDecimal.ZERO;
1858         List<OleInvoiceItem> item = invoiceDocument.getItems();
1859         for(OleInvoiceItem invoiceditem : item){
1860             if(invoiceditem.getItemType().isAdditionalChargeIndicator() && invoiceditem.getExtendedPrice()!=null){
1861                 addChargeItem =addChargeItem.add(invoiceditem.getExtendedPrice().bigDecimalValue());
1862             }
1863         }
1864         if (invoiceDocument.getTotalDollarAmount() != null ) {
1865             invoiceDocument.setInvoiceItemTotal(invoiceDocument.getTotalDollarAmount().subtract(new KualiDecimal(addChargeItem)).toString());
1866             invoiceDocument.setDocumentTotalAmount(invoiceDocument.getTotalDollarAmount().toString());
1867         }
1868         return invoiceDocument;
1869     }
1870 
1871     public OleInvoiceDocument populateInvoiceItems (OleInvoiceDocument invoiceDocument) {
1872         //int invoiceItemNumberCnt = getLastItemLineNumber(invoiceDocument);
1873 
1874         LOG.debug("Inside populateInvoiceItems method ");
1875         List<OleInvoiceItem> items = new ArrayList<>();
1876         Boolean receiveRequired = false;
1877         HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = new HashMap<>();
1878         BigDecimal addChargeItem=BigDecimal.ZERO;
1879         for (OlePurchaseOrderDocument po : invoiceDocument.getPurchaseOrderDocuments()) {
1880             if(po.isReceivingDocumentRequiredIndicator()) {
1881                 receiveRequired=true;
1882             }
1883             /* if(this.encumberedItemExistsForInvoicing(po))
1884             {*/
1885             for (OlePurchaseOrderItem poi : (List<OlePurchaseOrderItem>) po.getItems()) {
1886                 // check to make sure it's eligible for payment (i.e. active and has encumbrance available
1887                 //if (this.poItemEligibleForAp(invoiceDocument, poi)) {
1888                 if (poi.isItemForInvoice()) {
1889                     OleInvoiceItem invoiceItem = new OleInvoiceItem(poi, invoiceDocument, expiredOrClosedAccountList);
1890                     // invoiceItem.setItemLineNumber(++invoiceItemNumberCnt);
1891                     invoiceItem.setClosePurchaseOrderIndicator(po.isClosePO());
1892                     invoiceItem.setReopenPurchaseOrderIndicator(po.getIsReOpenPO());
1893                     PurchasingCapitalAssetItem purchasingCAMSItem = po.getPurchasingCapitalAssetItemByItemIdentifier(poi.getItemIdentifier());
1894                     if (purchasingCAMSItem != null) {
1895                         invoiceItem.setCapitalAssetTransactionTypeCode(purchasingCAMSItem.getCapitalAssetTransactionTypeCode());
1896                     }
1897                     invoiceItem.setUseTaxIndicator(po.isUseTaxIndicator());
1898                     invoiceItem.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
1899                     invoiceItem.setPostingYear(po.getPostingYear());
1900                     invoiceItem.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
1901                     invoiceItem.setReceivingDocumentRequiredIndicator(po.isReceivingDocumentRequiredIndicator());
1902                     if(invoiceItem.getItemType().isAdditionalChargeIndicator() && invoiceItem.getExtendedPrice()!=null){
1903                         addChargeItem =addChargeItem.add(invoiceItem.getExtendedPrice().bigDecimalValue());
1904                     }
1905                     // copy usetaxitems over
1906                     invoiceItem.getUseTaxItems().clear();
1907                     for (PurApItemUseTax useTax : poi.getUseTaxItems()) {
1908                         invoiceItem.getUseTaxItems().add(useTax);
1909                     }
1910                     invoiceItem.setPurchaseOrderEndDate(invoiceDocument.getPurchaseOrderDocuments().get(0).getPoEndDate());
1911                     //SpringContext.getBean(PurapAccountingService.class).updateItemAccountAmounts(invoiceItem);
1912                  //   this.calculateAccount(invoiceItem);
1913                     invoiceDocument.getItems().add(invoiceItem);
1914                     if (LOG.isDebugEnabled()) {
1915                         LOG.debug("Size**********************" + invoiceDocument.getItems().size());
1916                     }
1917                 }
1918             }
1919             invoiceDocument.setTotalDollarAmount(invoiceDocument.getTotalDollarAmount().add(po.getTotalDollarAmount()));
1920         }
1921 
1922         //  List<OleInvoiceItem> item = invoiceDocument.getItems();
1923        /* for(OleInvoiceItem invoiceditem : item){
1924             if(invoiceditem.getItemType().isAdditionalChargeIndicator() && invoiceditem.getExtendedPrice()!=null){
1925                 addChargeItem =addChargeItem.add(invoiceditem.getExtendedPrice().bigDecimalValue());
1926             }
1927         }*/
1928         if (invoiceDocument.getTotalDollarAmount() != null ) {
1929             invoiceDocument.setInvoiceItemTotal(invoiceDocument.getTotalDollarAmount().subtract(new KualiDecimal(addChargeItem)).toString());
1930             invoiceDocument.setDocumentTotalAmount(invoiceDocument.getTotalDollarAmount().toString());
1931         }
1932         invoiceDocument.setDocumentTotalAmount(invoiceDocument.getInvoicedItemTotal());
1933         // invoiceDocument.setPurchaseOrderDocuments(new ArrayList<OlePurchaseOrderDocument>());
1934         invoiceDocument.getPurchaseOrderDocuments().clear();
1935         invoiceDocument.setReceivingDocumentRequiredIndicator(receiveRequired);
1936         return invoiceDocument;
1937     }
1938 
1939     /**
1940      * This method calculates the Amount and the Percent in Accounting Line if the Invoiced List Price changed
1941      */
1942     public void calculateAccount(PurApItem purapItem) {
1943         purapItem.setExtendedPrice(purapItem.calculateExtendedPrice());
1944         List<PurApAccountingLine> purApAccountingLines = purapItem.getSourceAccountingLines();
1945         BigDecimal totalPercent = BigDecimal.ZERO;
1946         BigDecimal totalAmt = BigDecimal.ZERO;
1947         for (PurApAccountingLine account : purApAccountingLines) {
1948             if (purapItem.getTotalAmount() != null && !purapItem.getTotalAmount().equals(KualiDecimal.ZERO)) {
1949                 if (account.getAccountLinePercent() != null && (account.getAmount() == null || account.getAmount().equals(KualiDecimal.ZERO))) {
1950                     BigDecimal percent = account.getAccountLinePercent().divide(new BigDecimal(100));
1951                     account.setAmount((purapItem.getTotalAmount().multiply(new KualiDecimal(percent))));
1952                 } else if (account.getAmount() != null && account.getAmount().isNonZero() && account.getAccountLinePercent() == null) {
1953                     KualiDecimal dollar = account.getAmount().multiply(new KualiDecimal(100));
1954                     BigDecimal dollarToPercent = dollar.bigDecimalValue().divide((purapItem.getTotalAmount().bigDecimalValue()), 0, RoundingMode.FLOOR);
1955                     account.setAccountLinePercent(dollarToPercent);
1956                 } else if (account.getAmount() != null && account.getAmount().isZero() && account.getAccountLinePercent() == null) {
1957                     account.setAccountLinePercent(new BigDecimal(0));
1958                 } else if((account.getAmount()!=null&&account.getAccountLinePercent() != null) ||
1959                         (account.getAmount()!=null&& account.getAccountLinePercent().intValue()== 100)){
1960                     BigDecimal percent = account.getAccountLinePercent().divide(new BigDecimal(100));
1961                     account.setAmount((purapItem.getTotalAmount().multiply(new KualiDecimal(percent))));
1962                 }
1963                 totalPercent = totalPercent.add(account.getAccountLinePercent());
1964                 totalAmt = totalAmt.add(account.getAmount().bigDecimalValue());
1965             } else {
1966                 account.setAmount(KualiDecimal.ZERO);
1967             }
1968         }
1969         // If Total Percent or Total Amount mis matches,percentage is divided across accounting lines.
1970         if(totalPercent.intValue() != 100 ||
1971                 (purapItem.getTotalAmount()!=null && totalAmt.compareTo(purapItem.getTotalAmount().bigDecimalValue())!=0)){
1972             for (PurApAccountingLine account : purApAccountingLines) {
1973                 if (purapItem.getTotalAmount() != null && !purapItem.getTotalAmount().equals(KualiDecimal.ZERO)) {
1974                     BigDecimal percent = BigDecimal.ONE.divide(new BigDecimal(purApAccountingLines.size()), BigDecimal.ROUND_CEILING, BigDecimal.ROUND_HALF_UP);
1975                     account.setAmount((purapItem.getTotalAmount().multiply(new KualiDecimal(percent))));
1976                 } else {
1977                     account.setAmount(KualiDecimal.ZERO);
1978                 }
1979             }
1980         }
1981 
1982     }
1983 
1984     @Override
1985     public void convertPOItemToInvoiceItem (OleInvoiceDocument oleInvoiceDocument) {
1986         boolean poItemsSelected = false;
1987         for (OlePurchaseOrderDocument po : oleInvoiceDocument.getPurchaseOrderDocuments()) {
1988             for (OlePurchaseOrderItem poi : (List<OlePurchaseOrderItem>) po.getItems()) {
1989                 if (poi.isItemForInvoice()) {
1990                     poItemsSelected = true;
1991                     break;
1992                 }
1993             }
1994         }
1995         if (poItemsSelected) {
1996             oleInvoiceDocument = this.populateInvoiceItems(oleInvoiceDocument);
1997             //   oleInvoiceDocument = this.populateInvoiceDocument(oleInvoiceDocument);
1998             /*SpringContext.getBean(PurapAccountingService.class).updateAccountAmounts(oleInvoiceDocument);*/
1999         }
2000         else {
2001             oleInvoiceDocument.setPurchaseOrderDocuments(new ArrayList<OlePurchaseOrderDocument>());
2002             GlobalVariables.getMessageMap().putError(OleSelectConstant.PROCESS_ITEM_SECTION_ID, OLEKeyConstants.ERROR_NO_PO_SELECTED);
2003         }
2004     }
2005 
2006     /**
2007      * This method prepares the warning message for the Invoice Document based on the Invoice Amount
2008      * and the Grand Total
2009      */
2010     public String createInvoiceNoMatchQuestionText(OleInvoiceDocument invoiceDocument) {
2011 
2012         String questionText = null;
2013         StringBuffer questionTextBuffer = new StringBuffer("");
2014         if (invoiceDocument.getInvoiceAmount() != null && invoiceDocument.getInvoicedGrandTotal() != null ) {
2015             KualiDecimal invoiceAmount = new KualiDecimal(invoiceDocument.getInvoiceAmount());
2016             KualiDecimal invoiceGrandTotal = new KualiDecimal(invoiceDocument.getInvoicedGrandTotal());
2017             if(!invoiceAmount.equals(invoiceGrandTotal)) {
2018                 questionText = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(PurapKeyConstants.AP_QUESTION_CONFIRM_INVOICE_MISMATCH);
2019                 questionText = StringUtils.replace(questionText, "{0}", "");
2020                 //String questionText = super.createInvoiceNoMatchQuestionText(invoiceDocument);
2021 
2022                 CurrencyFormatter cf = new CurrencyFormatter();
2023                 //PaymentRequestDocument preq = (PaymentRequestDocument) invoiceDocument;
2024 
2025 
2026                 questionTextBuffer.append(questionText);
2027                 if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyType())) {
2028                     String currencyType = getCurrencyType(invoiceDocument.getInvoiceCurrencyType());
2029                     if (StringUtils.isNotBlank(currencyType)) {
2030                         if (!currencyType.equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME) && invoiceDocument.getForeignVendorInvoiceAmount() != null) {
2031                             if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyExchangeRate())) {
2032                                 try {
2033                                     Double.parseDouble(invoiceDocument.getInvoiceCurrencyExchangeRate());
2034                                 }
2035                                 catch (NumberFormatException nfe) {
2036                                     throw new RuntimeException("Invalid Exchange Rate", nfe);
2037                                 }
2038                                 invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(new BigDecimal(invoiceDocument.getInvoiceCurrencyExchangeRate()), 4, RoundingMode.HALF_UP)));
2039                             }   else {
2040                                 BigDecimal exchangeRate = getExchangeRate(invoiceDocument.getInvoiceCurrencyType()).getExchangeRate();
2041                                 invoiceDocument.setVendorInvoiceAmount(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount().divide(exchangeRate, 4, RoundingMode.HALF_UP)));
2042                             }
2043                         }
2044                     }
2045 
2046                 }
2047                 questionTextBuffer.append("[br][br][b]Summary Detail Below:[b][br][br][table questionTable]");
2048                 questionTextBuffer.append("[tr][td leftTd]Vendor Invoice Amount :[/td][td rightTd]" + (String) cf.format(invoiceDocument.getVendorInvoiceAmount()) + "[/td][/tr]");
2049                 questionTextBuffer.append("[tr][td leftTd]Invoice Total Prior to Additional Charges:[/td][td rightTd]" + (String) cf.format(new KualiDecimal(invoiceDocument.getInvoicedItemTotal())) + "[/td][/tr]");
2050 
2051 
2052                 //only add this line if payment request has a discount
2053                 if (invoiceDocument.isDiscount()) {
2054                     questionTextBuffer.append("[tr][td leftTd]Total Before Discount:[/td][td rightTd]" + (String) cf.format(invoiceDocument.getGrandPreTaxTotalExcludingDiscount()) + "[/td][/tr]");
2055                 }
2056 
2057                 //if sales tax is enabled, show additional summary lines
2058                 boolean salesTaxInd = SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_SALES_TAX_IND);
2059                 if (salesTaxInd) {
2060                     questionTextBuffer.append("[tr][td leftTd]Grand Total Prior to Tax:[/td][td rightTd]" + (String) cf.format(invoiceDocument.getGrandPreTaxTotal()) + "[/td][/tr]");
2061                     questionTextBuffer.append("[tr][td leftTd]Grand Total Tax:[/td][td rightTd]" + (String) cf.format(invoiceDocument.getGrandTaxAmount()) + "[/td][/tr]");
2062                 }
2063 
2064                 questionTextBuffer.append("[tr][td leftTd]Grand Total:[/td][td rightTd]" + (String) cf.format(new KualiDecimal(invoiceDocument.getInvoicedGrandTotal())) + "[/td][/tr]");
2065 
2066                 if (StringUtils.isNotBlank(invoiceDocument.getInvoiceCurrencyType())) {
2067                     String currencyType = getCurrencyType(invoiceDocument.getInvoiceCurrencyType());
2068                     if (StringUtils.isNotBlank(currencyType)) {
2069                         if (!currencyType.equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME)) {
2070                             questionTextBuffer.append("[tr][td] [/td][/tr]");
2071                             questionTextBuffer.append("[tr][td leftTd]Foreign Vendor Invoice Amount :[/td][td rightTd]" + (String) cf.format(new KualiDecimal(invoiceDocument.getForeignVendorInvoiceAmount())) + "[/td][/tr]");
2072                             questionTextBuffer.append("[tr][td leftTd]Foreign Invoice Total Prior to Additional Charges:[/td][td rightTd]" + (String) cf.format(new KualiDecimal(invoiceDocument.getInvoicedForeignItemTotal())) + "[/td][/tr]");
2073                             questionTextBuffer.append("[tr][td leftTd]Foreign Grand Total:[/td][td rightTd]" + (String) cf.format(new KualiDecimal(invoiceDocument.getInvoicedForeignGrandTotal())) + "[/td][/tr]");
2074                         }
2075                     }
2076                 }
2077                 questionTextBuffer.append("[/table]");
2078             }
2079         }
2080 
2081         return questionTextBuffer.toString();
2082 
2083     }
2084 
2085 
2086     /**
2087      * This method prepares the warning message for the Invoice Document based on the Invoice Amount
2088      * and the Grand Total
2089      */
2090     public String createSubscriptionDateOverlapQuestionText(OleInvoiceDocument invoiceDocument) {
2091         boolean isOverlap = false;
2092         List<OleInvoiceDocument> overlapInvDocumentList = new ArrayList<OleInvoiceDocument>();
2093         List<OleInvoiceItem> invItems = (List<OleInvoiceItem>) invoiceDocument.getItems();
2094         List<OleInvoiceItem> subscriptionInvItems = new ArrayList<OleInvoiceItem>();
2095         List<OleInvoiceItem> subscriptionInvoicedItems = new ArrayList<OleInvoiceItem>();
2096 
2097         for (OleInvoiceItem invoiceItem : invItems) {
2098             if (invoiceItem.isSubscriptionOverlap()) {
2099                 subscriptionInvItems.add(invoiceItem);
2100             }
2101         }
2102         for (OleInvoiceItem subscriptionInvItem : subscriptionInvItems) {
2103 
2104             if (subscriptionInvItem.getPoItemIdentifier() != null) {
2105                 Map matchPOItem = new HashMap();
2106                 matchPOItem.put("poItemIdentifier", subscriptionInvItem.getPoItemIdentifier());
2107                 List<OleInvoiceItem> itemList = (List<OleInvoiceItem>) getBusinessObjectService().findMatching(OleInvoiceItem.class, matchPOItem);
2108 
2109                 for (OleInvoiceItem invoicedItem : itemList) {
2110                     if (invoicedItem.getSubscriptionFromDate() != null && invoicedItem.getSubscriptionToDate() != null) {
2111                         subscriptionInvoicedItems.add(invoicedItem);
2112                     }
2113                 }
2114 
2115                 for (OleInvoiceItem oleInvoiceItem : subscriptionInvoicedItems) {
2116 
2117                     if (oleInvoiceItem.getPoItemIdentifier().equals(subscriptionInvItem.getPoItemIdentifier())) {
2118 
2119                         if (subscriptionInvItem.getSubscriptionFromDate().compareTo(oleInvoiceItem.getSubscriptionFromDate()) >= 0 && subscriptionInvItem.getSubscriptionFromDate().compareTo(oleInvoiceItem.getSubscriptionToDate()) <= 0) {
2120                             isOverlap = true;
2121                             overlapInvDocumentList.add((OleInvoiceDocument) oleInvoiceItem.getInvoiceDocument());
2122                         } else if (subscriptionInvItem.getSubscriptionToDate().compareTo(oleInvoiceItem.getSubscriptionFromDate()) >= 0 && subscriptionInvItem.getSubscriptionToDate().compareTo(oleInvoiceItem.getSubscriptionToDate()) <= 0) {
2123                             isOverlap = true;
2124                             overlapInvDocumentList.add((OleInvoiceDocument) oleInvoiceItem.getInvoiceDocument());
2125                         } else if ((subscriptionInvItem.getSubscriptionFromDate().compareTo(oleInvoiceItem.getSubscriptionFromDate()) < 0) && (subscriptionInvItem.getSubscriptionToDate().compareTo(oleInvoiceItem.getSubscriptionToDate()) > 0)) {
2126                             isOverlap = true;
2127                             overlapInvDocumentList.add((OleInvoiceDocument) oleInvoiceItem.getInvoiceDocument());
2128                         }
2129                     }
2130                 }
2131             }
2132         }
2133         String questionText = null;
2134         StringBuffer questionTextBuffer = new StringBuffer("");
2135         if (isOverlap) {
2136             questionText = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(PurapKeyConstants.AP_QUESTION_CONFIRM_INVOICE_SUBSCRIPTION_DATE_OVERLAP);
2137             questionText = StringUtils.replace(questionText, "{0}", "");
2138             //String questionText = super.createInvoiceNoMatchQuestionText(invoiceDocument);
2139 
2140 
2141             questionTextBuffer.append(questionText);
2142 
2143             questionTextBuffer.append("[br][br][b]Summary Detail Below:[b][br][br][table questionTable]");
2144             questionTextBuffer.append("[tr][td leftTd]Following Invoices Subscription Date Overlap with current Invoice :[/td][td rightTd] [/td][/tr]");
2145             questionTextBuffer.append("[tr][td leftTd][/td][td rightTd]");
2146 
2147             for (OleInvoiceDocument overlapInvDocument : overlapInvDocumentList) {
2148                 questionTextBuffer.append(overlapInvDocument.getDocumentNumber() + "    ");
2149             }
2150             questionTextBuffer.append("[/td][/tr][/table]");
2151         }
2152 
2153         overlapInvDocumentList.clear();
2154         subscriptionInvItems.clear();
2155         return questionTextBuffer.toString();
2156 
2157     }
2158 
2159 
2160    /* public Integer getLastItemLineNumber(OleInvoiceDocument invoiceDocument){
2161         int  lastItemLineNumber = 0;
2162         if(invoiceDocument.getItems() != null){
2163             for(InvoiceItem item : (List<OleInvoiceItem>)invoiceDocument.getItems()) {
2164                  if(item.getItemTypeCode().equals("ITEM")){
2165                      lastItemLineNumber++;
2166                  }
2167             }
2168         }
2169         return lastItemLineNumber;
2170     }*/
2171 
2172     public String getParameter(String name){
2173         ParameterKey parameterKey = ParameterKey.create(org.kuali.ole.OLEConstants.APPL_ID, org.kuali.ole.OLEConstants.SELECT_NMSPC, org.kuali.ole.OLEConstants.SELECT_CMPNT,name);
2174         Parameter parameter = CoreServiceApiServiceLocator.getParameterRepositoryService().getParameter(parameterKey);
2175         return parameter!=null?parameter.getValue():null;
2176     }
2177 
2178     public String[] getCollapseSections() {
2179         LOG.debug("Inside getCollapseSections()");
2180         String[] collapseSections = new String[]{};
2181         try {
2182             collapseSections = parameterService.getParameterValuesAsString(Class.forName(PurapConstants.PURAP_DETAIL_TYPE_CODE_MAP.get(PurapConstants.PurapDocTypeCodes.INVOICE_DOCUMENT)),
2183                     OLEConstants.INVOICE_COLLAPSE_SECTIONS_ON_PO_ADD).toArray(new String[]{});
2184         }
2185         catch (Exception e) {
2186             LOG.error("Exception while getting the default Collapse section on Invoice Document"+e);
2187             throw new RuntimeException(e);
2188         }
2189         LOG.debug("Leaving getCollapseSections()");
2190         return collapseSections;
2191     }
2192 
2193     public String[] getDefaultCollapseSections() {
2194         LOG.debug("Inside getDefaultCollapseSections()");
2195         String[] collapseSections = new String[]{};
2196         try {
2197             collapseSections = parameterService.getParameterValuesAsString(Class.forName(PurapConstants.PURAP_DETAIL_TYPE_CODE_MAP.get(PurapConstants.PurapDocTypeCodes.INVOICE_DOCUMENT)),
2198                     OLEConstants.INITIAL_COLLAPSE_SECTIONS).toArray(new String[]{});
2199         }
2200         catch (Exception e) {
2201             LOG.error("Exception while getting the default Collapse section on Invoice Document"+e);
2202             throw new RuntimeException(e);
2203         }
2204         LOG.debug("Leaving getDefaultCollapseSections()");
2205         return collapseSections;
2206     }
2207 
2208     public boolean canCollapse(String sectionName, String[] collapseSections) {
2209         LOG.debug("Inside method canCollapse()");
2210         List<String> sectionLists = Arrays.asList(collapseSections);
2211         if (sectionLists.contains(sectionName)) {
2212             return false;
2213         }
2214         return true;
2215     }
2216 
2217     /**
2218      * This method checks whether duplication occured on the Invoice Document.
2219      * @param invoiceDocument
2220      * @return isDuplicationExists
2221      */
2222 
2223     public boolean isDuplicationExists(OleInvoiceDocument invoiceDocument, OLEInvoiceForm invoiceForm, boolean isBlanketApprove) {
2224         LOG.debug("Inside method isDuplicationExists()");
2225         boolean isDuplicationExists = false;
2226         if(invoiceDocument.getInvoiceNumber()!=null && !invoiceDocument.getInvoiceNumber().equalsIgnoreCase("")){
2227             Map<String, Object> map = new HashMap<String, Object>();
2228             map.put(OLEConstants.InvoiceDocument.INVOICE_NUMBER, invoiceDocument.getInvoiceNumber().toString());
2229             map.put(OLEConstants.InvoiceDocument.INVOICE_DATE, invoiceDocument.getInvoiceDate());
2230             map.put(OLEConstants.InvoiceDocument.VENDOR_GENERATED_IDENTIFIER, invoiceDocument.getVendorHeaderGeneratedIdentifier().toString());
2231             map.put(OLEConstants.InvoiceDocument.VENDOR_DETAIL_ASSIGNED_GENERATED_IDENTIFIER, invoiceDocument.getVendorDetailAssignedIdentifier().toString());
2232             List<OleInvoiceDocument> documents = (List<OleInvoiceDocument>) KRADServiceLocator.getBusinessObjectService().findMatching(OleInvoiceDocument.class, map);
2233             StringBuffer duplicationMessage = new StringBuffer();
2234             //String msg = ;
2235             duplicationMessage.append("\n");
2236             duplicationMessage.append(OleSelectConstant.DUPLICATE_INVOICE + " ");
2237             if (documents.size() > 0) {
2238                 for (OleInvoiceDocument invDoc : documents) {
2239                     if (invDoc.getDocumentNumber() != null &&
2240                             invoiceDocument.getDocumentNumber() != null &&
2241                             !invDoc.getDocumentNumber().equalsIgnoreCase(invoiceDocument.getDocumentNumber()) &&
2242                             !invDoc.getApplicationDocumentStatus().equalsIgnoreCase(OLEConstants.InvoiceDocument.INVOICE_DOCUMENT_INITIATED)) {
2243                         String docNum = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(OLEKeyConstants.LOAD_DUPLICATE_INVOICE);
2244                         docNum =  StringUtils.replace(docNum, "{0}", invDoc.getDocumentNumber());
2245                         duplicationMessage.append(docNum + " ");
2246                         isDuplicationExists = true;
2247                     }
2248                 }
2249             }
2250             if (isDuplicationExists && !isBlanketApprove) {
2251                 duplicationMessage.append(OleSelectConstant.QUES_FOR_DUPLICATE_INVOICE);
2252                 invoiceDocument.setDuplicateFlag(true);
2253                 invoiceForm.setDuplicationMessage(duplicationMessage.toString());
2254             }
2255             else if (isDuplicationExists && isBlanketApprove) {
2256                 duplicationMessage.append(OleSelectConstant.QUES_FOR_DUPLICATE_INVOICE);
2257                 invoiceDocument.setDuplicateApproveFlag(true);
2258                 invoiceForm.setDuplicationApproveMessage(duplicationMessage.toString());
2259             }
2260         }
2261         LOG.debug("Leaving method isDuplicationExists()");
2262         return isDuplicationExists;
2263     }
2264 
2265 
2266     public String getPaymentMethodType(String paymentId){
2267         if(paymentId != null && !(paymentId.equals(""))){
2268             Map payMap = new HashMap();
2269             payMap.put("paymentMethodId", paymentId);
2270             OlePaymentMethod olePaymentMethod = KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(OlePaymentMethod.class,payMap);
2271             if(olePaymentMethod != null){
2272                 return olePaymentMethod.getPaymentMethod();
2273             }
2274         }
2275         return "";
2276     }
2277 
2278     public boolean validateDepositAccount(OleInvoiceDocument oleInvoiceDocument) {
2279         boolean valid = true;
2280         if (getPaymentMethodType(oleInvoiceDocument.getPaymentMethodIdentifier()).equals(OLEConstants.DEPOSIT)) {
2281             for (OleInvoiceItem item : (List<OleInvoiceItem>) oleInvoiceDocument.getItems()) {
2282                 KualiDecimal invoiceAmount = new KualiDecimal(item.getInvoiceListPrice());
2283                 if (invoiceAmount.isLessEqual(KualiDecimal.ZERO) && item.getItemTypeCode().equals("ITEM")) {
2284                     return false;
2285                 }
2286             }
2287         }
2288         return valid;
2289     }
2290 
2291 
2292     public boolean isNotificationRequired(OleInvoiceDocument oleInvoiceDocument) {
2293         boolean isAmountExceeds = false;
2294         List<OleInvoiceEncumbranceNotification> invoiceEncumbranceNotificationList = new ArrayList<>();
2295         List<OleInvoiceItem> oleInvoiceItems = oleInvoiceDocument.getItems();
2296         for (OleInvoiceItem oleInvoiceItem : oleInvoiceItems) {
2297             if (oleInvoiceItem.getExtendedPrice() != null && oleInvoiceItem.getItemType().isQuantityBasedGeneralLedgerIndicator()) {
2298                 KualiDecimal extendedCost = oleInvoiceItem.getExtendedPrice();
2299                 List<PurApAccountingLine> sourceAccountingLines = oleInvoiceItem.getSourceAccountingLines();
2300                 for (PurApAccountingLine accLine : sourceAccountingLines) {
2301                     Map<String, Object> key = new HashMap<String, Object>();
2302                     String chartCode = accLine.getChartOfAccountsCode();
2303                     String accNo = accLine.getAccountNumber();
2304                     key.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartCode);
2305                     key.put(OLEPropertyConstants.ACCOUNT_NUMBER, accNo);
2306                     Account account = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(
2307                             Account.class, key);
2308                     if (account != null) {
2309                         KualiDecimal thresholdAmount = null;
2310                         KualiDecimal thresholdPercentLimit = null;
2311                         KualiDecimal thresholdPercentage = null;
2312                         KualiDecimal purchaseOrderAmount = KualiDecimal.ZERO;
2313                         if (oleInvoiceItem.getPurchaseOrderItemUnitPrice() != null) {
2314                             purchaseOrderAmount = new KualiDecimal(oleInvoiceItem.getPurchaseOrderItemUnitPrice());
2315                         }
2316                         if (account.getThresholdAmount() != null && oleInvoiceItem.getExtendedPrice() != null) {
2317                             thresholdAmount = account.getThresholdAmount();
2318                             thresholdAmount = thresholdAmount.add(purchaseOrderAmount);
2319                         }
2320                         if (account.getThresholdPercentage() != null && oleInvoiceItem.getExtendedPrice() != null) {
2321                             thresholdPercentLimit = calculateThresholdAmount(account.getThresholdPercentage(), purchaseOrderAmount);
2322                             thresholdPercentLimit = thresholdPercentLimit.add(purchaseOrderAmount);
2323                         }
2324                         if (thresholdAmount != null && thresholdPercentLimit != null) {
2325                             if (extendedCost.isGreaterThan(thresholdAmount) && extendedCost.isGreaterThan(thresholdPercentLimit)) {
2326                                 OleInvoiceEncumbranceNotification invoiceEncumbranceNotification = new OleInvoiceEncumbranceNotification();
2327                                 invoiceEncumbranceNotification.setItemTitle(oleInvoiceItem.getItemDescription());
2328                                 invoiceEncumbranceNotification.setPurchaseOrderIdentifier(oleInvoiceItem.getPurchaseOrderIdentifier().toString());
2329                                 invoiceEncumbranceNotification.setPurchaseOrderAmount(purchaseOrderAmount.toString());
2330                                 invoiceEncumbranceNotification.setInvoiceAmount(oleInvoiceItem.getExtendedPrice().toString());
2331                                 invoiceEncumbranceNotification.setDifferenceByThresholdAmount((extendedCost.subtract(purchaseOrderAmount)).toString());
2332                                 invoiceEncumbranceNotificationList.add(invoiceEncumbranceNotification);
2333                             }
2334                         } else if (thresholdAmount != null) {
2335                             if (extendedCost.isGreaterThan(thresholdAmount)) {
2336                                 OleInvoiceEncumbranceNotification invoiceEncumbranceNotification = new OleInvoiceEncumbranceNotification();
2337                                 invoiceEncumbranceNotification.setItemTitle(oleInvoiceItem.getItemDescription());
2338                                 invoiceEncumbranceNotification.setPurchaseOrderIdentifier(oleInvoiceItem.getPurchaseOrderIdentifier().toString());
2339                                 invoiceEncumbranceNotification.setPurchaseOrderAmount(purchaseOrderAmount.toString());
2340                                 invoiceEncumbranceNotification.setInvoiceAmount(oleInvoiceItem.getExtendedPrice().toString());
2341                                 invoiceEncumbranceNotification.setDifferenceByThresholdAmount((extendedCost.subtract(purchaseOrderAmount)).toString());
2342                                 invoiceEncumbranceNotificationList.add(invoiceEncumbranceNotification);
2343                             }
2344                         } else if (thresholdPercentLimit != null) {
2345                             if (extendedCost.isGreaterThan(thresholdPercentLimit)) {
2346                                 OleInvoiceEncumbranceNotification invoiceEncumbranceNotification = new OleInvoiceEncumbranceNotification();
2347                                 invoiceEncumbranceNotification.setItemTitle(oleInvoiceItem.getItemDescription());
2348                                 invoiceEncumbranceNotification.setPurchaseOrderIdentifier(oleInvoiceItem.getPurchaseOrderIdentifier().toString());
2349                                 invoiceEncumbranceNotification.setPurchaseOrderAmount(purchaseOrderAmount.toString());
2350                                 invoiceEncumbranceNotification.setInvoiceAmount(oleInvoiceItem.getExtendedPrice().toString());
2351                                 invoiceEncumbranceNotification.setDifferenceByThresholdAmount((extendedCost.subtract(purchaseOrderAmount)).toString());
2352                                 invoiceEncumbranceNotificationList.add(invoiceEncumbranceNotification);
2353                             }
2354                         }
2355                     }
2356                 }
2357             }
2358         }
2359         if (invoiceEncumbranceNotificationList != null && invoiceEncumbranceNotificationList.size() > 0) {
2360             this.invoiceEncumbranceNotificationList = invoiceEncumbranceNotificationList;
2361             return true;
2362         }
2363         oleInvoiceDocument.setAmountExceeds(isAmountExceeds);
2364         return isAmountExceeds;
2365     }
2366 
2367 
2368     public KualiDecimal calculateThresholdAmount(KualiDecimal thresholdPercentage, KualiDecimal purchaseOrderAmount) {
2369         KualiDecimal thresholdLimt = (purchaseOrderAmount.multiply(thresholdPercentage)).divide(new KualiDecimal(100));
2370         return thresholdLimt;
2371     }
2372 
2373 
2374 
2375     public String createInvoiceAmountExceedsThresholdText(OleInvoiceDocument oleinvoiceDocument) {
2376         StringBuffer warningMessageBuffer = new StringBuffer("");
2377         warningMessageBuffer.append("Warning: Some Titles on this Invoice are billed at a significantly higher rate than the PO line indicated:");
2378         warningMessageBuffer.append("<br/><br/><b>Summary Detail Below :</b><br/><br/><table border=\"1\">");
2379         warningMessageBuffer.append("<tr><th>Title</th>").
2380                 append("<th>PO #</th>").
2381                 append("<th>PO Price</th>").append("<th>Invoiced Price</th>").
2382                 append("<th>Difference</th>");
2383         List<OleInvoiceEncumbranceNotification> oleInvoiceEncumbranceNotificationList = this.invoiceEncumbranceNotificationList;
2384         for (int accCount = 0; accCount < oleInvoiceEncumbranceNotificationList.size(); accCount++) {
2385             warningMessageBuffer.append("<tr><td>").append(oleInvoiceEncumbranceNotificationList.get(accCount).getItemTitle()).append("</td><td>").
2386                     append(oleInvoiceEncumbranceNotificationList.get(accCount).getPurchaseOrderIdentifier()).append("</td><td>").
2387                     append(oleInvoiceEncumbranceNotificationList.get(accCount).getPurchaseOrderAmount()).append("</td><td>").
2388                     append(oleInvoiceEncumbranceNotificationList.get(accCount).getInvoiceAmount()).append("</td><td>").
2389                     append(oleInvoiceEncumbranceNotificationList.get(accCount).getDifferenceByThresholdAmount());
2390 
2391         }
2392         warningMessageBuffer.append("</td></tr></table>");
2393         warningMessageBuffer.append("<br/>Do you want to approve the invoice anyway?");
2394         return warningMessageBuffer.toString();
2395     }
2396 
2397     public OleInvoiceRecord populateValuesFromProfile(BibMarcRecord bibMarcRecord){
2398         OleInvoiceRecord oleInvoiceRecord = new OleInvoiceRecord();
2399         mapDataFieldsToInvoiceRecord(oleInvoiceRecord,bibMarcRecord);
2400         setDefaultAndConstantValuesToInvoiceRecord(oleInvoiceRecord);
2401         checkForForeignCurrency(oleInvoiceRecord);
2402         oleInvoiceRecord.setUnitPrice(oleInvoiceRecord.getListPrice());
2403         return oleInvoiceRecord;
2404     }
2405 
2406     private void mapDataFieldsToInvoiceRecord(OleInvoiceRecord oleInvoiceRecord,BibMarcRecord bibMarcRecord) {
2407         List<OLEBatchProcessProfileMappingOptionsBo> oleBatchProcessProfileMappingOptionsBoList = oleBatchProcessProfileBo.getOleBatchProcessProfileMappingOptionsList();
2408         for (OLEBatchProcessProfileMappingOptionsBo oleBatchProcessProfileMappingOptionsBo : oleBatchProcessProfileMappingOptionsBoList) {
2409             List<OLEBatchProcessProfileDataMappingOptionsBo> oleBatchProcessProfileDataMappingOptionsBoList = oleBatchProcessProfileMappingOptionsBo.getOleBatchProcessProfileDataMappingOptionsBoList();
2410             Collections.sort(oleBatchProcessProfileDataMappingOptionsBoList, new Comparator<OLEBatchProcessProfileDataMappingOptionsBo>() {
2411                 @Override
2412                 public int compare(OLEBatchProcessProfileDataMappingOptionsBo obj1, OLEBatchProcessProfileDataMappingOptionsBo obj2) {
2413                     int result = obj1.getDestinationField().compareTo(obj2.getDestinationField());
2414                     if(result != 0){
2415                         return result;
2416                     }
2417                     return obj1.getPriority() < obj2.getPriority() ? -1 : obj1.getPriority() > obj2.getPriority() ? 1 : 0;
2418                 }
2419             });
2420             List<String> failureRecords = new ArrayList<>();
2421             for (int dataMapCount = 0;dataMapCount<oleBatchProcessProfileDataMappingOptionsBoList.size();dataMapCount++) {
2422                 if (StringUtils.isNotBlank(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDataTypeDestinationField()) &&
2423                         StringUtils.isNotBlank(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getSourceField()) && StringUtils.isNotBlank(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2424                     String sourceField = oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getSourceField();
2425                     String sourceFields[] = sourceField.split("\\$");
2426                     if (sourceFields.length == 2) {
2427                         String dataField = sourceFields[0].trim();
2428                         String tagField = sourceFields[1].trim();
2429                         if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_ITEM_IDENTIFIER.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2430                             String vendorItemIdentifier = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2431                             if(!StringUtils.isBlank(vendorItemIdentifier)){
2432                                 oleInvoiceRecord.setVendorItemIdentifier(vendorItemIdentifier);
2433                             }
2434                             else {
2435                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_VENDOR_ITEM_IDENTIFIER +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2436                             }
2437                         }
2438                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_NUMBER.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2439                             String vendorNumber = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2440                             if(!StringUtils.isBlank(vendorNumber)) {
2441                                 boolean validVendorNumber = getOleOrderRecordService().validateVendorNumber(vendorNumber);
2442                                 if(!validVendorNumber){
2443                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_VENDOR_NUMBER + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + vendorNumber);
2444                                     vendorNumber = null;
2445                                 }
2446                                 oleInvoiceRecord.setVendorNumber(vendorNumber);
2447                             }
2448                             else {
2449                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_VENDOR_NUMBER + " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2450                             }
2451                         }
2452                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.LIST_PRICE.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2453                             String listPrice = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2454                             if(!StringUtils.isBlank(listPrice)){
2455                                 if(!StringUtils.isBlank(listPrice)){
2456                                     boolean validListPrice = getOleOrderRecordService().validateDestinationFieldValues(listPrice);
2457                                     if(!validListPrice){
2458                                         failureRecords.add(org.kuali.ole.OLEConstants.INVALID_INVOICED_PRICE + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + listPrice);
2459                                         listPrice = null;
2460                                     }
2461                                     else {
2462                                         listPrice = Float.parseFloat(listPrice) + "";
2463                                     }
2464                                     oleInvoiceRecord.setListPrice(listPrice);
2465                                 }
2466                             }
2467                             else{
2468                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_INVOICED_PRICE +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2469                             }
2470                         }
2471                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.FOREIGN_LIST_PRICE.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2472                             String foreignListPrice = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2473                             if(!StringUtils.isBlank(foreignListPrice)){
2474                                 if(!StringUtils.isBlank(foreignListPrice)){
2475                                     boolean validForeignListPrice = getOleOrderRecordService().validateDestinationFieldValues(foreignListPrice);
2476                                     if(!validForeignListPrice){
2477                                         failureRecords.add(org.kuali.ole.OLEConstants.INVALID_FOREIGN_INVOICED_PRICE + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + foreignListPrice);
2478                                         foreignListPrice = null;
2479                                     }
2480                                     else {
2481                                         foreignListPrice = Float.parseFloat(foreignListPrice) + "";
2482                                     }
2483                                     oleInvoiceRecord.setForeignListPrice(foreignListPrice);
2484                                 }
2485                             }
2486                             else{
2487                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_INVOICED_FOREIGN_PRICE +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2488                             }
2489                         }
2490                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.QUANTITY.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2491                             String quantity = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2492                             if(!StringUtils.isBlank(quantity)) {
2493                                 boolean validQuantity = getOleOrderRecordService().validateForNumber(quantity);
2494                                 if(!validQuantity){
2495                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_QTY + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + quantity);
2496                                     quantity = null;
2497                                 }
2498                                 oleInvoiceRecord.setQuantity(quantity);
2499                             }
2500                             else {
2501                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_QTY + " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2502                             }
2503                         }
2504                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_TYPES.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2505                             String itemType = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2506                             if(!StringUtils.isBlank(itemType)){
2507                                 Map<String,String> itemTypeMap = new HashMap<>();
2508                                 itemTypeMap.put(org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_TYPE_CODE, itemType);
2509                                 List<ItemType> itemTypeList = (List) getBusinessObjectService().findMatching(ItemType.class, itemTypeMap);
2510                                 if(itemTypeList != null && itemTypeList.size() == 0){
2511                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_ITEM_TYPE_CD + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + itemType);
2512                                 }
2513                                 oleInvoiceRecord.setItemType(org.kuali.ole.OLEConstants.ITEM_TYP);
2514                             }
2515                             else {
2516                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_ITEM_TYPE + " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2517                             }
2518                         }
2519                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_NUMBER.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2520                             String invoiceNumber = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2521                             if(!StringUtils.isBlank(invoiceNumber)) {
2522                                 /*boolean validInvoiceNumber = getOleOrderRecordService().validateForNumber(invoiceNumber);
2523                                 if(!validInvoiceNumber){
2524                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_INV_NMBR + "  "+ dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + invoiceNumber);
2525                                     invoiceNumber = null;
2526                                 }*/
2527                                 oleInvoiceRecord.setInvoiceNumber(invoiceNumber);
2528                             }
2529                             else {
2530                                 //failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_INVOICE_NUMBER +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2531                             }
2532                         }
2533                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_DATE.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2534                             String invoiceDate = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2535                             if(!StringUtils.isBlank(invoiceDate)){
2536                                 boolean validInvoiceDate = validateInvoiceDate(invoiceDate);
2537                                 if(!validInvoiceDate){
2538                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_INV_DT + "  " + dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + "  "  + invoiceDate + "  " +  "Allowed format is yyyymmdd");
2539                                 }
2540                                 oleInvoiceRecord.setInvoiceDate(invoiceDate);
2541                             }
2542                             else {
2543                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_INVOICE_DATE +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2544                             }
2545                         }
2546                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_DESCRIPTION.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2547                             String itemDescription = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2548                             if(!StringUtils.isBlank(itemDescription)){
2549                                 oleInvoiceRecord.setItemDescription(itemDescription);
2550                             }
2551                             else {
2552                                 //failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_ITEM_DESCRIPTION +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2553                             }
2554                         }
2555                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ACCOUNT_NUMBER.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2556                             String accountNumber = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2557                             if(!StringUtils.isBlank(accountNumber)){
2558                                 Map<String,String> accountNumberMap = new HashMap<>();
2559                                 accountNumberMap.put(org.kuali.ole.OLEConstants.OLEBatchProcess.ACCOUNT_NUMBER, accountNumber);
2560                                 List<Account> accountNumberList = (List) getBusinessObjectService().findMatching(Account.class, accountNumberMap);
2561                                 if(accountNumberList.size() == 0){
2562                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_ACCOUNT_NUMBER + "  " +dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField +"  " + accountNumber);
2563                                     accountNumber = null;
2564                                 }
2565                                 oleInvoiceRecord.setAccountNumber(accountNumber);
2566                             }
2567                             else {
2568                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_ACCOUNT_NUMBER +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2569                             }
2570                         }
2571                         else if (org.kuali.ole.OLEConstants.OLEBatchProcess.OBJECT_CODE.equals(oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount).getDestinationField())) {
2572                             String objectCode = setDataMappingValues(oleBatchProcessProfileDataMappingOptionsBoList,dataMapCount,bibMarcRecord,dataField,tagField);
2573                             if(!StringUtils.isBlank(objectCode)){
2574                                 Map<String,String> objectCodeMap = new HashMap<>();
2575                                 objectCodeMap.put(org.kuali.ole.OLEConstants.OLEBatchProcess.OBJECT_CODE, objectCode);
2576                                 List<ObjectCode> objectCodeList = (List) getBusinessObjectService().findMatching(ObjectCode.class, objectCodeMap);
2577                                 if(objectCodeList.size() == 0){
2578                                     failureRecords.add(org.kuali.ole.OLEConstants.INVALID_OBJECT_CODE + "  " +dataField + " " + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField +"  " + objectCode);
2579                                     objectCode = null;
2580                                 }
2581                                 oleInvoiceRecord.setObjectCode(objectCode);
2582                             }
2583                             else {
2584                                 failureRecords.add(org.kuali.ole.OLEConstants.REQUIRED_OBJECT_CODE +  " " + dataField + org.kuali.ole.OLEConstants.DELIMITER_DOLLAR + tagField + " " + org.kuali.ole.OLEConstants.NULL_VALUE_MESSAGE);
2585                             }
2586                         }
2587                     }
2588                 }
2589             }
2590             if(failureRecords != null && failureRecords.size() > 0){
2591                 List reasonForFailure = (List) dataCarrierService.getData("invoiceIngestFailureReason");
2592                 if(reasonForFailure != null){
2593                     reasonForFailure.addAll(failureRecords);
2594                     reasonForFailure.add("==================================================================================");
2595                     dataCarrierService.addData("invoiceIngestFailureReason",reasonForFailure);
2596                 }
2597             }
2598         }
2599     }
2600 
2601     public void setDefaultAndConstantValuesToInvoiceRecord(OleInvoiceRecord oleInvoiceRecord) {
2602         List<OLEBatchProcessProfileConstantsBo> oleBatchProcessProfileConstantsBoList = oleBatchProcessProfileBo.getOleBatchProcessProfileConstantsList();
2603         for (OLEBatchProcessProfileConstantsBo oleBatchProcessProfileConstantsBo : oleBatchProcessProfileConstantsBoList) {
2604             if (StringUtils.isNotBlank(oleBatchProcessProfileConstantsBo.getDataType()) && org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_IMPORT.equalsIgnoreCase(oleBatchProcessProfileConstantsBo.getDataType())
2605                     && StringUtils.isNotBlank(oleBatchProcessProfileConstantsBo.getAttributeValue()) && StringUtils.isNotBlank(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2606                 if (org.kuali.ole.OLEConstants.OLEBatchProcess.CONSTANT.equals(oleBatchProcessProfileConstantsBo.getDefaultValue())) {
2607 
2608                     if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_ITEM_IDENTIFIER.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2609                         oleInvoiceRecord.setVendorItemIdentifier(oleBatchProcessProfileConstantsBo.getAttributeValue());
2610                     }
2611                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2612                         oleInvoiceRecord.setVendorNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2613                     }
2614                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.LIST_PRICE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2615                         oleInvoiceRecord.setListPrice(oleBatchProcessProfileConstantsBo.getAttributeValue());
2616                     }
2617                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.FOREIGN_LIST_PRICE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2618                         oleInvoiceRecord.setForeignListPrice(oleBatchProcessProfileConstantsBo.getAttributeValue());
2619                     }
2620                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.QUANTITY.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2621                         oleInvoiceRecord.setQuantity(oleBatchProcessProfileConstantsBo.getAttributeValue());
2622                     }
2623                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_TYPES.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2624                         oleInvoiceRecord.setItemType(org.kuali.ole.OLEConstants.ITEM_TYP);
2625                     }
2626                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2627                         oleInvoiceRecord.setInvoiceNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2628                     }
2629                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_DATE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2630                         oleInvoiceRecord.setInvoiceDate(oleBatchProcessProfileConstantsBo.getAttributeValue());
2631                     }
2632                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_DESCRIPTION.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2633                         oleInvoiceRecord.setItemDescription(oleBatchProcessProfileConstantsBo.getAttributeValue());
2634                     }
2635                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.ACCOUNT_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2636                         oleInvoiceRecord.setAccountNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2637                     }
2638                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.OBJECT_CODE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2639                         oleInvoiceRecord.setObjectCode(oleBatchProcessProfileConstantsBo.getAttributeValue());
2640                     }
2641                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.CURRENCY_TYPE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2642                         oleInvoiceRecord.setCurrencyType(oleBatchProcessProfileConstantsBo.getAttributeValue());
2643                         oleInvoiceRecord.setCurrencyTypeId(getCurrencyTypeIdFromCurrencyType(oleInvoiceRecord.getCurrencyType()));
2644                     }
2645                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.EXCHANGE_RATE.equals(oleBatchProcessProfileConstantsBo.getAttributeName())) {
2646                         oleInvoiceRecord.setInvoiceCurrencyExchangeRate(oleBatchProcessProfileConstantsBo.getAttributeValue());
2647                     }
2648                 }
2649                 else if (org.kuali.ole.OLEConstants.OLEBatchProcess.DEFAULT.equals(oleBatchProcessProfileConstantsBo.getDefaultValue())) {
2650 
2651                     if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_ITEM_IDENTIFIER.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getVendorItemIdentifier())) {
2652                         oleInvoiceRecord.setVendorItemIdentifier(oleBatchProcessProfileConstantsBo.getAttributeValue());
2653                     }
2654                     if (org.kuali.ole.OLEConstants.OLEBatchProcess.VENDOR_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getVendorNumber())) {
2655                         oleInvoiceRecord.setVendorNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2656                     }
2657                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.LIST_PRICE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getListPrice())) {
2658                         oleInvoiceRecord.setListPrice(oleBatchProcessProfileConstantsBo.getAttributeValue());
2659                     }
2660                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.FOREIGN_LIST_PRICE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getForeignListPrice())) {
2661                         oleInvoiceRecord.setForeignListPrice(oleBatchProcessProfileConstantsBo.getAttributeValue());
2662                     }
2663                     else if (org.kuali.ole.OLEConstants.OLEBatchProcess.QUANTITY.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getQuantity())) {
2664                         oleInvoiceRecord.setQuantity(oleBatchProcessProfileConstantsBo.getAttributeValue());
2665                     }
2666                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_TYPES.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getItemType())) {
2667                         oleInvoiceRecord.setItemType(org.kuali.ole.OLEConstants.ITEM_TYP);
2668                     }
2669                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getInvoiceNumber())) {
2670                         oleInvoiceRecord.setInvoiceNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2671                     }
2672                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.INVOICE_DATE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getInvoiceDate())) {
2673                         oleInvoiceRecord.setInvoiceDate(oleBatchProcessProfileConstantsBo.getAttributeValue());
2674                     }
2675                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.ITEM_DESCRIPTION.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getItemDescription())) {
2676                         oleInvoiceRecord.setItemDescription(oleBatchProcessProfileConstantsBo.getAttributeValue());
2677                     }
2678                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.ACCOUNT_NUMBER.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getAccountNumber())) {
2679                         oleInvoiceRecord.setAccountNumber(oleBatchProcessProfileConstantsBo.getAttributeValue());
2680                     }
2681                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.OBJECT_CODE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getObjectCode())) {
2682                         oleInvoiceRecord.setObjectCode(oleBatchProcessProfileConstantsBo.getAttributeValue());
2683                     }
2684                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.CURRENCY_TYPE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getCurrencyType())) {
2685                         oleInvoiceRecord.setCurrencyType(oleBatchProcessProfileConstantsBo.getAttributeValue());
2686                         oleInvoiceRecord.setCurrencyTypeId(getCurrencyTypeIdFromCurrencyType(oleInvoiceRecord.getCurrencyType()));
2687                     }
2688                     else if(org.kuali.ole.OLEConstants.OLEBatchProcess.EXCHANGE_RATE.equals(oleBatchProcessProfileConstantsBo.getAttributeName()) && StringUtils.isBlank(oleInvoiceRecord.getInvoiceCurrencyExchangeRate())) {
2689                         oleInvoiceRecord.setInvoiceCurrencyExchangeRate(oleBatchProcessProfileConstantsBo.getAttributeValue());
2690                     }
2691                 }
2692             }
2693         }
2694     }
2695 
2696     public String getCurrencyTypeIdFromCurrencyType(String currencyType){
2697         Map<String,String> currencyTypeMap = new HashMap<>();
2698         currencyTypeMap.put(org.kuali.ole.OLEConstants.OLEBatchProcess.CURRENCY_TYPE,currencyType);
2699         List<OleCurrencyType> currencyTypeList = (List) getBusinessObjectService().findMatching(OleCurrencyType.class, currencyTypeMap);
2700         return currencyTypeList.get(0).getCurrencyTypeId().toString();
2701     }
2702 
2703     private String getSubFieldValueFor(BibMarcRecord bibMarcRecord, String dataField, String tag) {
2704         String subFieldValue = null;
2705         org.kuali.ole.docstore.common.document.content.bib.marc.DataField dataFieldForTag = getDataFieldForTag(bibMarcRecord, dataField);
2706         if (null != dataFieldForTag) {
2707             List<org.kuali.ole.docstore.common.document.content.bib.marc.SubField> subfields = dataFieldForTag.getSubFields();
2708             for (Iterator<org.kuali.ole.docstore.common.document.content.bib.marc.SubField> iterator = subfields.iterator(); iterator.hasNext(); ) {
2709                 org.kuali.ole.docstore.common.document.content.bib.marc.SubField marcSubField = iterator.next();
2710                 if (marcSubField.getCode().equals(tag)) {
2711                     return marcSubField.getValue();
2712                 }
2713             }
2714         }
2715         return subFieldValue;
2716     }
2717 
2718     public org.kuali.ole.docstore.common.document.content.bib.marc.DataField getDataFieldForTag(BibMarcRecord bibMarcRecord, String tag) {
2719         for (Iterator<org.kuali.ole.docstore.common.document.content.bib.marc.DataField> iterator = bibMarcRecord.getDataFields().iterator(); iterator.hasNext(); ) {
2720             org.kuali.ole.docstore.common.document.content.bib.marc.DataField marcDataField = iterator.next();
2721             if (marcDataField.getTag().equalsIgnoreCase(tag)) {
2722                 return marcDataField;
2723             }
2724         }
2725         return null;
2726     }
2727 
2728 
2729     private String setDataMappingValues(List<OLEBatchProcessProfileDataMappingOptionsBo> oleBatchProcessProfileDataMappingOptionsBoList,int dataMapCount,BibMarcRecord bibMarcRecord,String dataField,String tagField){
2730         String subFieldValue = getSubFieldValueFor(bibMarcRecord, dataField, tagField);
2731         if (StringUtils.isBlank(subFieldValue)) {
2732             OLEBatchProcessProfileDataMappingOptionsBo oleBatchProcessProfileDataMappingOptionsBo = oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount);
2733             if (dataMapCount+1 <= oleBatchProcessProfileDataMappingOptionsBoList.size()) {
2734                 if(dataMapCount+1 == oleBatchProcessProfileDataMappingOptionsBoList.size()) {
2735                     subFieldValue = oleBatchProcessProfileDataMappingOptionsBo.getDestinationFieldValue();
2736                 }
2737                 else if(!oleBatchProcessProfileDataMappingOptionsBoList.get(dataMapCount+1).getDestinationField().equalsIgnoreCase(oleBatchProcessProfileDataMappingOptionsBo.getDestinationField())){
2738                     subFieldValue = oleBatchProcessProfileDataMappingOptionsBo.getDestinationFieldValue();
2739                 }
2740             }
2741         }
2742         return subFieldValue;
2743     }
2744 
2745     private boolean validateInvoiceDate(String invoiceDate){
2746         SimpleDateFormat dateFromRawFile = new SimpleDateFormat(org.kuali.ole.OLEConstants.DATE_FORMAT);
2747         try {
2748             dateFromRawFile.parse(invoiceDate);
2749             return true;
2750         }
2751         catch (ParseException e) {
2752             return false;
2753         }
2754     }
2755 
2756     private void checkForForeignCurrency(OleInvoiceRecord oleInvoiceRecord){
2757         if(!StringUtils.isBlank(oleInvoiceRecord.getCurrencyType())){
2758             if(!oleInvoiceRecord.getCurrencyType().equalsIgnoreCase(OleSelectConstant.CURRENCY_TYPE_NAME)){
2759                 if (oleInvoiceRecord.getForeignListPrice() != null && !oleInvoiceRecord.getForeignListPrice().isEmpty() &&
2760                         oleInvoiceRecord.getInvoiceCurrencyExchangeRate()!= null &&  !oleInvoiceRecord.getInvoiceCurrencyExchangeRate().isEmpty()) {
2761                     oleInvoiceRecord.setListPrice((new BigDecimal(oleInvoiceRecord.getForeignListPrice()).
2762                             divide(new BigDecimal(oleInvoiceRecord.getInvoiceCurrencyExchangeRate()), 4, RoundingMode.HALF_UP)).toString());
2763                 }
2764             }
2765         }
2766     }
2767 
2768 
2769     @Override
2770     public String getCurrencyType(String currencyTypeId) {
2771         if(StringUtils.isNotBlank(currencyTypeId)){
2772             Map currencyMap = new HashMap();
2773             currencyMap.put(OleSelectConstant.CURRENCY_TYPE_ID, new Long(currencyTypeId));
2774             OleCurrencyType oleCurrencyType = KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(OleCurrencyType.class,currencyMap);
2775             if(oleCurrencyType != null){
2776                 return oleCurrencyType.getCurrencyType();
2777             }
2778         }
2779         return "";
2780     }
2781 
2782 
2783     @Override
2784     public OleExchangeRate getExchangeRate(String currencyTypeId) {
2785         Map documentNumberMap = new HashMap();
2786         documentNumberMap.put(OleSelectConstant.CURRENCY_TYPE_ID, new Long(currencyTypeId));
2787         List<OleExchangeRate> exchangeRateList = (List) getBusinessObjectService().findMatchingOrderBy(OleExchangeRate.class, documentNumberMap, OleSelectConstant.EXCHANGE_RATE_DATE, false);
2788         Iterator iterator = exchangeRateList.iterator();
2789         if (iterator.hasNext()) {
2790             OleExchangeRate tempOleExchangeRate = (OleExchangeRate) iterator.next();
2791             return tempOleExchangeRate;
2792         }
2793         return null;
2794     }
2795 
2796     @Override
2797     public void deleteInvoiceItem(OleInvoiceDocument oleInvoiceDocument) {
2798         List<OleInvoiceItem> oleDeletedInvoiceItemList =oleInvoiceDocument.getDeletedInvoiceItems();
2799         for(OleInvoiceItem oleInvoiceItem:oleDeletedInvoiceItemList){
2800             List<OLEPaidCopy> olePaidCopies = oleInvoiceItem.getPaidCopies();
2801             for(OLEPaidCopy olePaidCopy : olePaidCopies){
2802                 Map<String,Integer> olePaidCopyMap=new HashMap<String,Integer>();
2803                 olePaidCopyMap.put("olePaidCopyId",olePaidCopy.getOlePaidCopyId());
2804                 KRADServiceLocator.getBusinessObjectService().deleteMatching(OLEPaidCopy.class,olePaidCopyMap);
2805             }
2806             Map<String,Integer> invoiceAccountMap=new HashMap<String,Integer>();
2807             invoiceAccountMap.put("itemIdentifier",oleInvoiceItem.getItemIdentifier());
2808             KRADServiceLocator.getBusinessObjectService().deleteMatching(InvoiceAccount.class,invoiceAccountMap);
2809             Map<String,Integer> invoiceItemMap=new HashMap<String,Integer>();
2810             invoiceItemMap.put("itemIdentifier",oleInvoiceItem.getItemIdentifier());
2811             KRADServiceLocator.getBusinessObjectService().deleteMatching(OleInvoiceItem.class,invoiceItemMap);
2812         }
2813     }
2814 }