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.DataCarrierService;
21  import org.kuali.ole.deliver.processor.LoanProcessor;
22  import org.kuali.ole.module.purap.PurapConstants;
23  import org.kuali.ole.module.purap.PurapConstants.PurchaseOrderStatuses;
24  import org.kuali.ole.module.purap.PurapKeyConstants;
25  import org.kuali.ole.module.purap.PurapParameterConstants;
26  import org.kuali.ole.module.purap.businessobject.PurApItem;
27  import org.kuali.ole.module.purap.businessobject.PurchaseOrderType;
28  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
29  import org.kuali.ole.module.purap.document.RequisitionDocument;
30  import org.kuali.ole.module.purap.document.service.LogicContainer;
31  import org.kuali.ole.module.purap.document.service.PaymentRequestService;
32  import org.kuali.ole.module.purap.document.service.PrintService;
33  import org.kuali.ole.module.purap.document.service.PurApWorkflowIntegrationService;
34  import org.kuali.ole.module.purap.document.service.impl.PurchaseOrderServiceImpl;
35  import org.kuali.ole.pojo.OleTxRecord;
36  import org.kuali.ole.select.OleSelectConstant;
37  import org.kuali.ole.select.document.OlePurchaseOrderDocument;
38  import org.kuali.ole.select.document.service.OlePurchaseOrderService;
39  import org.kuali.ole.select.document.service.OleSelectDocumentService;
40  import org.kuali.ole.sys.OLEConstants;
41  import org.kuali.ole.sys.context.SpringContext;
42  import org.kuali.ole.sys.document.validation.event.DocumentSystemSaveEvent;
43  import org.kuali.rice.core.api.config.property.ConfigurationService;
44  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
45  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
46  import org.kuali.rice.kew.api.KewApiConstants;
47  import org.kuali.rice.kew.api.KewApiServiceLocator;
48  import org.kuali.rice.kew.api.action.ActionRequestType;
49  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
50  import org.kuali.rice.kew.api.exception.WorkflowException;
51  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
52  import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
53  import org.kuali.rice.kim.api.identity.Person;
54  import org.kuali.rice.krad.exception.ValidationException;
55  import org.kuali.rice.krad.util.ErrorMessage;
56  import org.kuali.rice.krad.util.GlobalVariables;
57  import org.kuali.rice.krad.util.ObjectUtils;
58  import org.springframework.transaction.annotation.Transactional;
59  import org.springframework.util.AutoPopulatingList;
60  
61  import java.io.ByteArrayOutputStream;
62  import java.lang.reflect.InvocationTargetException;
63  import java.sql.Timestamp;
64  import java.text.MessageFormat;
65  import java.util.*;
66  
67  @Transactional
68  public class OlePurchaseOrderServiceImpl extends PurchaseOrderServiceImpl implements OlePurchaseOrderService {
69  
70      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OlePurchaseOrderServiceImpl.class);
71      // private DocumentService documentService;
72  
73      private ConfigurationService kualiConfigurationService;
74      private PrintService printService;
75      private PurApWorkflowIntegrationService purapWorkflowIntegrationService;
76      private OleSelectDocumentService oleSelectDocumentService;
77  
78      @Override
79      public void setPrintService(PrintService printService) {
80          this.printService = printService;
81      }
82  
83      @Override
84      public void setConfigurationService(ConfigurationService kualiConfigurationService) {
85          this.kualiConfigurationService = kualiConfigurationService;
86      }
87  
88      @Override
89      public void setPurapWorkflowIntegrationService(PurApWorkflowIntegrationService purapWorkflowIntegrationService) {
90          this.purapWorkflowIntegrationService = purapWorkflowIntegrationService;
91      }
92  
93      /**
94       * @see org.kuali.ole.module.purap.document.service.PurchaseOrderService#createAutomaticPurchaseOrderDocument(org.kuali.ole.module.purap.document.RequisitionDocument)
95       */
96      @Override
97      public void createAutomaticPurchaseOrderDocument(RequisitionDocument reqDocument) {
98          String newSessionUserId = getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER);
99          try {
100             LogicContainer logicToRun = new LogicContainer() {
101                 @Override
102                 public Object runLogic(Object[] objects) throws Exception {
103                     RequisitionDocument doc = (RequisitionDocument) objects[0];
104                     // update REQ data
105                     doc.setPurchaseOrderAutomaticIndicator(Boolean.TRUE);
106                     // create PO and populate with default data
107                     PurchaseOrderDocument po = generatePurchaseOrderFromRequisition(doc);
108                     po.setDefaultValuesForAPO();
109                     po.setContractManagerCode(PurapConstants.APO_CONTRACT_MANAGER);
110                     populatePOValuesFromProfileAttributes(doc,po);
111                     String purchaseOrderType = "";
112                     if (doc.getPurchaseOrderTypeId() != null) {
113                         Map purchaseOrderTypeIdMap = new HashMap();
114                         purchaseOrderTypeIdMap.put("purchaseOrderTypeId", doc.getPurchaseOrderTypeId());
115                         org.kuali.rice.krad.service.BusinessObjectService
116                                 businessObjectService = SpringContext.getBean(org.kuali.rice.krad.service.BusinessObjectService.class);
117                         LOG.debug("before calling findMatching");
118                         List<PurchaseOrderType> purchaseOrderTypeDocumentList = (List) businessObjectService.findMatching(PurchaseOrderType.class, purchaseOrderTypeIdMap);
119                         LOG.debug("after calling findMatching");
120                         if (purchaseOrderTypeDocumentList != null && purchaseOrderTypeDocumentList.size() > 0) {
121                             PurchaseOrderType purchaseOrderTypeDoc = purchaseOrderTypeDocumentList.get(0);
122                             purchaseOrderType = purchaseOrderTypeDoc.getPurchaseOrderType();
123                         }
124                         if (LOG.isDebugEnabled()) {
125                             LOG.debug("purchaseOrderType >>>>>>>>>>>" + purchaseOrderType);
126                             LOG.debug("purchaseOrder DocumentNumber >>>>>>>>>>>" + po.getDocumentNumber());
127                         }
128                         if (purchaseOrderType != null ) {
129                                 /*&& !(po.isLicensingRequirementIndicator())) {*/
130                             LOG.debug("before calling document service impl");
131                             documentService.routeDocument(po, null, null);
132                             LOG.debug("after calling document service impl ");
133                         } else {
134                             documentService.saveDocument(po, DocumentSystemSaveEvent.class);
135                         }
136                     }
137                     final DocumentAttributeIndexingQueue documentAttributeIndexingQueue = KewApiServiceLocator.getDocumentAttributeIndexingQueue();
138                     documentAttributeIndexingQueue.indexDocument(po.getDocumentNumber());
139                     return null;
140                 }
141             };
142             purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, new Object[]{reqDocument});
143         } catch (WorkflowException e) {
144             String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
145             LOG.error(errorMsg, e);
146             throw new RuntimeException(errorMsg, e);
147         } catch (Exception e) {
148             throw new RuntimeException(e);
149         }
150     }
151 
152     private void populatePOValuesFromProfileAttributes(RequisitionDocument doc,PurchaseOrderDocument po){
153         DataCarrierService dataCarrierService = GlobalResourceLoader.getService(org.kuali.ole.OLEConstants.DATA_CARRIER_SERVICE);
154         OleTxRecord oleTxRecord = (OleTxRecord)dataCarrierService.getData(org.kuali.ole.OLEConstants.OLE_TX_RECORD);
155         if(oleTxRecord != null && doc.getRequisitionSource() != null && doc.getRequisitionSource().getRequisitionSourceCode().equalsIgnoreCase(OleSelectConstant.REQUISITON_SRC_TYPE_AUTOINGEST)){
156             po.setPurchaseOrderConfirmedIndicator(oleTxRecord.isPurchaseOrderConfirmationIndicator());
157             if(oleTxRecord.getVendorChoice() != null){
158                 po.setPurchaseOrderVendorChoiceCode(oleTxRecord.getVendorChoice());
159             }
160             if(oleTxRecord.getAssignToUser() != null){
161                 po.setAssignedUserPrincipalName(oleTxRecord.getAssignToUser());
162             }
163         }
164     }
165 
166     /**
167      * @see org.kuali.ole.module.purap.document.service.PurchaseOrderService#performPurchaseOrderFirstTransmitViaPrinting(java.lang.String,
168      *      java.io.ByteArrayOutputStream)
169      */
170     @Override
171     public void performPurchaseOrderFirstTransmitViaPrinting(String documentNumber, ByteArrayOutputStream baosPDF) {
172         PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(documentNumber);
173         String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
174         Collection<String> generatePDFErrors = printService.generatePurchaseOrderPdf(po, baosPDF, environment, null);
175         if (!generatePDFErrors.isEmpty()) {
176             addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
177             throw new ValidationException("printing purchase order for first transmission failed");
178         }
179         Timestamp currentDate = dateTimeService.getCurrentTimestamp();
180         po.setPurchaseOrderFirstTransmissionTimestamp(currentDate);
181         po.setPurchaseOrderLastTransmitTimestamp(currentDate);
182         po.setOverrideWorkflowButtons(Boolean.FALSE);
183         boolean performedAction = purapWorkflowIntegrationService.takeAllActionsForGivenCriteria(po, "Action taken automatically as part of document initial print transmission", PurapConstants.PurchaseOrderStatuses.NODE_DOCUMENT_TRANSMISSION, GlobalVariables.getUserSession().getPerson(), null);
184         if (!performedAction) {
185             Person systemUserPerson = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
186             purapWorkflowIntegrationService.takeAllActionsForGivenCriteria(po, "Action taken automatically as part of document initial print transmission by user " + GlobalVariables.getUserSession().getPerson().getName(), PurapConstants.PurchaseOrderStatuses.NODE_DOCUMENT_TRANSMISSION, systemUserPerson, getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
187         }
188         po.setOverrideWorkflowButtons(Boolean.TRUE);
189         if (!po.getApplicationDocumentStatus().equals(PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN)) {
190             attemptSetupOfInitialOpenOfDocument(po);
191         }
192         purapService.saveDocumentNoValidation(po);
193     }
194 
195     @Override
196     public void purchaseOrderFirstTransmitViaPrinting(String documentNumber, ByteArrayOutputStream baosPDF) {
197         PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(documentNumber);
198         String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
199         Collection<String> generatePDFErrors = printService.generatePurchaseOrderPdf(po, baosPDF, environment, null);
200         LOG.error("PDF Errors" + generatePDFErrors);
201         if (!generatePDFErrors.isEmpty()) {
202             addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
203             throw new ValidationException("printing purchase order for first transmission failed");
204         }
205     }
206 
207 
208     /**
209      * If the status of the purchase order is not OPEN and the initial open date is null, sets the initial open date to current date
210      * and update the status to OPEN, then save the purchase order.
211      *
212      * @param po The purchase order document whose initial open date and status we want to update.
213      */
214     @Override
215     protected void attemptSetupOfInitialOpenOfDocument(PurchaseOrderDocument po) {
216         if (LOG.isDebugEnabled()) {
217             LOG.debug("attemptSetupOfInitialOpenOfDocument() started using document with doc id " + po.getDocumentNumber());
218         }
219 
220         if (!PurchaseOrderStatuses.APPDOC_OPEN.equals(po.getApplicationDocumentStatus())) {
221             if (OLEConstants.FinancialDocumentTypeCodes.PURCHASE_ORDER_AMENDMENT.equalsIgnoreCase(po.getDocumentHeader().getWorkflowDocument().getDocumentTypeName())) {
222                 po.setPurchaseOrderInitialOpenTimestamp(null);
223             }
224             if (ObjectUtils.isNull(po.getPurchaseOrderInitialOpenTimestamp())) {
225                 LOG.debug("attemptSetupOfInitialOpenOfDocument() setting initial open date on document");
226                 po.setPurchaseOrderInitialOpenTimestamp(dateTimeService.getCurrentTimestamp());
227             } else {
228                 throw new RuntimeException("Document does not have status code '" + PurchaseOrderStatuses.APPDOC_OPEN + "' on it but value of initial open date is " + po.getPurchaseOrderInitialOpenTimestamp());
229             }
230             if (LOG.isDebugEnabled()) {
231                 LOG.debug("attemptSetupOfInitialOpenOfDocument() Setting po document id " + po.getDocumentNumber() + " status from '" + po.getApplicationDocumentStatus() + "' to '" + PurchaseOrderStatuses.APPDOC_OPEN + "'");
232             }
233             po.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_OPEN);
234             // no need to save here because calling class should handle the save if needed
235         } else {
236             LOG.error("attemptSetupOfInitialOpenOfDocument() Found document already in '" + PurchaseOrderStatuses.APPDOC_OPEN + "' status for PO#" + po.getPurapDocumentIdentifier() + "; will not change or update");
237         }
238     }
239 
240     //setting print button for PO amendment document
241     @Override
242     public void setStatusCompletePurchaseOrderAmendment(PurchaseOrderDocument poa) {
243 
244         LOG.debug("setStatusCompletePurchaseOrderAmendment() started");
245         setupDocumentForPendingFirstTransmission(poa);
246         if (!PurchaseOrderStatuses.STATUSES_BY_TRANSMISSION_TYPE.values().contains(poa.getApplicationDocumentStatus())) {
247             attemptSetupOfInitialOpenOfDocument(poa);
248         } else if (PurchaseOrderStatuses.APPDOC_PENDING_PRINT.equals(poa.getApplicationDocumentStatus())) {
249             // default to using user that routed PO
250             String userToRouteFyi = poa.getDocumentHeader().getWorkflowDocument().getRoutedByPrincipalId();
251             // Below code commented to fix issue in POA Screen when changing from NO PRINT to PRINT by Suresh Subramanian
252         /*if (poa.getPurchaseOrderAutomaticIndicator()) {
253             // if APO, use the user that initiated the requisition
254             RequisitionDocument req = SpringContext.getBean(RequisitionService.class).getRequisitionById(poa.getRequisitionIdentifier());
255            userToRouteFyi = req.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
256         }
257 */
258             // send FYI to user for printing
259             poa.getDocumentHeader().getWorkflowDocument().adHocToPrincipal(ActionRequestType.FYI, poa.getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next(), "This POA is ready for printing and distribution.", userToRouteFyi, "", true, "PRINT");
260         }
261     }
262 
263     @Override
264     public void completePurchaseOrderAmendment(PurchaseOrderDocument poa) {
265         LOG.debug("completePurchaseOrderAmendment() started");
266 
267         setCurrentAndPendingIndicatorsForApprovedPODocuments(poa);
268 
269         if (SpringContext.getBean(PaymentRequestService.class).hasActivePaymentRequestsForPurchaseOrder(poa.getPurapDocumentIdentifier())) {
270             poa.setPaymentRequestPositiveApprovalIndicator(true);
271             poa.setReceivingDocumentRequiredIndicator(false);
272         }
273         // check thresholds to see if receiving is required for purchase order amendment
274         else if (!poa.isReceivingDocumentRequiredIndicator()) {
275             setReceivingRequiredIndicatorForPurchaseOrder(poa);
276         }
277 
278         // if unordered items have been added to the PO then send an FYI to all fiscal officers
279        /* if (hasNewUnorderedItem(poa)) {
280             sendFyiForNewUnorderedItems(poa);
281         }*/
282         DocumentRouteHeaderValue routeHeader = SpringContext.getBean(RouteHeaderService.class).getRouteHeader(poa.getDocumentNumber());
283         String status = routeHeader.getDocRouteStatus();
284         if (status.equals(KewApiConstants.ROUTE_HEADER_PROCESSED_CD)) {
285             List<PurApItem> items = poa.getItems();
286             for (PurApItem item : items) {
287                 initiateTransmission(poa, item);
288             }
289             //initiateTransmission(poa);
290         }
291 
292     }
293     /**
294      * Gets the documentService attribute.
295      * @return Returns the documentService.
296      */
297     // public DocumentService getDocumentService() {
298     //     return documentService;
299     // }
300 
301 
302     /**
303      * Sets the documentService attribute value.
304      * @param documentService The documentService to set.
305      */
306     //  public void setDocumentService(DocumentService documentService) {
307     //      this.documentService = documentService;
308     //  }
309 
310 
311     /**
312      * @see org.kuali.ole.module.purap.document.service.PurchaseOrderService#createPurchaseOrderDocument(org.kuali.ole.module.purap.document.RequisitionDocument,
313      *      java.lang.String, java.lang.Integer)
314      */
315     @Override
316     public PurchaseOrderDocument createPurchaseOrderDocument(RequisitionDocument reqDocument, String newSessionUserId, Integer contractManagerCode) {
317         try {
318             LogicContainer logicToRun = new LogicContainer() {
319                 @Override
320                 public Object runLogic(Object[] objects) throws Exception {
321                     RequisitionDocument doc = (RequisitionDocument) objects[0];
322                     PurchaseOrderDocument po = generatePurchaseOrderFromRequisition(doc);
323                     Integer cmCode = (Integer) objects[1];
324                     po.setContractManagerCode(cmCode);
325                     String paramName = PurapParameterConstants.DEFAULT_B2B_VENDOR_CHOICE;
326                     String paramValue = SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurchaseOrderDocument.class, paramName);
327                     po.setPurchaseOrderVendorChoiceCode(paramValue);
328                     purapService.saveDocumentNoValidation(po);
329                     return po;
330                 }
331             };
332             return (PurchaseOrderDocument) purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, new Object[]{reqDocument, contractManagerCode});
333         } catch (WorkflowException e) {
334             String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
335             LOG.error(errorMsg, e);
336             throw new RuntimeException(errorMsg, e);
337         } catch (Exception e) {
338             throw new RuntimeException(e);
339         }
340     }
341 
342     public String createPurchaseOrderAmendmentDocument(OlePurchaseOrderDocument olePurchaseOrderDocument,String docNumber) {
343         String errorString = null;
344         String newStatus = PurapConstants.PurchaseOrderStatuses.APPDOC_AMENDMENT;
345         String annotation = "Amended in batch by PO document "+olePurchaseOrderDocument.getDocumentNumber()+" and POBA document "+docNumber;
346         String documentType = "OLE_POA";
347         //PurchaseOrderDocument document = getPurchaseOrderByDocumentNumber(olePurchaseOrderDocument.getDocumentNumber());
348         createNoteForAutoCloseOrders(olePurchaseOrderDocument, annotation);
349         try {
350             synchronized (this) {
351                 createAndRoutePotentialChangeDocument(olePurchaseOrderDocument, documentType, annotation, null, newStatus);
352             }
353 
354         }  catch (Exception e) {
355             Map<String, AutoPopulatingList<ErrorMessage>> errorMessages = GlobalVariables.getMessageMap().getErrorMessages();
356             for (Iterator<String> errorMessageIterator = errorMessages.keySet().iterator(); errorMessageIterator.hasNext(); ) {
357                 String errorKey = errorMessageIterator.next();
358                 AutoPopulatingList<ErrorMessage> errorList = errorMessages.get(errorKey);
359                 for (ErrorMessage errorMessage : errorList) {
360                     if(StringUtils.isNotEmpty(errorString)){
361                         errorString += MessageFormat.format(kualiConfigurationService.getPropertyValueAsString(errorMessage.getErrorKey()), errorMessage.getMessageParameters());
362                         errorString += "\n";
363                    }else{
364                         errorString = MessageFormat.format(kualiConfigurationService.getPropertyValueAsString(errorMessage.getErrorKey()), errorMessage.getMessageParameters());
365                         errorString += "\n";
366                     }
367                 }
368 
369             }
370             GlobalVariables.getMessageMap().clearErrorMessages();
371         }
372         return errorString;
373 
374     }
375 
376     public boolean getIsATypeOfRCVGDoc() {
377         return false;
378     }
379 
380     public boolean getIsATypeOfCORRDoc() {
381         return false;
382     }
383 
384     public OleSelectDocumentService getOleSelectDocumentService() {
385         if(oleSelectDocumentService == null){
386             oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
387         }
388         return oleSelectDocumentService;
389     }
390 
391     public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
392         this.oleSelectDocumentService = oleSelectDocumentService;
393     }
394 
395 }