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.StringUtils;
20  import org.kuali.ole.module.purap.PurapConstants;
21  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderDocTypes;
22  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses;
23  import org.kuali.ole.module.purap.businessobject.*;
24  import org.kuali.ole.module.purap.document.PaymentRequestDocument;
25  import org.kuali.ole.module.purap.document.PurchaseOrderAmendmentDocument;
26  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
27  import org.kuali.ole.module.purap.document.service.LogicContainer;
28  import org.kuali.ole.module.purap.document.service.OlePurapService;
29  import org.kuali.ole.module.purap.document.service.PurapService;
30  import org.kuali.ole.module.purap.document.service.PurchaseOrderService;
31  import org.kuali.ole.module.purap.document.service.impl.PaymentRequestServiceImpl;
32  import org.kuali.ole.module.purap.service.PurapAccountingService;
33  import org.kuali.ole.select.OleSelectConstant;
34  import org.kuali.ole.select.businessobject.OlePaymentMethod;
35  import org.kuali.ole.select.businessobject.OlePaymentRequestItem;
36  import org.kuali.ole.select.businessobject.OlePurchaseOrderItem;
37  import org.kuali.ole.select.document.OlePaymentRequestDocument;
38  import org.kuali.ole.select.document.service.OlePaymentRequestService;
39  import org.kuali.ole.select.document.service.OlePurapAccountingService;
40  import org.kuali.ole.select.document.service.OleSelectDocumentService;
41  import org.kuali.ole.sys.OLEConstants;
42  import org.kuali.ole.sys.OLEKeyConstants;
43  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
44  import org.kuali.ole.sys.context.SpringContext;
45  import org.kuali.rice.core.api.util.type.KualiDecimal;
46  import org.kuali.rice.kew.api.exception.WorkflowException;
47  import org.kuali.rice.krad.bo.Note;
48  import org.kuali.rice.krad.service.DocumentService;
49  import org.kuali.rice.krad.service.KRADServiceLocator;
50  import org.kuali.rice.krad.service.NoteService;
51  import org.kuali.rice.krad.util.GlobalVariables;
52  import org.kuali.rice.krad.util.ObjectUtils;
53  
54  import java.math.BigDecimal;
55  import java.math.RoundingMode;
56  import java.util.*;
57  
58  /**
59   * This class has implementation for PaymentRequesr with respect to OLE.
60   */
61  public class OlePaymentRequestServiceImpl extends PaymentRequestServiceImpl implements OlePaymentRequestService {
62  
63      protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OlePaymentRequestServiceImpl.class);
64  
65      protected PurchaseOrderService purchaseOrderService;
66      protected PurapService purapService;
67      protected DocumentService documentService;
68      protected NoteService noteService;
69      private OlePurapAccountingService olePurapAccountingService;
70      private PurapAccountingService purapAccountingService;
71      private OleSelectDocumentService oleSelectDocumentService;
72  
73      @Override
74      public void setPurapService(PurapService purapService) {
75          this.purapService = purapService;
76      }
77  
78      @Override
79      public void setPurchaseOrderService(PurchaseOrderService purchaseOrderService) {
80          this.purchaseOrderService = purchaseOrderService;
81      }
82  
83      @Override
84      public void setDocumentService(DocumentService documentService) {
85          this.documentService = documentService;
86      }
87  
88      @Override
89      public void setNoteService(NoteService noteService) {
90          this.noteService = noteService;
91      }
92  
93  
94      @Override
95      public void setPurapAccountingService(PurapAccountingService purapAccountingService) {
96          this.purapAccountingService = purapAccountingService;
97      }
98  
99      public void setOlePurapAccountingService(OlePurapAccountingService olePurapAccountingService) {
100         this.olePurapAccountingService = olePurapAccountingService;
101     }
102 
103     /**
104      * This method deletes unneeded items and updates the totals on the po and does any additional processing based on items
105      *
106      * @see org.kuali.ole.select.document.service.OlePaymentRequestService#completePaymentDocument(org.kuali.ole.select.document.OlePaymentRequestDocument)
107      */
108     @Override
109     public void completePaymentDocument(OlePaymentRequestDocument paymentRequestDocument) {
110         LOG.debug("Inside CompletePaymentDocument");
111 
112         PurchaseOrderDocument poDoc = null;
113 
114         if (paymentRequestDocument instanceof PaymentRequestDocument) {
115             // delete unentered items
116             purapService.deleteUnenteredItems(paymentRequestDocument);
117 
118             poDoc = paymentRequestDocument.getPurchaseOrderDocument();
119         }
120         updatePaymentTotalsOnPurchaseOrder(paymentRequestDocument, poDoc);
121 
122         purapService.saveDocumentNoValidation(poDoc);
123 
124         poDoc.setVendorName(paymentRequestDocument.getVendorDetail().getVendorName());
125 
126         spawnPoAmendmentForUnorderedItems(paymentRequestDocument, poDoc);
127 
128         purapService.saveDocumentNoValidation(paymentRequestDocument);
129 
130         LOG.debug("Leaving CompletePaymentDocument");
131     }
132 
133     protected void updatePaymentTotalsOnPurchaseOrder(OlePaymentRequestDocument paymentDocument, PurchaseOrderDocument poDoc) {
134        /* LOG.debug("Inside updatePaymentTotalsOnPurchaseOrder");
135         for (OlePaymentRequestItem paymentItem : (List<OlePaymentRequestItem>) paymentDocument.getItems()) {
136             ItemType itemType = paymentItem.getItemType();
137             if (StringUtils.equalsIgnoreCase(itemType.getItemTypeCode(), PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE)) {
138                 OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) poDoc.getItemByLineNumber(paymentItem.getItemLineNumber());
139 
140                 if (ObjectUtils.isNotNull(poItem)) {
141 
142                     KualiDecimal poItemReceivedTotal = poItem.getOutstandingQuantity();
143 
144                     KualiDecimal itemQuantity = paymentItem.getItemQuantity();
145 
146                     if (ObjectUtils.isNull(itemQuantity)) {
147                         itemQuantity = KualiDecimal.ZERO;
148                     }
149                     if (ObjectUtils.isNull(poItemReceivedTotal)) {
150                         poItemReceivedTotal = KualiDecimal.ZERO;
151                     }   */
152                     /* Modified for OLE - 2516
153                       poItem.setItemQuantity(itemQuantity);
154                     */
155                /*     poItem.setItemUnitPrice(paymentItem.getItemUnitPrice());
156                 }
157             }
158         }
159         LOG.debug("Leaving updatePaymentTotalsOnPurchaseOrder");  */
160 
161         LOG.debug("Inside updatePaymentTotalsOnPurchaseOrder");
162        // List<Integer> poList = new ArrayList();
163        // Integer invPoId = 0;
164       /*  for (PaymentRequestItem payItem : (List<PaymentRequestItem>) paymentDocument.getItems()) {
165             if (!(poList.contains(payItem.getPurchaseOrderIdentifier()))) {
166                 poList.add(payItem.getPurchaseOrderIdentifier());
167             }
168         }*/
169         for (PaymentRequestItem payItem : (List<PaymentRequestItem>) paymentDocument.getItems()) {
170          //   for (Integer purchaseOrderId : poList) {
171                 if (payItem.getItemType() != null && payItem.getItemType().getItemTypeCode() != null && StringUtils.equalsIgnoreCase(payItem.getItemType().getItemTypeCode(), PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE))
172                 {
173                     PurchaseOrderDocument purDoc = paymentDocument.getPurchaseOrderDocument();
174                     OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) purDoc.getItemByLineNumber(payItem.getItemLineNumber());
175 
176                     if (ObjectUtils.isNotNull(poItem)) {
177 
178                         KualiDecimal poItemReceivedTotal = poItem.getOutstandingQuantity();
179 
180                         KualiDecimal itemQuantity = payItem.getItemQuantity();
181 
182                         if (ObjectUtils.isNull(itemQuantity)) {
183                             itemQuantity = KualiDecimal.ZERO;
184                         }
185                         if (ObjectUtils.isNull(poItemReceivedTotal)) {
186                             poItemReceivedTotal = KualiDecimal.ZERO;
187                         }
188                         /* Modified for OLE - 2516
189                           poItem.setItemQuantity(itemQuantity);
190                         */
191                          //poItem.setItemUnitPrice(payItem.getItemUnitPrice());/*Modified for the jira 5458*/
192                     }
193                  //   purapService.saveDocumentNoValidation(poDoc);
194                 }
195 
196          }
197          LOG.debug("Leaving updatePaymentTotalsOnPurchaseOrder");
198     }
199     /**
200      * Spawns PO amendments for new unordered items on a PaymentRequest document.
201      *
202      * @param paymentDocument
203      * @param po
204      */
205     protected void spawnPoAmendmentForUnorderedItems(OlePaymentRequestDocument paymentDocument, PurchaseOrderDocument po) {
206 
207         LOG.debug("Inside spawnPoAmendmentForUnorderedItems");
208         if (paymentDocument instanceof OlePaymentRequestDocument) {
209             OlePaymentRequestDocument rlDoc = paymentDocument;
210 
211             //if a new item has been added spawn a purchase order amendment
212             if (hasNewUnorderedItem(paymentDocument)) {
213                 String newSessionUserId = getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER);
214                 try {
215 
216                     LogicContainer logicToRun = new LogicContainer() {
217                         @Override
218                         public Object runLogic(Object[] objects) throws Exception {
219                             OlePaymentRequestDocument rlDoc = (OlePaymentRequestDocument) objects[0];
220                             String poDocNumber = (String) objects[1];
221 
222                             //create a PO amendment
223                             PurchaseOrderAmendmentDocument amendmentPo = (PurchaseOrderAmendmentDocument) purchaseOrderService.createAndSavePotentialChangeDocument(poDocNumber, PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT, PurchaseOrderStatuses.APPDOC_AMENDMENT);
224 
225                             //add new lines to amendement
226                             addUnorderedItemsToAmendment(amendmentPo, rlDoc);
227 
228                             //route amendment
229                             documentService.routeDocument(amendmentPo, null, null);
230 
231                             //add note to amendment po document
232                             String note = "Purchase Order Amendment " + amendmentPo.getPurapDocumentIdentifier() + " (document id " + amendmentPo.getDocumentNumber() + ") created for new unordered line items (document id " + rlDoc.getDocumentNumber() + ")";
233 
234                             Note noteObj = documentService.createNoteFromDocument(amendmentPo, note);
235                             amendmentPo.addNote(noteObj);
236                             documentService.saveDocumentNotes(amendmentPo);
237                             noteService.save(noteObj);
238 
239                             return null;
240                         }
241                     };
242 
243                     purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, new Object[]{rlDoc, po.getDocumentNumber()});
244                 } catch (WorkflowException e) {
245                     String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
246                     throw new RuntimeException(errorMsg, e);
247                 } catch (Exception e) {
248                     throw new RuntimeException(e);
249                 }
250             }
251         }
252         LOG.debug("Leaving spawnPoAmendmentForUnorderedItems");
253     }
254 
255     /**
256      * Checks the item list for newly added items.
257      *
258      * @param paymentDoc
259      * @return
260      */
261     protected boolean hasNewUnorderedItem(OlePaymentRequestDocument paymentDoc) {
262         LOG.debug("Inside hasNewUnorderedItem");
263         boolean itemAdded = false;
264 
265         for (OlePaymentRequestItem prItem : (List<OlePaymentRequestItem>) paymentDoc.getItems()) {
266             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(prItem.getItemTypeCode())) {
267                 itemAdded = true;
268                 break;
269             }
270         }
271         LOG.debug("Leaving hasNewUnorderedItem");
272         return itemAdded;
273     }
274 
275     /**
276      * Adds an unordered item to a po amendment document.
277      *
278      * @param amendment
279      * @param rlDoc
280      */
281     protected void addUnorderedItemsToAmendment(PurchaseOrderAmendmentDocument amendment, OlePaymentRequestDocument rlDoc) {
282 
283         LOG.debug("Inside addUnorderedItemsToAmendment");
284         OlePurchaseOrderItem poi = null;
285 
286         for (OlePaymentRequestItem rlItem : (List<OlePaymentRequestItem>) rlDoc.getItems()) {
287             if (PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(rlItem.getItemTypeCode())) {
288                 poi = createPoItemFromPaymentLine(rlItem);
289                 poi.setDocumentNumber(amendment.getDocumentNumber());
290                 poi.refreshNonUpdateableReferences();
291                 amendment.addItem(poi);
292             }
293         }
294         LOG.debug("Leaving addUnorderedItemsToAmendment");
295 
296     }
297 
298     /**
299      * Creates a PO item from paymentRequest Line item.
300      *
301      * @param rlItem
302      * @return
303      */
304     protected OlePurchaseOrderItem createPoItemFromPaymentLine(OlePaymentRequestItem rlItem) {
305         LOG.debug("Inside createPoItemFromPaymentLine");
306         OlePurchaseOrderItem poi = new OlePurchaseOrderItem();
307         poi.setItemActiveIndicator(true);
308         poi.setItemTypeCode(rlItem.getItemTypeCode());
309         poi.setItemLineNumber(rlItem.getItemLineNumber());
310         poi.setItemCatalogNumber(rlItem.getItemCatalogNumber());
311         poi.setItemDescription(rlItem.getItemDescription());
312         poi.setItemQuantity(rlItem.getItemQuantity());
313         poi.setItemUnitOfMeasureCode(rlItem.getItemUnitOfMeasureCode());
314         poi.setItemUnitPrice(rlItem.getItemUnitPrice());
315 //        poi.setSourceAccountingLines(rlItem.getSourceAccountingLines());
316         poi.setItemNoOfParts(rlItem.getItemNoOfParts());
317         poi.setItemListPrice(rlItem.getItemListPrice());
318         poi.setItemDiscount(rlItem.getItemDiscount());
319         poi.setItemDiscountType(rlItem.getItemDiscountType());
320         poi.setFormatTypeId(rlItem.getFormatTypeId());
321 
322         //Foreign Currency
323         poi.setItemCurrencyType(rlItem.getItemCurrencyType());
324         poi.setItemForeignListPrice((rlItem.getItemForeignListPrice()));
325         poi.setItemForeignDiscount((rlItem.getItemForeignDiscount()));
326         poi.setItemForeignDiscountAmt((rlItem.getItemForeignDiscountAmt()));
327         poi.setItemForeignDiscountType(rlItem.getItemForeignDiscountType());
328         poi.setItemForeignUnitCost((rlItem.getItemForeignUnitCost()));
329         poi.setItemExchangeRate((rlItem.getItemExchangeRate()));
330         poi.setItemUnitCostUSD((rlItem.getItemUnitCostUSD()));
331         poi.setItemInvoicedTotalAmount(rlItem.getTotalAmount());
332         poi.setBibInfoBean(rlItem.getBibInfoBean());
333         poi.setItemTitleId(rlItem.getItemTitleId());
334         setAccountingLinesFromPayment(rlItem, poi);
335 
336         LOG.debug("Leaving createPoItemFromPaymentLine");
337         return poi;
338     }
339 
340     /**
341      * Setting Accounting Lines For POA from newLineItem
342      *
343      * @param payItem
344      * @param purItem
345      */
346 
347     public void setAccountingLinesFromPayment(OlePaymentRequestItem payItem, OlePurchaseOrderItem purItem) {
348         LOG.debug("Inside setAccountingLinesFromPayment");
349         for (int i = 0; i < payItem.getSourceAccountingLines().size(); i++) {
350             // OLE-3669 : Ensuring that the purchasing document has enough accounting lines
351             // for copying from the payment
352             while (purItem.getSourceAccountingLines().size() < i + 1) {
353                 PurchaseOrderAccount poAccount = new PurchaseOrderAccount();
354                 poAccount.setPurchaseOrderItem(purItem);
355                 purItem.getSourceAccountingLines().add(poAccount);
356             }
357             purItem.getSourceAccountingLine(i).copyFrom(payItem.getSourceAccountingLine(i));
358             purItem.getSourceAccountingLine(i).setAccountLinePercent(payItem.getSourceAccountingLine(i).getAccountLinePercent());
359         }
360         LOG.debug("Leaving setAccountingLinesFromPayment");
361     }
362 
363     /**
364      * @see org.kuali.ole.select.document.service.OlePaymentRequestService#calculateProrateItemSurcharge(org.kuali.ole.select.document.OlePaymentRequestDocument)
365      */
366     @Override
367     public void calculateProrateItemSurcharge(OlePaymentRequestDocument paymentRequestDocument) {
368         LOG.debug("Inside Calculation for ProrateItemSurcharge");
369         //  KualiDecimal addChargeItem = paymentRequestDocument.getGrandPreTaxTotalExcludingDiscount().subtract(paymentRequestDocument.getLineItemPreTaxTotal());
370         BigDecimal addChargeItem = BigDecimal.ZERO;
371         List<OlePaymentRequestItem> item = paymentRequestDocument.getItems();
372 
373         for (OlePaymentRequestItem items : item) {
374             if (!items.getItemType().isQuantityBasedGeneralLedgerIndicator() && !items.getItemTypeCode().equalsIgnoreCase(PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE) && items.getItemUnitPrice() != null) {
375                 addChargeItem = addChargeItem.add(items.getItemUnitPrice());
376             }
377         }
378         List<BigDecimal> newUnitPriceList = new ArrayList<BigDecimal>();
379         BigDecimal totalExtPrice = new BigDecimal(0);
380         BigDecimal newUnitPrice = new BigDecimal(0);
381         BigDecimal extPrice = new BigDecimal(0);
382         BigDecimal unitPricePercent = new BigDecimal(0);
383         BigDecimal hundred = new BigDecimal(100);
384         BigDecimal one = new BigDecimal(1);
385         BigDecimal totalSurCharge = new BigDecimal(0);
386         BigDecimal totalItemQuantity = new BigDecimal(0);
387         BigDecimal itemSurchargeCons = new BigDecimal(0);
388         for (int i = 0; item.size() > i; i++) {
389             OlePaymentRequestItem items = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
390             if ((items.getItemType().isQuantityBasedGeneralLedgerIndicator()) && !ObjectUtils.isNull(items.getItemQuantity())) {
391                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
392                     totalItemQuantity = totalItemQuantity.add(items.getItemQuantity().bigDecimalValue());
393                 }
394                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR) || paymentRequestDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) || paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
395                     if (items.getItemDiscount() == null) {
396                         items.setItemDiscount(KualiDecimal.ZERO);
397                     }
398                     if (items.getItemDiscountType() != null && items.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
399                         newUnitPrice = (hundred.subtract(items.getItemDiscount().bigDecimalValue())).divide(hundred).multiply(items.getItemListPrice().bigDecimalValue());
400                     } else {
401                         newUnitPrice = items.getItemListPrice().bigDecimalValue().subtract(items.getItemDiscount().bigDecimalValue());
402                     }
403                     newUnitPriceList.add(newUnitPrice);
404                     extPrice = newUnitPrice.multiply(items.getItemQuantity().bigDecimalValue());
405                     totalExtPrice = totalExtPrice.add(extPrice);
406                 }
407                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE)) {
408                     if (items.getItemSurcharge() == null) {
409                         items.setItemSurcharge(BigDecimal.ZERO);
410                     }
411                     totalSurCharge = totalSurCharge.add(items.getItemQuantity().bigDecimalValue().multiply(items.getItemSurcharge()));
412                 }
413             }
414 
415         }
416         if (paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
417             if (totalItemQuantity.compareTo(BigDecimal.ZERO) != 0) {
418                 itemSurchargeCons = one.divide(totalItemQuantity, 8, RoundingMode.HALF_UP);
419             }
420         }
421         for (int i = 0, j = 0; item.size() > i; i++) {
422             OlePaymentRequestItem items = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
423             if (items.getItemType().isQuantityBasedGeneralLedgerIndicator() && newUnitPriceList.size() > j && !ObjectUtils.isNull(items.getItemQuantity())) {
424                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_DOLLAR)) {
425                     if (totalExtPrice.compareTo(BigDecimal.ZERO) != 0) {
426                         unitPricePercent = newUnitPriceList.get(j).divide(totalExtPrice, 8, RoundingMode.HALF_UP);
427                     }
428                     items.setItemSurcharge(unitPricePercent.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
429                     items.setItemUnitPrice(newUnitPriceList.get(j).add(items.getItemSurcharge()));
430                 }
431                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.PRORATE_BY_QTY)) {
432                     items.setItemSurcharge(itemSurchargeCons.multiply(addChargeItem).setScale(4, RoundingMode.HALF_UP));
433                     items.setItemUnitPrice(newUnitPriceList.get(j).add(items.getItemSurcharge()));
434                 }
435                 if (paymentRequestDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE) && items.getItemSurcharge() != null) {
436                     items.setItemUnitPrice(newUnitPriceList.get(j).add(items.getItemSurcharge()));
437                 }
438                 j++;
439             }
440         }
441         if (paymentRequestDocument.getProrateBy().equals(OLEConstants.MANUAL_PRORATE)) {
442             if (totalSurCharge.compareTo(addChargeItem) != 0) {
443                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, OLEKeyConstants.ERROR_PAYMENT_REQUEST_TOTAL_MISMATCH);
444             }
445         }
446         LOG.debug("Leaving Calculation for ProrateItemSurcharge");
447     }
448 
449     @Override
450     public void calculatePaymentRequest(PaymentRequestDocument paymentRequest, boolean updateDiscount) {
451         LOG.debug("calculatePaymentRequest() started");
452 
453         // general calculation, i.e. for the whole preq document
454         if (ObjectUtils.isNull(paymentRequest.getPaymentRequestPayDate())) {
455             paymentRequest.setPaymentRequestPayDate(calculatePayDate(paymentRequest.getInvoiceDate(), paymentRequest.getVendorPaymentTerms()));
456         }
457 
458         distributeAccounting(paymentRequest);
459 
460         purapService.calculateTax(paymentRequest);
461 
462         // do proration for full order and trade in
463         purapService.prorateForTradeInAndFullOrderDiscount(paymentRequest);
464 
465         // do proration for payment terms discount
466         if (updateDiscount) {
467             calculateDiscount(paymentRequest);
468         }
469 
470         distributeAccounting(paymentRequest);
471     }
472 
473     @Override
474     protected void distributeAccounting(PaymentRequestDocument paymentRequestDocument) {
475         // update the account amounts before doing any distribution
476         purapAccountingService.updateAccountAmounts(paymentRequestDocument);
477 
478         for (PaymentRequestItem item : (List<PaymentRequestItem>) paymentRequestDocument.getItems()) {
479             KualiDecimal totalAmount = KualiDecimal.ZERO;
480             List<PurApAccountingLine> distributedAccounts = null;
481             List<SourceAccountingLine> summaryAccounts = null;
482             Set excludedItemTypeCodes = new HashSet();
483             excludedItemTypeCodes.add(PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE);
484 
485             // skip above the line
486             if (item.getItemType().isLineItemIndicator()) {
487                 continue;
488             }
489 
490             if ((ObjectUtils.isNotNull(item.getExtendedPrice())) && (KualiDecimal.ZERO.compareTo(item.getExtendedPrice()) != 0) && !"DISC".equals(item.getItemTypeCode())) {
491                 if ((StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE, item.getItemType().getItemTypeCode())) && (paymentRequestDocument.getGrandTotal() != null) && ((KualiDecimal.ZERO.compareTo(paymentRequestDocument.getGrandTotal()) != 0))) {
492 
493                     // No discount is applied to other item types other than item line
494                     // See KFSMI-5210 for details
495 
496                     // total amount should be the line item total, not the grand total
497                     totalAmount = paymentRequestDocument.getLineItemTotal();
498 
499                     // prorate item line accounts only
500                     Set includedItemTypeCodes = new HashSet();
501                     includedItemTypeCodes.add(PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE);
502                     summaryAccounts = olePurapAccountingService.generateSummaryIncludeItemTypesAndNoZeroTotals(paymentRequestDocument.getItems(), includedItemTypeCodes);
503                     distributedAccounts = olePurapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, PurapConstants.PRORATION_SCALE, PaymentRequestAccount.class);
504 
505                     // update amounts on distributed accounts
506                     purapAccountingService.updateAccountAmountsWithTotal(distributedAccounts, item.getTotalAmount());
507                 } else {
508                     PurchaseOrderItem poi = item.getPurchaseOrderItem();
509                     if ((poi != null) && (poi.getSourceAccountingLines() != null) && (!(poi.getSourceAccountingLines().isEmpty())) && (poi.getExtendedPrice() != null) && ((KualiDecimal.ZERO.compareTo(poi.getExtendedPrice())) != 0)) {
510                         // use accounts from purchase order item matching this item
511                         // account list of current item is already empty
512                         item.generateAccountListFromPoItemAccounts(poi.getSourceAccountingLines());
513                     } else {
514                         totalAmount = paymentRequestDocument.getPurchaseOrderDocument().getTotalDollarAmountAboveLineItems();
515                         purapAccountingService.updateAccountAmounts(paymentRequestDocument.getPurchaseOrderDocument());
516                         summaryAccounts = olePurapAccountingService.generateSummary(paymentRequestDocument.getItems());
517                         distributedAccounts = olePurapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, PurapConstants.PRORATION_SCALE, PaymentRequestAccount.class);
518                     }
519 
520                 }
521                 if (CollectionUtils.isNotEmpty(distributedAccounts)) {
522                     item.setSourceAccountingLines(distributedAccounts);
523                 }
524             }
525             // update the item
526             purapAccountingService.updateItemAccountAmounts(item);
527         }
528         // update again now that distribute is finished. (Note: we may not need this anymore now that I added updateItem line above
529         purapAccountingService.updateAccountAmounts(paymentRequestDocument);
530     }
531 
532     /**
533      * @see org.kuali.ole.module.purap.document.service.PaymentRequestService#getPaymentRequestByDocumentNumber(java.lang.String)
534      */
535     @Override
536     public PaymentRequestDocument getPaymentRequestByDocumentNumber(String documentNumber) {
537         LOG.debug("getPaymentRequestByDocumentNumber() started");
538 
539         if (ObjectUtils.isNotNull(documentNumber)) {
540             try {
541                 OlePaymentRequestDocument doc = (OlePaymentRequestDocument) documentService.getByDocumentHeaderId(documentNumber);
542                 return doc;
543             } catch (WorkflowException e) {
544                 String errorMessage = "Error getting payment request document from document service";
545                 LOG.error("Exception in getPaymentRequestByDocumentNumber() " + errorMessage, e);
546                 throw new RuntimeException(errorMessage, e);
547             }
548         }
549         return null;
550     }
551 
552     /**
553      * This method is validates the prorate surchanges if prorate by manual
554      *
555      * @see org.kuali.ole.select.document.service.OlePaymentRequestService#validateProratedSurcharge(org.kuali.ole.select.document.OlePaymentRequestDocument)
556      */
557     @Override
558     public boolean validateProratedSurcharge(OlePaymentRequestDocument paymentRequestDocument) {
559 
560         List<OlePaymentRequestItem> items = paymentRequestDocument.getItems();
561         boolean manuvalProrateValidFlag = false;
562         BigDecimal proratedSurchargeAmount = new BigDecimal(0);
563         for (int i = 0; items.size() > i; i++) {
564             OlePaymentRequestItem item = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
565             if ("".equals(item.getItemTitleId()) || item.getItemTitleId() == null) {
566                 if (item.getItemUnitPrice() != null && !"".equals(item.getItemUnitPrice())) {
567                     manuvalProrateValidFlag = true;
568                 }
569             }
570         }
571         if (manuvalProrateValidFlag) {
572             for (int i = 0; items.size() > i; i++) {
573                 OlePaymentRequestItem item = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
574                 if (!"".equals(item.getItemTitleId()) && item.getItemTitleId() != null) {
575                     if (item.getItemSurcharge() != null && item.getItemSurcharge().compareTo(new BigDecimal(0)) != 0) {
576                         proratedSurchargeAmount = proratedSurchargeAmount.add(item.getItemSurcharge());
577                     }
578                 }
579             }
580             if (proratedSurchargeAmount.compareTo(new BigDecimal(0)) == 0) {
581                 manuvalProrateValidFlag = false;
582                 paymentRequestDocument.setProrateBy(null);
583                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, OLEKeyConstants.ERROR_PAYMENT_REQUEST_TOTAL_MISMATCH);
584             }
585         }
586         return manuvalProrateValidFlag;
587     }
588 
589     /**
590      * This method is for caluclate the total amount without select proprate by Quantity,doller and manual
591      *
592      * @see org.kuali.ole.select.document.service.OlePaymentRequestService#calculateWithoutProrates(org.kuali.ole.select.document.OlePaymentRequestDocument)
593      */
594     @Override
595     public void calculateWithoutProrates(OlePaymentRequestDocument paymentRequestDocument) {
596         LOG.debug("Inside Calculation for with out  prorate");
597         BigDecimal addChargeItem = BigDecimal.ZERO;
598         List<OlePaymentRequestItem> items = paymentRequestDocument.getItems();
599 
600         for (OlePaymentRequestItem item : items) {
601             if (item.getItemTitleId() != null && !"".equals(item.getItemTitleId())) {
602                 if (!item.getItemListPrice().equals(item.getExtendedPrice())) {
603                     item.setItemUnitPrice(item.getItemListPrice().bigDecimalValue());
604                     item.setExtendedPrice(item.getItemListPrice());
605                     item.setItemSurcharge(BigDecimal.ZERO);
606                 }
607             }
608         }
609 
610         for (OlePaymentRequestItem item : items) {
611             if (!item.getItemType().isQuantityBasedGeneralLedgerIndicator()
612                     && !item.getItemTypeCode().equalsIgnoreCase(
613                     PurapConstants.ItemTypeCodes.ITEM_TYPE_PMT_TERMS_DISCOUNT_CODE)
614                     && item.getItemUnitPrice() != null) {
615                 addChargeItem = addChargeItem.add(item.getItemUnitPrice());
616             }
617         }
618         List<BigDecimal> newUnitPriceList = new ArrayList<BigDecimal>();
619         BigDecimal totalExtPrice = new BigDecimal(0);
620         BigDecimal newUnitPrice = new BigDecimal(0);
621         BigDecimal extPrice = new BigDecimal(0);
622         BigDecimal unitPricePercent = new BigDecimal(0);
623         BigDecimal hundred = new BigDecimal(100);
624         BigDecimal one = new BigDecimal(1);
625         BigDecimal totalSurCharge = new BigDecimal(0);
626         BigDecimal totalItemQuantity = new BigDecimal(0);
627         BigDecimal itemSurchargeCons = new BigDecimal(0);
628         for (int i = 0; items.size() > i; i++) {
629             OlePaymentRequestItem item = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
630             if ((item.getItemType().isQuantityBasedGeneralLedgerIndicator())
631                     && !ObjectUtils.isNull(item.getItemQuantity())) {
632                 if (item.getItemSurcharge() == null) {
633                     item.setItemSurcharge(BigDecimal.ZERO);
634                 }
635                 if (paymentRequestDocument.getProrateBy() == null) {
636                     if (item.getItemDiscount() == null) {
637                         item.setItemDiscount(KualiDecimal.ZERO);
638                     }
639                     if (item.getItemDiscountType() != null
640                             && item.getItemDiscountType().equalsIgnoreCase(OleSelectConstant.DISCOUNT_TYPE_PERCENTAGE)) {
641                         newUnitPrice = SpringContext.getBean(OlePurapService.class).calculateDiscount(item).setScale(2, BigDecimal.ROUND_HALF_UP);
642                     } else {
643                         newUnitPrice = SpringContext.getBean(OlePurapService.class).calculateDiscount(item).setScale(2, BigDecimal.ROUND_HALF_UP);
644                     }
645                     newUnitPriceList.add(newUnitPrice);
646                     extPrice = newUnitPrice.multiply(item.getItemQuantity().bigDecimalValue());
647                     totalExtPrice = totalExtPrice.add(extPrice);
648                 }
649                 totalSurCharge = totalSurCharge.add(item.getItemQuantity().bigDecimalValue()
650                         .multiply(item.getItemSurcharge()));
651             }
652         }
653         for (int i = 0, j = 0; items.size() > i; i++) {
654             OlePaymentRequestItem item = (OlePaymentRequestItem) paymentRequestDocument.getItem(i);
655             if (item.getItemType().isQuantityBasedGeneralLedgerIndicator() && newUnitPriceList.size() > j
656                     && !ObjectUtils.isNull(item.getItemQuantity())) {
657                 if (item.getItemSurcharge() != null) {
658                     item.setItemUnitPrice(newUnitPriceList.get(j).add(item.getItemSurcharge()));
659                 }
660                 j++;
661             }
662         }
663 
664         LOG.debug("Leaving Calculation for with out  prorate");
665     }
666 
667     public String getPaymentMethod(Integer paymentId){
668         Map payMap = new HashMap();
669         payMap.put("paymentMethodId", paymentId);
670         OlePaymentMethod olePaymentMethod = KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(OlePaymentMethod.class,payMap);
671         if(olePaymentMethod != null){
672             return olePaymentMethod.getPaymentMethod();
673         }
674         return "";
675     }
676 
677     public OleSelectDocumentService getOleSelectDocumentService() {
678         if(oleSelectDocumentService == null){
679             oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
680         }
681         return oleSelectDocumentService;
682     }
683 
684     public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
685         this.oleSelectDocumentService = oleSelectDocumentService;
686     }
687 
688 }