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