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