001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.module.purap.document.service.impl; 017 018 import java.io.ByteArrayOutputStream; 019 import java.sql.Date; 020 import java.text.MessageFormat; 021 import java.util.Collection; 022 import java.util.HashMap; 023 import java.util.List; 024 025 import org.apache.commons.lang.StringUtils; 026 import org.apache.log4j.Logger; 027 import org.kuali.rice.kns.exception.ValidationException; 028 import org.kuali.rice.kns.service.DateTimeService; 029 import org.kuali.rice.kns.service.DocumentService; 030 import org.kuali.rice.kns.service.KualiConfigurationService; 031 import org.kuali.rice.kns.service.NoteService; 032 import org.kuali.rice.kns.util.GlobalVariables; 033 import org.kuali.rice.kns.util.ObjectUtils; 034 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 035 import org.kuali.rice.kns.workflow.service.WorkflowDocumentService; 036 import org.kuali.kfs.module.purap.PurapConstants; 037 import org.kuali.kfs.module.purap.PurapKeyConstants; 038 import org.kuali.kfs.module.purap.PurapWorkflowConstants.PurchaseOrderDocument.NodeDetailEnum; 039 import org.kuali.kfs.module.purap.document.BulkReceivingDocument; 040 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 041 import org.kuali.kfs.module.purap.document.CorrectionReceivingDocument; 042 import org.kuali.kfs.module.purap.document.ReceivingDocument; 043 import org.kuali.kfs.module.purap.document.LineItemReceivingDocument; 044 import org.kuali.kfs.module.purap.document.dataaccess.BulkReceivingDao; 045 import org.kuali.kfs.module.purap.document.service.BulkReceivingService; 046 import org.kuali.kfs.module.purap.document.service.PrintService; 047 import org.kuali.kfs.module.purap.document.service.PurapService; 048 import org.kuali.kfs.module.purap.document.service.PurchaseOrderService; 049 import org.kuali.kfs.module.purap.document.validation.event.AttributedContinuePurapEvent; 050 import org.kuali.kfs.sys.KFSConstants; 051 import org.kuali.kfs.sys.KFSPropertyConstants; 052 import org.kuali.kfs.sys.context.SpringContext; 053 import org.springframework.transaction.annotation.Transactional; 054 055 import org.kuali.rice.kew.exception.WorkflowException; 056 057 @Transactional 058 public class BulkReceivingServiceImpl implements BulkReceivingService { 059 060 private static final Logger LOG = Logger.getLogger(BulkReceivingServiceImpl.class); 061 062 private DateTimeService dateTimeService; 063 private PurchaseOrderService purchaseOrderService; 064 private BulkReceivingDao bulkReceivingDao; 065 private DocumentService documentService; 066 private WorkflowDocumentService workflowDocumentService; 067 private KualiConfigurationService configurationService; 068 private PurapService purapService; 069 private NoteService noteService; 070 private KualiConfigurationService kualiConfigurationService; 071 private PrintService printService; 072 073 public boolean canPrintReceivingTicket(BulkReceivingDocument blkRecDoc) { 074 075 boolean canCreate = false; 076 KualiWorkflowDocument workflowDocument = null; 077 078 try{ 079 workflowDocument = workflowDocumentService.createWorkflowDocument(Long.valueOf(blkRecDoc.getDocumentNumber()), GlobalVariables.getUserSession().getPerson()); 080 }catch(WorkflowException we){ 081 throw new RuntimeException(we); 082 } 083 084 if( workflowDocument.stateIsFinal()){ 085 canCreate = true; 086 } 087 088 return canCreate; 089 } 090 091 public void populateAndSaveBulkReceivingDocument(BulkReceivingDocument blkRecDoc) 092 throws WorkflowException { 093 try { 094 documentService.saveDocument(blkRecDoc, AttributedContinuePurapEvent.class); 095 } 096 catch (WorkflowException we) { 097 String errorMsg = "Error saving document # " + blkRecDoc.getDocumentHeader().getDocumentNumber() + " " + we.getMessage(); 098 throw new RuntimeException(errorMsg, we); 099 } 100 } 101 102 public HashMap<String, String> bulkReceivingDuplicateMessages(BulkReceivingDocument blkRecDoc) { 103 HashMap<String, String> msgs; 104 msgs = new HashMap<String, String>(); 105 Integer poId = blkRecDoc.getPurchaseOrderIdentifier(); 106 StringBuffer currentMessage = new StringBuffer(""); 107 List<String> docNumbers = null; 108 109 //check vendor date for duplicates 110 if( blkRecDoc.getShipmentReceivedDate() != null ){ 111 docNumbers = bulkReceivingDao.duplicateVendorDate(poId, blkRecDoc.getShipmentReceivedDate()); 112 if( hasDuplicateEntry(docNumbers) ){ 113 appendDuplicateMessage(currentMessage, PurapKeyConstants.MESSAGE_DUPLICATE_RECEIVING_LINE_VENDOR_DATE, blkRecDoc.getPurchaseOrderIdentifier()); 114 } 115 } 116 117 //check packing slip number for duplicates 118 if( !StringUtils.isEmpty(blkRecDoc.getShipmentPackingSlipNumber()) ){ 119 docNumbers = bulkReceivingDao.duplicatePackingSlipNumber(poId, blkRecDoc.getShipmentPackingSlipNumber()); 120 if( hasDuplicateEntry(docNumbers) ){ 121 appendDuplicateMessage(currentMessage, PurapKeyConstants.MESSAGE_DUPLICATE_RECEIVING_LINE_PACKING_SLIP_NUMBER, blkRecDoc.getPurchaseOrderIdentifier()); 122 } 123 } 124 125 //check bill of lading number for duplicates 126 if( !StringUtils.isEmpty(blkRecDoc.getShipmentBillOfLadingNumber()) ){ 127 docNumbers = bulkReceivingDao.duplicateBillOfLadingNumber(poId, blkRecDoc.getShipmentBillOfLadingNumber()); 128 if( hasDuplicateEntry(docNumbers) ){ 129 appendDuplicateMessage(currentMessage, PurapKeyConstants.MESSAGE_DUPLICATE_RECEIVING_LINE_BILL_OF_LADING_NUMBER, blkRecDoc.getPurchaseOrderIdentifier()); 130 } 131 } 132 133 //add message if one exists 134 if(currentMessage.length() > 0){ 135 //add suffix 136 appendDuplicateMessage(currentMessage, PurapKeyConstants.MESSAGE_DUPLICATE_RECEIVING_LINE_SUFFIX, blkRecDoc.getPurchaseOrderIdentifier() ); 137 138 //add msg to map 139 msgs.put(PurapConstants.BulkReceivingDocumentStrings.DUPLICATE_BULK_RECEIVING_DOCUMENT_QUESTION, currentMessage.toString()); 140 } 141 142 return msgs; 143 } 144 145 /** 146 * Looks at a list of doc numbers, but only considers an entry duplicate 147 * if the document is in a Final status. 148 * 149 * @param docNumbers 150 * @return 151 */ 152 protected boolean hasDuplicateEntry(List<String> docNumbers){ 153 154 boolean isDuplicate = false; 155 KualiWorkflowDocument workflowDocument = null; 156 157 for (String docNumber : docNumbers) { 158 159 try{ 160 workflowDocument = workflowDocumentService.createWorkflowDocument(Long.valueOf(docNumber), GlobalVariables.getUserSession().getPerson()); 161 }catch(WorkflowException we){ 162 throw new RuntimeException(we); 163 } 164 165 //if the doc number exists, and is in final status, consider this a dupe and return 166 if(workflowDocument.stateIsFinal()){ 167 isDuplicate = true; 168 break; 169 } 170 } 171 172 return isDuplicate; 173 174 } 175 176 protected void appendDuplicateMessage(StringBuffer currentMessage, 177 String duplicateMessageKey, 178 Integer poId){ 179 180 //append prefix if this is first call 181 if(currentMessage.length() == 0){ 182 String messageText = configurationService.getPropertyString(PurapKeyConstants.MESSAGE_BULK_RECEIVING_DUPLICATE_PREFIX); 183 String prefix = MessageFormat.format(messageText, poId.toString() ); 184 185 currentMessage.append(prefix); 186 } 187 188 //append message 189 currentMessage.append( configurationService.getPropertyString(duplicateMessageKey) ); 190 } 191 192 public String getBulkReceivingDocumentNumberInProcessForPurchaseOrder(Integer poId, 193 String bulkReceivingDocumentNumber){ 194 195 String docNumberInProcess = StringUtils.EMPTY; 196 197 List<String> docNumbers = bulkReceivingDao.getDocumentNumbersByPurchaseOrderId(poId); 198 KualiWorkflowDocument workflowDocument = null; 199 200 for (String docNumber : docNumbers) { 201 202 try{ 203 workflowDocument = workflowDocumentService.createWorkflowDocument(Long.valueOf(docNumber), 204 GlobalVariables.getUserSession().getPerson()); 205 }catch(WorkflowException we){ 206 throw new RuntimeException(we); 207 } 208 209 if(!(workflowDocument.stateIsCanceled() || 210 workflowDocument.stateIsException() || 211 workflowDocument.stateIsFinal()) && 212 !docNumber.equals(bulkReceivingDocumentNumber)){ 213 214 docNumberInProcess = docNumber; 215 break; 216 } 217 } 218 219 return docNumberInProcess; 220 } 221 222 public void populateBulkReceivingFromPurchaseOrder(BulkReceivingDocument blkRecDoc) { 223 224 if (blkRecDoc != null){ 225 PurchaseOrderDocument poDoc = purchaseOrderService.getCurrentPurchaseOrder(blkRecDoc.getPurchaseOrderIdentifier()); 226 if(poDoc != null){ 227 blkRecDoc.populateBulkReceivingFromPurchaseOrder(poDoc); 228 } 229 } 230 231 } 232 233 public BulkReceivingDocument getBulkReceivingByDocumentNumber(String documentNumber){ 234 235 if (ObjectUtils.isNotNull(documentNumber)) { 236 try { 237 BulkReceivingDocument doc = (BulkReceivingDocument) documentService.getByDocumentHeaderId(documentNumber); 238 if (ObjectUtils.isNotNull(doc)) { 239 KualiWorkflowDocument workflowDocument = doc.getDocumentHeader().getWorkflowDocument(); 240 doc.refreshReferenceObject(KFSPropertyConstants.DOCUMENT_HEADER); 241 doc.getDocumentHeader().setWorkflowDocument(workflowDocument); 242 } 243 return doc; 244 } 245 catch (WorkflowException e) { 246 String errorMessage = "Error getting bulk receiving document from document service"; 247 throw new RuntimeException(errorMessage, e); 248 } 249 } 250 return null; 251 } 252 253 public void performPrintReceivingTicketPDF(String blkDocId, 254 ByteArrayOutputStream baosPDF){ 255 256 BulkReceivingDocument blkRecDoc = getBulkReceivingByDocumentNumber(blkDocId); 257 Collection<String> generatePDFErrors = printService.generateBulkReceivingPDF(blkRecDoc, baosPDF); 258 259 if (!generatePDFErrors.isEmpty()) { 260 addStringErrorMessagesToErrorMap(PurapKeyConstants.ERROR_BULK_RECEIVING_PDF, generatePDFErrors); 261 throw new ValidationException("printing bulk receiving ticket failed"); 262 } 263 264 } 265 266 protected void addStringErrorMessagesToErrorMap(String errorKey, 267 Collection<String> errors) { 268 269 if (ObjectUtils.isNotNull(errors)) { 270 for (String error : errors) { 271 LOG.error("Adding error message using error key '" + errorKey + "' with text '" + error + "'"); 272 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, errorKey, error); 273 } 274 } 275 276 } 277 278 public KualiConfigurationService getKualiConfigurationService() { 279 return kualiConfigurationService; 280 } 281 282 public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) { 283 this.kualiConfigurationService = kualiConfigurationService; 284 } 285 286 public PrintService getPrintService() { 287 return printService; 288 } 289 290 public void setPrintService(PrintService printService) { 291 this.printService = printService; 292 } 293 294 public void setPurchaseOrderService(PurchaseOrderService purchaseOrderService) { 295 this.purchaseOrderService = purchaseOrderService; 296 } 297 298 public void setBulkReceivingDao(BulkReceivingDao bulkReceivingDao) { 299 this.bulkReceivingDao = bulkReceivingDao; 300 } 301 302 public void setDocumentService(DocumentService documentService){ 303 this.documentService = documentService; 304 } 305 306 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService){ 307 this.workflowDocumentService = workflowDocumentService; 308 } 309 310 public void setConfigurationService(KualiConfigurationService configurationService) { 311 this.configurationService = configurationService; 312 } 313 314 public void setPurapService(PurapService purapService) { 315 this.purapService = purapService; 316 } 317 318 public void setNoteService(NoteService noteService) { 319 this.noteService = noteService; 320 } 321 322 public DateTimeService getDateTimeService() { 323 return dateTimeService; 324 } 325 326 public void setDateTimeService(DateTimeService dateTimeService) { 327 this.dateTimeService = dateTimeService; 328 } 329 } 330