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