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