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  
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.ole.module.purap.PurapConstants;
21  import org.kuali.ole.module.purap.businessobject.*;
22  import org.kuali.ole.module.purap.document.CorrectionReceivingDocument;
23  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
24  import org.kuali.ole.module.purap.document.ReceivingDocument;
25  import org.kuali.ole.module.purap.document.service.ReceivingService;
26  import org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl;
27  import org.kuali.ole.select.businessobject.*;
28  import org.kuali.ole.sys.OLEConstants;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.rice.core.api.util.type.KualiDecimal;
31  import org.kuali.rice.kew.api.exception.WorkflowException;
32  import org.kuali.rice.krad.bo.AdHocRoutePerson;
33  import org.kuali.rice.krad.service.BusinessObjectService;
34  import org.kuali.rice.krad.util.ObjectUtils;
35  import org.springframework.transaction.annotation.Transactional;
36  
37  import java.util.ArrayList;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  /**
43   * This class has implementation for ReceivingService with respect to OLE.
44   */
45  
46  @Transactional
47  public class OleReceivingServiceImpl extends ReceivingServiceImpl implements ReceivingService {
48  
49      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OleReceivingServiceImpl.class);
50  
51      /**
52       * This method is overridden to set total parts received and total parts damaged for
53       * a PurchaseOrderItem
54       *
55       * @param receivingDocument ReceivingDocument from which total parts received and damaged are to be set in PO
56       * @param poDoc             Purchase order document to set total parts received and damaged
57       * @return
58       * @see org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl#updateReceivingTotalsOnPurchaseOrder(org.kuali.ole.module.purap.document.ReceivingDocument, org.kuali.ole.module.purap.document.PurchaseOrderDocument)
59       */
60      @Override
61      protected void updateReceivingTotalsOnPurchaseOrder(ReceivingDocument receivingDocument, PurchaseOrderDocument poDoc) {
62          LOG.debug("Inside updateReceivingTotalsOnPurchaseOrder of OleReceivingServiceImpl");
63          super.updateReceivingTotalsOnPurchaseOrder(receivingDocument, poDoc);
64          for (OleReceivingItem receivingItem : (List<OleReceivingItem>) receivingDocument.getItems()) {
65              ItemType itemType = receivingItem.getItemType();
66              if (!StringUtils.equalsIgnoreCase(itemType.getItemTypeCode(), PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE)) {
67                  //TODO: Chris - this method of getting the line out of po should be turned into a method that can get an item based on a combo or itemType and line
68                  OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) poDoc.getItemByLineNumber(receivingItem.getItemLineNumber());
69  
70                  if (ObjectUtils.isNotNull(poItem)) {
71                      KualiDecimal poItemPartsReceivedTotal = poItem.getItemReceivedTotalParts();
72  
73                      KualiDecimal receivingItemPartsReceivedOriginal = receivingItem.getItemOriginalReceivedTotalParts();
74  
75                      if (ObjectUtils.isNull(receivingItemPartsReceivedOriginal)) {
76                          receivingItemPartsReceivedOriginal = KualiDecimal.ZERO;
77                      }
78                      KualiDecimal receivingItemPartsReceived = receivingItem.getItemReceivedTotalParts();
79                      KualiDecimal receivingItemPartsTotalReceivedAdjusted = receivingItemPartsReceived.subtract(receivingItemPartsReceivedOriginal);
80  
81                      if (ObjectUtils.isNull(poItemPartsReceivedTotal)) {
82                          poItemPartsReceivedTotal = KualiDecimal.ZERO;
83                      }
84                      KualiDecimal poItemPartsReceivedTotalAdjusted = poItemPartsReceivedTotal.add(receivingItemPartsTotalReceivedAdjusted);
85  
86                      KualiDecimal receivingItemPartsReturnedOriginal = receivingItem.getItemOriginalReturnedTotalParts();
87                      if (ObjectUtils.isNull(receivingItemPartsReturnedOriginal)) {
88                          receivingItemPartsReturnedOriginal = KualiDecimal.ZERO;
89                      }
90  
91                      KualiDecimal receivingItemPartsReturned = receivingItem.getItemReturnedTotalParts();
92                      if (ObjectUtils.isNull(receivingItemPartsReturned)) {
93                          receivingItemPartsReturned = KualiDecimal.ZERO;
94                      }
95  
96                      KualiDecimal receivingItemPartsTotalReturnedAdjusted = receivingItemPartsReturned.subtract(receivingItemPartsReturnedOriginal);
97  
98                      poItemPartsReceivedTotalAdjusted = poItemPartsReceivedTotalAdjusted.subtract(receivingItemPartsTotalReturnedAdjusted);
99  
100                     poItem.setItemReceivedTotalParts(poItemPartsReceivedTotalAdjusted);
101 
102                     KualiDecimal poPartsTotalDamaged = poItem.getItemDamagedTotalParts();
103                     if (ObjectUtils.isNull(poPartsTotalDamaged)) {
104                         poPartsTotalDamaged = KualiDecimal.ZERO;
105                     }
106 
107                     KualiDecimal receivingItemPartsTotalDamagedOriginal = receivingItem.getItemOriginalDamagedTotalParts();
108                     if (ObjectUtils.isNull(receivingItemPartsTotalDamagedOriginal)) {
109                         receivingItemPartsTotalDamagedOriginal = KualiDecimal.ZERO;
110                     }
111 
112                     KualiDecimal receivingItemPartsTotalDamaged = receivingItem.getItemDamagedTotalParts();
113                     if (ObjectUtils.isNull(receivingItemPartsTotalDamaged)) {
114                         receivingItemPartsTotalDamaged = KualiDecimal.ZERO;
115                     }
116 
117                     KualiDecimal receivingItemPartsTotalDamagedAdjusted = receivingItemPartsTotalDamaged.subtract(receivingItemPartsTotalDamagedOriginal);
118 
119                     poItem.setItemDamagedTotalParts(poPartsTotalDamaged.add(receivingItemPartsTotalDamagedAdjusted));
120                 }
121             }
122         }
123         LOG.debug("Leaving updateReceivingTotalsOnPurchaseOrder of OleReceivingServiceImpl");
124     }
125 
126     /**
127      * This method is overridden to set total parts receiving and damaged in OlePurchaseOrderItem from OleLineItemReceivingItem
128      *
129      * @param rlItem Receiving line item from which total damaged and received parts are to be set in PO
130      * @return
131      * @see org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl#createPoItemFromReceivingLine(org.kuali.ole.module.purap.businessobject.LineItemReceivingItem)
132      */
133     @Override
134     protected PurchaseOrderItem createPoItemFromReceivingLine(LineItemReceivingItem rlItem) {
135         LOG.debug("Inside createPoItemFromReceivingLine of OleReceivingServiceImpl");
136         OlePurchaseOrderItem poi = (OlePurchaseOrderItem) super.createPoItemFromReceivingLine(rlItem);
137         OleLineItemReceivingItem oleRlItem = (OleLineItemReceivingItem) rlItem;
138         poi.setItemDamagedTotalParts(oleRlItem.getItemDamagedTotalParts());
139         poi.setItemReceivedTotalParts(oleRlItem.getItemReceivedTotalParts());
140         poi.setBibInfoBean(oleRlItem.getBibInfoBean());
141         poi.setItemTitleId(oleRlItem.getItemTitleId());
142         LOG.debug("Leaving createPoItemFromReceivingLine of OleReceivingServiceImpl");
143         return poi;
144     }
145 
146 
147     /**
148      * This method is overridden to disable notes on a document when quantity returned or damaged is entered.
149      *
150      * @param recDoc Receiving Document
151      * @return
152      * @see org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl#createNoteForReturnedAndDamagedItems(org.kuali.ole.module.purap.document.ReceivingDocument)
153      */
154     @Override
155     public void createNoteForReturnedAndDamagedItems(ReceivingDocument recDoc) {
156 
157     }
158 
159     /**
160      * This method is overridden to include parts values in creating a list of fiscal officers for new unordered items added to a purchase order.
161      *
162      * @param recDoc ReceivingDocument
163      * @return Fiscal officer list to send notification
164      * @see org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl#createFyiFiscalOfficerList(org.kuali.ole.module.purap.document.ReceivingDocument)
165      */
166     @Override
167     protected List<AdHocRoutePerson> createFyiFiscalOfficerList(ReceivingDocument recDoc) {
168         LOG.debug("Inside createFyiFiscalOfficerList of OleReceivingServiceImpl");
169         PurchaseOrderDocument po = recDoc.getPurchaseOrderDocument();
170         List<AdHocRoutePerson> adHocRoutePersons = new ArrayList<AdHocRoutePerson>();
171         Map fiscalOfficers = new HashMap();
172         AdHocRoutePerson adHocRoutePerson = null;
173 
174         for (OleReceivingItem recItem : (List<OleReceivingItem>) recDoc.getItems()) {
175             //if this item has an item line number then it is coming from the po
176             if (ObjectUtils.isNotNull(recItem.getItemLineNumber())) {
177                 OlePurchaseOrderItem poItem = (OlePurchaseOrderItem) po.getItemByLineNumber(recItem.getItemLineNumber());
178 
179                 if ((poItem.getItemQuantity().isLessThan(poItem.getItemReceivedTotalQuantity()) ||
180                         recItem.getItemDamagedTotalQuantity().isGreaterThan(KualiDecimal.ZERO))
181                         && (((poItem.getItemNoOfParts().kualiDecimalValue()).isLessThan(poItem.getItemReceivedTotalParts()))
182                         || recItem.getItemDamagedTotalParts().isGreaterThan(KualiDecimal.ZERO))) {
183 
184                     // loop through accounts and pull off fiscal officer
185                     for (PurApAccountingLine account : poItem.getSourceAccountingLines()) {
186 
187                         //check for dupes of fiscal officer
188                         if (fiscalOfficers.containsKey(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName()) == false) {
189 
190                             //add fiscal officer to list
191                             fiscalOfficers.put(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName(), account.getAccount().getAccountFiscalOfficerUser().getPrincipalName());
192 
193                             //create AdHocRoutePerson object and add to list
194                             adHocRoutePerson = new AdHocRoutePerson();
195                             adHocRoutePerson.setId(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName());
196                             adHocRoutePerson.setActionRequested(OLEConstants.WORKFLOW_FYI_REQUEST);
197                             adHocRoutePersons.add(adHocRoutePerson);
198                         }
199                     }
200 
201                 }
202 
203             }
204         }
205         LOG.debug("Leaving createFyiFiscalOfficerList of OleReceivingServiceImpl");
206         return adHocRoutePersons;
207     }
208 
209     /**
210      * This method is overridden to change annotation to include Parts
211      *
212      * @see org.kuali.ole.module.purap.document.service.impl.ReceivingServiceImpl#sendFyiForItems(org.kuali.ole.module.purap.document.ReceivingDocument)
213      */
214     @Override
215     protected void sendFyiForItems(ReceivingDocument recDoc) {
216         LOG.debug("Inside sendFyiForItems of OleReceivingServiceImpl");
217         List<AdHocRoutePerson> fyiList = createFyiFiscalOfficerList(recDoc);
218         String annotation = "Notification of Item exceeded Quantity/Parts or Damaged" + "(document id " + recDoc.getDocumentNumber() + ")";
219         String responsibilityNote = "Please Review";
220 
221         for (AdHocRoutePerson adHocPerson : fyiList) {
222             try {
223                 recDoc.appSpecificRouteDocumentToUser(
224                         recDoc.getDocumentHeader().getWorkflowDocument(),
225                         adHocPerson.getId(),
226                         annotation,
227                         responsibilityNote);
228             } catch (WorkflowException e) {
229                 throw new RuntimeException("Error routing fyi for document with id " + recDoc.getDocumentNumber(), e);
230             }
231 
232         }
233         LOG.debug("Leaving sendFyiForItems of OleReceivingServiceImpl");
234     }
235 
236     /**
237      * This method deletes unneeded items and updates the totals on the po and does any additional processing based on items i.e.
238      * FYI etc
239      *
240      * @param receivingDocument receiving document
241      */
242     @Override
243     public void completeCorrectionReceivingDocument(ReceivingDocument correctionDocument) {
244         ReceivingDocument receivingDoc = ((CorrectionReceivingDocument) correctionDocument)
245                 .getLineItemReceivingDocument();
246 
247         if (correctionDocument.getItems().size() >= 1) {
248             for (OleCorrectionReceivingItem correctionItem : (List<OleCorrectionReceivingItem>) correctionDocument.getItems()) {
249                 if (!StringUtils.equalsIgnoreCase(correctionItem.getItemType().getItemTypeCode(),
250                         PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE)) {
251                     int itemNumber = correctionItem.getItemLineNumber().intValue();
252                     OleLineItemReceivingItem recItem = (OleLineItemReceivingItem) receivingDoc.getItem(correctionItem
253                             .getItemLineNumber().intValue() - itemNumber);
254                     List<PurchaseOrderItem> purchaseOrderItems = receivingDoc.getPurchaseOrderDocument().getItems();
255                     PurchaseOrderItem poItem = purchaseOrderItems.get(correctionItem.getItemLineNumber().intValue()
256                             - itemNumber);
257 
258                     if (ObjectUtils.isNotNull(recItem)) {
259                         recItem.setItemReceivedTotalQuantity(correctionItem.getItemReceivedTotalQuantity());
260                         recItem.setItemReceivedTotalParts(correctionItem.getItemReceivedTotalParts());
261                         recItem.setItemReturnedTotalQuantity(correctionItem.getItemReturnedTotalQuantity());
262                         recItem.setItemReturnedTotalParts(correctionItem.getItemReturnedTotalParts());
263                         recItem.setItemDamagedTotalQuantity(correctionItem.getItemDamagedTotalQuantity());
264                         recItem.setItemDamagedTotalParts(correctionItem.getItemDamagedTotalParts());
265                         updateReceivingItemReceiptStatus(recItem, correctionItem);
266                     }
267                 }
268             }
269 
270 
271         } else {
272             for (CorrectionReceivingItem correctionItem : (List<CorrectionReceivingItem>) correctionDocument.getItems()) {
273                 if (!StringUtils.equalsIgnoreCase(correctionItem.getItemType().getItemTypeCode(),
274                         PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE)) {
275                     LineItemReceivingItem recItem = (LineItemReceivingItem) receivingDoc.getItem(correctionItem
276                             .getItemLineNumber().intValue() - 1);
277                     List<PurchaseOrderItem> purchaseOrderItems = receivingDoc.getPurchaseOrderDocument().getItems();
278                     PurchaseOrderItem poItem = purchaseOrderItems
279                             .get(correctionItem.getItemLineNumber().intValue() - 1);
280 
281                     if (ObjectUtils.isNotNull(recItem)) {
282                         recItem.setItemReceivedTotalQuantity(correctionItem.getItemReceivedTotalQuantity());
283                         recItem.setItemReturnedTotalQuantity(correctionItem.getItemReturnedTotalQuantity());
284                         recItem.setItemDamagedTotalQuantity(correctionItem.getItemDamagedTotalQuantity());
285                     }
286                 }
287             }
288         }
289     }
290 
291     public void updateReceivingItemReceiptStatus(OleLineItemReceivingItem recItem,
292                                                  OleCorrectionReceivingItem correctionItem) {
293 
294         int finalCopiesReceived = (correctionItem.getItemReceivedTotalQuantity().subtract(
295                 correctionItem.getItemReturnedTotalQuantity()).intValue());
296         int finalPartsReceived = (correctionItem.getItemReceivedTotalParts().subtract(
297                 correctionItem.getItemReturnedTotalParts()).intValue());
298         if (correctionItem.getItemOriginalReceivedTotalQuantity().intValue() == finalCopiesReceived
299                 && correctionItem.getItemOriginalReceivedTotalParts().intValue() == finalPartsReceived) {
300             recItem.setReceiptStatusId(getReceiptStatusDetails(OLEConstants.RCV_RECEIPT_STATUS_RCVD));
301         } else {
302             if (finalCopiesReceived == 0 && finalCopiesReceived == 0) {
303                 recItem.setReceiptStatusId(getReceiptStatusDetails(OLEConstants.RCV_RECEIPT_STATUS_NONE));
304             } else {
305                 recItem.setReceiptStatusId(getReceiptStatusDetails(OLEConstants.RCV_RECEIPT_STATUS_EXPTD));
306             }
307         }
308     }
309 
310     public int getReceiptStatusDetails(String receiptStatusCd) {
311         int receiptStatusId = 0;
312         Map<String, String> receiptStatusCdMap = new HashMap<String, String>();
313         receiptStatusCdMap.put(OLEConstants.RCPT_STATUS_CD, receiptStatusCd);
314         List<OleReceiptStatus> oleReceiptStatusList = (List) SpringContext.getBean(BusinessObjectService.class)
315                 .findMatching(OleReceiptStatus.class, receiptStatusCdMap);
316         for (OleReceiptStatus oleReceiptStatus : oleReceiptStatusList) {
317             receiptStatusId = oleReceiptStatus.getReceiptStatusId().intValue();
318         }
319         return receiptStatusId;
320     }
321 
322 }
323