1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.module.purap.document.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.lang.text.StrBuilder;
20 import org.kuali.ole.coa.businessobject.Account;
21 import org.kuali.ole.coa.service.AccountService;
22 import org.kuali.ole.deliver.batch.OleMailer;
23 import org.kuali.ole.integration.purap.CapitalAssetSystem;
24 import org.kuali.ole.module.purap.*;
25 import org.kuali.ole.module.purap.PurapConstants.*;
26 import org.kuali.ole.module.purap.batch.AutoClosePurchaseOrdersStep;
27 import org.kuali.ole.module.purap.batch.AutoCloseRecurringOrdersStep;
28 import org.kuali.ole.module.purap.businessobject.*;
29 import org.kuali.ole.module.purap.document.*;
30 import org.kuali.ole.module.purap.document.dataaccess.PurchaseOrderDao;
31 import org.kuali.ole.module.purap.document.service.*;
32 import org.kuali.ole.module.purap.edi.PurchaseOrderEdi;
33 import org.kuali.ole.module.purap.pdf.PurchaseOrderParameters;
34 import org.kuali.ole.module.purap.pdf.PurchaseOrderPdf;
35 import org.kuali.ole.module.purap.pdf.PurchaseOrderTransmitParameters;
36 import org.kuali.ole.module.purap.util.PurApObjectUtils;
37 import org.kuali.ole.module.purap.util.ThresholdHelper;
38 import org.kuali.ole.module.purap.util.ThresholdHelper.ThresholdSummary;
39 import org.kuali.ole.select.document.service.OleSelectDocumentService;
40 import org.kuali.ole.select.service.OleTransmissionService;
41 import org.kuali.ole.sys.OLEConstants;
42 import org.kuali.ole.sys.OLEPropertyConstants;
43 import org.kuali.ole.sys.businessobject.SourceAccountingLine;
44 import org.kuali.ole.sys.context.SpringContext;
45 import org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase;
46 import org.kuali.ole.sys.document.validation.event.AttributedRouteDocumentEvent;
47 import org.kuali.ole.sys.document.validation.event.DocumentSystemSaveEvent;
48 import org.kuali.ole.sys.service.impl.OleParameterConstants;
49 import org.kuali.ole.vnd.VendorConstants;
50 import org.kuali.ole.vnd.VendorConstants.AddressTypes;
51 import org.kuali.ole.vnd.businessobject.*;
52 import org.kuali.ole.vnd.document.service.VendorService;
53 import org.kuali.rice.core.api.config.property.ConfigContext;
54 import org.kuali.rice.core.api.config.property.ConfigurationService;
55 import org.kuali.rice.core.api.datetime.DateTimeService;
56 import org.kuali.rice.core.api.mail.*;
57 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
58 import org.kuali.rice.core.api.util.type.KualiDecimal;
59 import org.kuali.rice.coreservice.api.parameter.Parameter;
60 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
61 import org.kuali.rice.kew.api.KewApiConstants;
62 import org.kuali.rice.kew.api.KewApiServiceLocator;
63 import org.kuali.rice.kew.api.WorkflowDocument;
64 import org.kuali.rice.kew.api.action.ActionRequestType;
65 import org.kuali.rice.kew.api.document.WorkflowDocumentService;
66 import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
67 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
68 import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
69 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
70 import org.kuali.rice.kew.api.exception.WorkflowException;
71 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
72 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
73 import org.kuali.rice.kew.service.KEWServiceLocator;
74 import org.kuali.rice.kim.api.identity.Person;
75 import org.kuali.rice.kim.api.identity.PersonService;
76 import org.kuali.rice.kns.document.MaintenanceDocument;
77 import org.kuali.rice.kns.maintenance.Maintainable;
78 import org.kuali.rice.kns.service.DataDictionaryService;
79 import org.kuali.rice.kns.util.KNSGlobalVariables;
80 import org.kuali.rice.krad.bo.AdHocRoutePerson;
81 import org.kuali.rice.krad.bo.AdHocRouteRecipient;
82 import org.kuali.rice.krad.bo.Note;
83 import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
84 import org.kuali.rice.krad.document.Document;
85 import org.kuali.rice.krad.document.DocumentBase;
86 import org.kuali.rice.krad.exception.ValidationException;
87 import org.kuali.rice.krad.rules.rule.event.RouteDocumentEvent;
88 import org.kuali.rice.krad.service.*;
89 import org.kuali.rice.krad.util.GlobalVariables;
90 import org.kuali.rice.krad.util.MessageMap;
91 import org.kuali.rice.krad.util.ObjectUtils;
92 import org.springframework.transaction.annotation.Transactional;
93
94 import java.io.ByteArrayOutputStream;
95 import java.io.File;
96 import java.sql.Timestamp;
97 import java.text.ParseException;
98 import java.util.*;
99
100 @Transactional
101 public class PurchaseOrderServiceImpl implements PurchaseOrderService {
102 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderServiceImpl.class);
103
104 protected BusinessObjectService businessObjectService;
105 protected DateTimeService dateTimeService;
106 protected DocumentService documentService;
107 protected NoteService noteService;
108 protected PurapService purapService;
109 protected PrintService printService;
110 protected PurchaseOrderDao purchaseOrderDao;
111 protected WorkflowDocumentService workflowDocumentService;
112 protected ConfigurationService kualiConfigurationService;
113 protected KualiRuleService kualiRuleService;
114 protected VendorService vendorService;
115 protected RequisitionService requisitionService;
116 protected PurApWorkflowIntegrationService purapWorkflowIntegrationService;
117 protected MaintenanceDocumentService maintenanceDocumentService;
118 protected ParameterService parameterService;
119 protected PersonService personService;
120 protected MailService mailService;
121 protected B2BPurchaseOrderService b2bPurchaseOrderService;
122 protected DataDictionaryService dataDictionaryService;
123 protected String documentNumber;
124 protected String fromEmailAddress;
125 protected List fileNameList;
126 protected String toEmailAddress;
127
128 protected static final boolean TRANSMISSION_IS_RETRANSMIT = true;
129 protected static final boolean TRANSMISSION_IS_NOT_RETRANSMIT = !TRANSMISSION_IS_RETRANSMIT;
130 protected OlePurapService olePurapService;
131 private OleSelectDocumentService oleSelectDocumentService;
132
133 public OlePurapService getOlePurapService() {
134 if (olePurapService == null) {
135 olePurapService = SpringContext.getBean(OlePurapService.class);
136 }
137 return olePurapService;
138 }
139
140 @Override
141 public boolean isPurchaseOrderOpenForProcessing(Integer poId) {
142 return isPurchaseOrderOpenForProcessing(getCurrentPurchaseOrder(poId));
143 }
144
145 @Override
146 public boolean isPurchaseOrderOpenForProcessing(PurchaseOrderDocument purchaseOrderDocument) {
147 boolean can = PurchaseOrderStatuses.APPDOC_OPEN.equals(purchaseOrderDocument.getApplicationDocumentStatus());
148 can = can && purchaseOrderDocument.isPurchaseOrderCurrentIndicator() && !purchaseOrderDocument.isPendingActionIndicator();
149
150
151 if (can) {
152 List<PaymentRequestView> preqViews = purchaseOrderDocument.getRelatedViews().getRelatedPaymentRequestViews();
153 if (preqViews != null) {
154 for (PaymentRequestView preqView : preqViews) {
155 if (!purapService.isPaymentRequestFullDocumentEntryCompleted(preqView.getApplicationDocumentStatus())) {
156 return false;
157 }
158 }
159 }
160 List<CreditMemoView> cmViews = purchaseOrderDocument.getRelatedViews().getRelatedCreditMemoViews();
161 if (cmViews != null) {
162 for (CreditMemoView cmView : cmViews) {
163 if (!purapService.isVendorCreditMemoFullDocumentEntryCompleted(cmView.getApplicationDocumentStatus())) {
164 return false;
165 }
166 }
167 }
168 List<InvoiceView> invViews = purchaseOrderDocument.getRelatedViews().getRelatedInvoiceViews();
169 if (invViews != null) {
170 for (InvoiceView invView : invViews) {
171 if (!purapService.isInvoiceFullDocumentEntryCompleted(invView.getApplicationDocumentStatus())) {
172 return false;
173 }
174 }
175 }
176
177 }
178
179
180 return can;
181 }
182
183 @Override
184 public boolean isCommodityCodeRequiredOnPurchaseOrder() {
185 boolean enableCommodityCode = parameterService.getParameterValueAsBoolean(OleParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_COMMODITY_CODE_IND);
186 if (!enableCommodityCode) {
187 return false;
188 } else {
189 return parameterService.getParameterValueAsBoolean(PurchaseOrderDocument.class, PurapRuleConstants.ITEMS_REQUIRE_COMMODITY_CODE_IND);
190 }
191 }
192
193
194
195
196
197
198 protected void saveDocumentNoValidationUsingClearMessageMap(PurchaseOrderDocument document) {
199 MessageMap errorHolder = GlobalVariables.getMessageMap();
200 GlobalVariables.setMessageMap(new MessageMap());
201 try {
202 purapService.saveDocumentNoValidation(document);
203 } finally {
204 GlobalVariables.setMessageMap(errorHolder);
205 }
206 }
207
208
209
210
211
212
213 protected void saveDocumentStandardSave(PurchaseOrderDocument document) {
214 try {
215 documentService.saveDocument(document);
216 } catch (WorkflowException we) {
217 String errorMsg = "Workflow Error saving document # " + document.getDocumentHeader().getDocumentNumber() + " " + we.getMessage();
218 LOG.error(errorMsg, we);
219 throw new RuntimeException(errorMsg, we);
220 }
221 }
222
223 @Override
224 public PurchasingCapitalAssetItem createCamsItem(PurchasingDocument purDoc, PurApItem purapItem) {
225 PurchasingCapitalAssetItem camsItem = new PurchaseOrderCapitalAssetItem();
226 camsItem.setItemIdentifier(purapItem.getItemIdentifier());
227
228 if (purDoc.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetTabStrings.INDIVIDUAL_ASSETS)) {
229 CapitalAssetSystem resultSystem = new PurchaseOrderCapitalAssetSystem();
230 camsItem.setPurchasingCapitalAssetSystem(resultSystem);
231 }
232 camsItem.setPurchasingDocument(purDoc);
233
234 return camsItem;
235 }
236
237 @Override
238 public CapitalAssetSystem createCapitalAssetSystem() {
239 CapitalAssetSystem resultSystem = new PurchaseOrderCapitalAssetSystem();
240 return resultSystem;
241 }
242
243
244
245
246 @Override
247 public void createAutomaticPurchaseOrderDocument(RequisitionDocument reqDocument) {
248 String newSessionUserId = getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER);
249 try {
250
251 LogicContainer logicToRun = new LogicContainer() {
252 @Override
253 public Object runLogic(Object[] objects) throws Exception {
254 RequisitionDocument doc = (RequisitionDocument) objects[0];
255
256 doc.setPurchaseOrderAutomaticIndicator(Boolean.TRUE);
257
258 PurchaseOrderDocument po = generatePurchaseOrderFromRequisition(doc);
259 po.setDefaultValuesForAPO();
260
261
262 checkForPrintTransmission(po);
263 po.setContractManagerCode(PurapConstants.APO_CONTRACT_MANAGER);
264
265
266
267 final DocumentAttributeIndexingQueue documentAttributeIndexingQueue = KewApiServiceLocator.getDocumentAttributeIndexingQueue();
268 documentAttributeIndexingQueue.indexDocument(po.getDocumentNumber());
269
270 return null;
271 }
272 };
273 purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, new Object[]{reqDocument});
274 } catch (WorkflowException e) {
275 String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
276 LOG.error(errorMsg, e);
277 throw new RuntimeException(errorMsg, e);
278 } catch (Exception e) {
279 throw new RuntimeException(e);
280 }
281 }
282
283
284
285
286
287
288
289 protected void checkForPrintTransmission(PurchaseOrderDocument po) throws WorkflowException {
290 if (PurapConstants.POTransmissionMethods.PRINT.equals(po.getPurchaseOrderRetransmissionMethodCode())) {
291 po.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_PENDING_PRINT);
292 }
293 }
294
295
296
297
298
299 @Override
300 public PurchaseOrderDocument createPurchaseOrderDocument(RequisitionDocument reqDocument, String newSessionUserId, Integer contractManagerCode) {
301 try {
302 LogicContainer logicToRun = new LogicContainer() {
303 @Override
304 public Object runLogic(Object[] objects) throws Exception {
305 RequisitionDocument doc = (RequisitionDocument) objects[0];
306 PurchaseOrderDocument po = generatePurchaseOrderFromRequisition(doc);
307 Integer cmCode = (Integer) objects[1];
308 po.setContractManagerCode(cmCode);
309 purapService.saveDocumentNoValidation(po);
310 return po;
311 }
312 };
313 return (PurchaseOrderDocument) purapService.performLogicWithFakedUserSession(newSessionUserId, logicToRun, new Object[]{reqDocument, contractManagerCode});
314 } catch (WorkflowException e) {
315 String errorMsg = "Workflow Exception caught: " + e.getLocalizedMessage();
316 LOG.error(errorMsg, e);
317 throw new RuntimeException(errorMsg, e);
318 } catch (Exception e) {
319 throw new RuntimeException(e);
320 }
321 }
322
323
324
325
326
327
328
329
330 protected PurchaseOrderDocument generatePurchaseOrderFromRequisition(RequisitionDocument reqDocument) throws WorkflowException {
331 PurchaseOrderDocument poDocument = null;
332 poDocument = (PurchaseOrderDocument) documentService.getNewDocument(PurchaseOrderDocTypes.PURCHASE_ORDER_DOCUMENT);
333 poDocument.populatePurchaseOrderFromRequisition(reqDocument);
334
335 poDocument.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_IN_PROCESS);
336
337 poDocument.setPurchaseOrderCurrentIndicator(true);
338 poDocument.setPendingActionIndicator(false);
339
340
341
342 if (RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode())) {
343 String paramName = PurapParameterConstants.DEFAULT_B2B_VENDOR_CHOICE;
344 String paramValue = parameterService.getParameterValueAsString(PurchaseOrderDocument.class, paramName);
345 poDocument.setPurchaseOrderVendorChoiceCode(paramValue);
346 }
347
348 if (ObjectUtils.isNotNull(poDocument.getVendorContract())) {
349 poDocument.setVendorPaymentTermsCode(poDocument.getVendorContract().getVendorPaymentTermsCode());
350 poDocument.setVendorShippingPaymentTermsCode(poDocument.getVendorContract().getVendorShippingPaymentTermsCode());
351 poDocument.setVendorShippingTitleCode(poDocument.getVendorContract().getVendorShippingTitleCode());
352 } else {
353 VendorDetail vendor = vendorService.getVendorDetail(poDocument.getVendorHeaderGeneratedIdentifier(), poDocument.getVendorDetailAssignedIdentifier());
354 if (ObjectUtils.isNotNull(vendor)) {
355 poDocument.setVendorPaymentTermsCode(vendor.getVendorPaymentTermsCode());
356 poDocument.setVendorShippingPaymentTermsCode(vendor.getVendorShippingPaymentTermsCode());
357 poDocument.setVendorShippingTitleCode(vendor.getVendorShippingTitleCode());
358 }
359 }
360
361 if (!PurapConstants.RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode())) {
362 purapService.addBelowLineItems(poDocument);
363 }
364 poDocument.fixItemReferences();
365
366 return poDocument;
367 }
368
369
370
371
372 @Override
373 public KualiDecimal getInternalPurchasingDollarLimit(PurchaseOrderDocument document) {
374 if ((document.getVendorContract() != null) && (document.getContractManager() != null)) {
375 KualiDecimal contractDollarLimit = vendorService.getApoLimitFromContract(document.getVendorContract().getVendorContractGeneratedIdentifier(), document.getChartOfAccountsCode(), document.getOrganizationCode());
376
377
378
379
380
381 if (document.getContractManager().getContractManagerDelegationDollarLimit() == null) {
382 document.refreshReferenceObject(PurapPropertyConstants.CONTRACT_MANAGER);
383 }
384 KualiDecimal contractManagerLimit = document.getContractManager().getContractManagerDelegationDollarLimit();
385 if ((contractDollarLimit != null) && (contractManagerLimit != null)) {
386 if (contractDollarLimit.compareTo(contractManagerLimit) > 0) {
387 return contractDollarLimit;
388 } else {
389 return contractManagerLimit;
390 }
391 } else if (contractDollarLimit != null) {
392 return contractDollarLimit;
393 } else {
394 return contractManagerLimit;
395 }
396 } else if ((document.getVendorContract() == null) && (document.getContractManager() != null)) {
397
398 if (document.getContractManager().getContractManagerDelegationDollarLimit() == null) {
399 document.refreshReferenceObject(PurapPropertyConstants.CONTRACT_MANAGER);
400 }
401 return document.getContractManager().getContractManagerDelegationDollarLimit();
402 } else if ((document.getVendorContract() != null) && (document.getContractManager() == null)) {
403 return purapService.getApoLimit(document.getVendorContract().getVendorContractGeneratedIdentifier(), document.getChartOfAccountsCode(), document.getOrganizationCode());
404 } else {
405 String errorMsg = "No internal purchase order dollar limit found for purchase order '" + document.getPurapDocumentIdentifier() + "'.";
406 LOG.warn(errorMsg);
407 return null;
408 }
409 }
410
411
412
413
414
415
416
417 protected void addStringErrorMessagesToMessageMap(String errorKey, Collection<String> errors) {
418 if (ObjectUtils.isNotNull(errors)) {
419 for (String error : errors) {
420 LOG.error("Adding error message using error key '" + errorKey + "' with text '" + error + "'");
421 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, errorKey, error);
422 }
423 }
424 }
425
426
427
428
429
430
431
432
433 @Override
434 public boolean printPurchaseOrderQuoteRequestsListPDF(String documentNumber, ByteArrayOutputStream baosPDF) {
435 PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(documentNumber);
436 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
437 Collection<String> generatePDFErrors = printService.generatePurchaseOrderQuoteRequestsListPdf(po, baosPDF);
438
439 if (generatePDFErrors.size() > 0) {
440 addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
441 return false;
442 } else {
443 return true;
444 }
445 }
446
447
448
449
450
451
452
453 @Override
454 public boolean printPurchaseOrderQuotePDF(PurchaseOrderDocument po, PurchaseOrderVendorQuote povq, ByteArrayOutputStream baosPDF) {
455 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
456 Collection<String> generatePDFErrors = printService.generatePurchaseOrderQuotePdf(po, povq, baosPDF, environment);
457
458 if (generatePDFErrors.size() > 0) {
459 addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
460 return false;
461 } else {
462 return true;
463 }
464 }
465
466
467
468
469
470 @Override
471 public void performPurchaseOrderFirstTransmitViaPrinting(String documentNumber, ByteArrayOutputStream baosPDF) {
472 PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(documentNumber);
473 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
474 Collection<String> generatePDFErrors = printService.generatePurchaseOrderPdf(po, baosPDF, environment, null);
475 if (!generatePDFErrors.isEmpty()) {
476 addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
477 throw new ValidationException("printing purchase order for first transmission failed");
478 }
479 if (ObjectUtils.isNotNull(po.getPurchaseOrderFirstTransmissionTimestamp())) {
480
481 String errorMsg = "Method to perform first transmit was called on document (doc id " + documentNumber + ") with already filled in 'first transmit date'";
482 LOG.error(errorMsg);
483 throw new RuntimeException(errorMsg);
484 }
485 Timestamp currentDate = dateTimeService.getCurrentTimestamp();
486 po.setPurchaseOrderFirstTransmissionTimestamp(currentDate);
487 po.setPurchaseOrderLastTransmitTimestamp(currentDate);
488 po.setOverrideWorkflowButtons(Boolean.FALSE);
489 boolean performedAction = purapWorkflowIntegrationService.takeAllActionsForGivenCriteria(po, "Action taken automatically as part of document initial print transmission", PurapConstants.PurchaseOrderStatuses.NODE_DOCUMENT_TRANSMISSION, GlobalVariables.getUserSession().getPerson(), null);
490 if (!performedAction) {
491 Person systemUserPerson = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
492 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));
493 }
494 po.setOverrideWorkflowButtons(Boolean.TRUE);
495 if (!po.getApplicationDocumentStatus().equals(PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN)) {
496 attemptSetupOfInitialOpenOfDocument(po);
497 }
498 purapService.saveDocumentNoValidation(po);
499 }
500
501
502
503
504
505 @Override
506 public void performPurchaseOrderPreviewPrinting(String documentNumber, ByteArrayOutputStream baosPDF) {
507 performPrintPurchaseOrderPDFOnly(documentNumber, baosPDF);
508 }
509
510
511
512
513
514 @Override
515 public void performPrintPurchaseOrderPDFOnly(String documentNumber, ByteArrayOutputStream baosPDF) {
516 PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(documentNumber);
517 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
518 Collection<String> generatePDFErrors = printService.generatePurchaseOrderPdf(po, baosPDF, environment, null);
519 if (!generatePDFErrors.isEmpty()) {
520 addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
521 throw new ValidationException("printing purchase order for first transmission failed");
522 }
523 }
524
525
526
527
528
529 @Override
530 public void retransmitPurchaseOrderPDF(PurchaseOrderDocument po, ByteArrayOutputStream baosPDF) {
531
532 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
533 List<PurchaseOrderItem> items = po.getItems();
534 List<PurchaseOrderItem> retransmitItems = new ArrayList<PurchaseOrderItem>();
535 for (PurchaseOrderItem item : items) {
536 if (item.isItemSelectedForRetransmitIndicator()) {
537 retransmitItems.add(item);
538 }
539 }
540 Collection<String> generatePDFErrors = printService.generatePurchaseOrderPdfForRetransmission(po, baosPDF, environment, retransmitItems);
541
542 if (generatePDFErrors.size() > 0) {
543 addStringErrorMessagesToMessageMap(PurapKeyConstants.ERROR_PURCHASE_ORDER_PDF, generatePDFErrors);
544 throw new ValidationException("found errors while trying to print po with doc id " + po.getDocumentNumber());
545 }
546 po.setPurchaseOrderLastTransmitTimestamp(dateTimeService.getCurrentTimestamp());
547 purapService.saveDocumentNoValidation(po);
548 }
549
550
551
552
553
554
555
556
557
558
559
560
561 protected PurchaseOrderDocument createPurchaseOrderDocumentFromSourceDocument(PurchaseOrderDocument sourceDocument, String docType) throws WorkflowException {
562 if (ObjectUtils.isNull(sourceDocument)) {
563 String errorMsg = "Attempting to create new PO of type '" + docType + "' from source PO doc that is null";
564 LOG.error(errorMsg);
565 throw new RuntimeException(errorMsg);
566 }
567
568 PurchaseOrderDocument newPurchaseOrderChangeDocument = (PurchaseOrderDocument) documentService.getNewDocument(docType);
569 newPurchaseOrderChangeDocument.setAccountDistributionMethod(sourceDocument.getAccountDistributionMethod());
570
571 Set classesToExclude = new HashSet();
572 Class sourceObjectClass = FinancialSystemTransactionalDocumentBase.class;
573 classesToExclude.add(sourceObjectClass);
574 while (sourceObjectClass.getSuperclass() != null) {
575 sourceObjectClass = sourceObjectClass.getSuperclass();
576 classesToExclude.add(sourceObjectClass);
577 }
578 PurApObjectUtils.populateFromBaseWithSuper(sourceDocument, newPurchaseOrderChangeDocument, PurapConstants.uncopyableFieldsForPurchaseOrder(), classesToExclude);
579 newPurchaseOrderChangeDocument.getDocumentHeader().setDocumentDescription(sourceDocument.getDocumentHeader().getDocumentDescription());
580 newPurchaseOrderChangeDocument.getDocumentHeader().setOrganizationDocumentNumber(sourceDocument.getDocumentHeader().getOrganizationDocumentNumber());
581 newPurchaseOrderChangeDocument.getDocumentHeader().setExplanation(sourceDocument.getDocumentHeader().getExplanation());
582 newPurchaseOrderChangeDocument.setPurchaseOrderCurrentIndicator(false);
583 newPurchaseOrderChangeDocument.setPendingActionIndicator(false);
584
585
586
587
588 for (PurApItem item : (List<PurApItem>) newPurchaseOrderChangeDocument.getItems()) {
589 item.getSourceAccountingLines().iterator();
590
591 SequenceAccessorService sas = SpringContext.getBean(SequenceAccessorService.class);
592 Integer itemIdentifier = sas.getNextAvailableSequenceNumber("PO_ITM_ID", PurApItem.class).intValue();
593 item.setItemIdentifier(itemIdentifier);
594 }
595
596 updateCapitalAssetRelatedCollections(newPurchaseOrderChangeDocument);
597 newPurchaseOrderChangeDocument.refreshNonUpdateableReferences();
598
599 return newPurchaseOrderChangeDocument;
600 }
601
602 protected void updateCapitalAssetRelatedCollections(PurchaseOrderDocument newDocument) {
603
604 for (PurchasingCapitalAssetItem capitalAssetItem : newDocument.getPurchasingCapitalAssetItems()) {
605 Integer lineNumber = capitalAssetItem.getPurchasingItem().getItemLineNumber();
606 PurApItem newItem = newDocument.getItemByLineNumber(lineNumber.intValue());
607 capitalAssetItem.setItemIdentifier(newItem.getItemIdentifier());
608 capitalAssetItem.setPurchasingDocument(newDocument);
609 capitalAssetItem.setCapitalAssetSystemIdentifier(null);
610 CapitalAssetSystem oldSystem = capitalAssetItem.getPurchasingCapitalAssetSystem();
611 capitalAssetItem.setPurchasingCapitalAssetSystem(new PurchaseOrderCapitalAssetSystem(oldSystem));
612
613 }
614 }
615
616
617
618
619
620 @Override
621 public PurchaseOrderDocument createAndSavePotentialChangeDocument(String documentNumber, String docType, String currentDocumentStatusCode) {
622 PurchaseOrderDocument currentDocument = getPurchaseOrderByDocumentNumber(documentNumber);
623
624 try {
625 PurchaseOrderDocument newDocument = createPurchaseOrderDocumentFromSourceDocument(currentDocument, docType);
626
627 if (ObjectUtils.isNotNull(newDocument)) {
628 newDocument.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS);
629
630
631 if (StringUtils.isNotBlank(currentDocumentStatusCode)) {
632 currentDocument.updateAndSaveAppDocStatus(currentDocumentStatusCode);
633 }
634 try {
635 documentService.saveDocument(newDocument, DocumentSystemSaveEvent.class);
636 }
637
638 catch (ValidationException ve) {
639 throw ve;
640 }
641
642 currentDocument.setPendingActionIndicator(true);
643 Note note = new Note();
644 List<Note> noteList = new ArrayList<Note>();
645 currentDocument.setNotes(noteList);
646 saveDocumentNoValidationUsingClearMessageMap(currentDocument);
647
648
649 return newDocument;
650 } else {
651 String errorMsg = "Attempting to create new PO of type '" + docType + "' from source PO doc id "
652 + documentNumber + " returned null for new document";
653 LOG.error(errorMsg);
654 throw new RuntimeException(errorMsg);
655 }
656 } catch (WorkflowException we) {
657 String errorMsg = "Workflow Exception caught trying to create and save PO document of type '" + docType
658 + "' using source document with doc id '" + documentNumber + "'";
659 LOG.error(errorMsg, we);
660 throw new RuntimeException(errorMsg, we);
661 }
662 }
663
664
665
666
667
668 @Override
669 public PurchaseOrderDocument createAndRoutePotentialChangeDocument(String documentNumber, String docType, String annotation, List adhocRoutingRecipients, String currentDocumentStatusCode) {
670 PurchaseOrderDocument currentDocument = getPurchaseOrderByDocumentNumber(documentNumber);
671
672 try {
673 currentDocument.updateAndSaveAppDocStatus(currentDocumentStatusCode);
674 } catch (WorkflowException e) {
675 throw new RuntimeException("Error saving routing data while saving document with id " + currentDocument.getDocumentNumber(), e);
676 }
677
678 try {
679 PurchaseOrderDocument newDocument = createPurchaseOrderDocumentFromSourceDocument(currentDocument, docType);
680
681 newDocument.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_CHANGE_IN_PROCESS);
682 if (ObjectUtils.isNotNull(newDocument)) {
683 try {
684
685
686 currentDocument.setPendingActionIndicator(true);
687 documentService.routeDocument(newDocument, annotation, adhocRoutingRecipients);
688 }
689
690 catch (ValidationException ve) {
691
692 currentDocument.setPendingActionIndicator(false);
693
694 saveDocumentNoValidationUsingClearMessageMap(currentDocument);
695 throw ve;
696 }
697 return newDocument;
698 } else {
699 String errorMsg = "Attempting to create new PO of type '" + docType + "' from source PO doc id " + documentNumber + " returned null for new document";
700 LOG.error(errorMsg);
701 throw new RuntimeException(errorMsg);
702 }
703 } catch (WorkflowException we) {
704 String errorMsg = "Workflow Exception caught trying to create and route PO document of type '" + docType + "' using source document with doc id '" + documentNumber + "'";
705 LOG.error(errorMsg, we);
706 throw new RuntimeException(errorMsg, we);
707 }
708 }
709
710
711
712
713
714 @Override
715 public PurchaseOrderSplitDocument createAndSavePurchaseOrderSplitDocument(List<PurchaseOrderItem> newPOItems, PurchaseOrderDocument currentDocument, boolean copyNotes, String splitNoteText) {
716
717 if (ObjectUtils.isNull(currentDocument)) {
718 String errorMsg = "Attempting to create new PO of type PurchaseOrderSplitDocument from source PO doc that is null";
719 LOG.error(errorMsg);
720 throw new RuntimeException(errorMsg);
721 }
722
723 try {
724 Note splitNote = SpringContext.getBean(DocumentService.class).createNoteFromDocument(currentDocument, splitNoteText);
725 currentDocument.addNote(splitNote);
726 noteService.save(splitNote);
727 } catch (Exception e) {
728 throw new RuntimeException(e);
729 }
730 String documentNumber = currentDocument.getDocumentNumber();
731
732 try {
733
734 PurchaseOrderSplitDocument newDocument = (PurchaseOrderSplitDocument) documentService.getNewDocument(PurchaseOrderDocTypes.PURCHASE_ORDER_SPLIT_DOCUMENT);
735
736 if (ObjectUtils.isNotNull(newDocument)) {
737
738
739 Set<Class> classesToExclude = getClassesToExcludeFromCopy();
740 Map<String, Class> uncopyableFields = PurapConstants.UNCOPYABLE_FIELDS_FOR_PO;
741 uncopyableFields.putAll(PurapConstants.uncopyableFieldsForSplitPurchaseOrder());
742
743
744 PurApObjectUtils.populateFromBaseWithSuper(currentDocument, newDocument, uncopyableFields, classesToExclude);
745 newDocument.getDocumentHeader().setDocumentDescription(currentDocument.getDocumentHeader().getDocumentDescription());
746 newDocument.getDocumentHeader().setOrganizationDocumentNumber(currentDocument.getDocumentHeader().getOrganizationDocumentNumber());
747 newDocument.setPurchaseOrderCurrentIndicator(true);
748 newDocument.setPendingActionIndicator(false);
749
750 newDocument.setAccountDistributionMethod(currentDocument.getAccountDistributionMethod());
751
752 newDocument.setItems(newPOItems);
753 purapService.addBelowLineItems(newDocument);
754 newDocument.renumberItems(0);
755
756 newDocument.setPostingYear(currentDocument.getPostingYear());
757
758 if (copyNotes) {
759
760 List<Note> notes = currentDocument.getNotes();
761 int noteLength = notes.size();
762 if (noteLength > 0) {
763 notes.subList(noteLength - 1, noteLength).clear();
764 for (Note note : notes) {
765 try {
766 Note copyingNote = documentService.createNoteFromDocument(newDocument, note.getNoteText());
767 newDocument.addNote(copyingNote);
768 noteService.save(copyingNote);
769 } catch (Exception e) {
770 throw new RuntimeException(e);
771 }
772 }
773 }
774 }
775
776 newDocument.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_IN_PROCESS);
777
778
779 fixItemReferences(newDocument);
780
781
782 purapService.saveDocumentNoValidation(newDocument);
783
784
785 splitNoteText = splitNoteText.substring(splitNoteText.indexOf(":") + 1);
786 splitNoteText = PurapConstants.PODocumentsStrings.SPLIT_NOTE_PREFIX_NEW_DOC + currentDocument.getPurapDocumentIdentifier() + " : " + splitNoteText;
787 try {
788 Note splitNote = documentService.createNoteFromDocument(newDocument, splitNoteText);
789 newDocument.addNote(splitNote);
790 noteService.save(splitNote);
791 } catch (Exception e) {
792 throw new RuntimeException(e);
793 }
794
795 return newDocument;
796 } else {
797 String errorMsg = "Attempting to create new PO of type 'PurchaseOrderSplitDocument' from source PO doc id " + documentNumber + " returned null for new document";
798 LOG.error(errorMsg);
799 throw new RuntimeException(errorMsg);
800 }
801 } catch (WorkflowException we) {
802 String errorMsg = "Workflow Exception caught trying to create and save PO document of type PurchaseOrderSplitDocument using source document with doc id '" + documentNumber + "'";
803 LOG.error(errorMsg, we);
804 throw new RuntimeException(errorMsg, we);
805 }
806 }
807
808
809
810
811
812
813 protected Set<Class> getClassesToExcludeFromCopy() {
814 Set<Class> classesToExclude = new HashSet<Class>();
815 Class sourceObjectClass = DocumentBase.class;
816 classesToExclude.add(sourceObjectClass);
817 while (sourceObjectClass.getSuperclass() != null) {
818 sourceObjectClass = sourceObjectClass.getSuperclass();
819 classesToExclude.add(sourceObjectClass);
820 }
821 return classesToExclude;
822 }
823
824
825
826
827
828
829
830
831 protected String getCurrentRouteNodeName(WorkflowDocument wd) throws WorkflowException {
832 String[] nodeNames = (String[]) wd.getNodeNames().toArray();
833 if ((nodeNames == null) || (nodeNames.length == 0)) {
834 return null;
835 } else {
836 return nodeNames[0];
837 }
838 }
839
840
841
842
843 @Override
844 public void completePurchaseOrder(PurchaseOrderDocument po) {
845 LOG.debug("completePurchaseOrder() started");
846 setCurrentAndPendingIndicatorsForApprovedPODocuments(po);
847 setupDocumentForPendingFirstTransmission(po);
848
849
850 if (!po.isReceivingDocumentRequiredIndicator()) {
851 setReceivingRequiredIndicatorForPurchaseOrder(po);
852 }
853
854
855 updateVendorCommodityCode(po);
856
857
858
859
860
861 if (!po.getRequisitionSourceCode().equalsIgnoreCase(PurapConstants.RequisitionSources.MANUAL_INGEST)) {
862 if (!(po.getOrderType().getPurchaseOrderType()).equals(OLEConstants.APPROVAL)) {
863 List<PurApItem> items = po.getItems();
864 fileNameList = new ArrayList();
865 for (PurApItem item : items) {
866 initiateTransmission(po, item);
867 }
868 sendEmail();
869 }
870 }
871
872
873
874 if (!PurchaseOrderStatuses.STATUSES_BY_TRANSMISSION_TYPE.values().contains(po.getApplicationDocumentStatus())) {
875 attemptSetupOfInitialOpenOfDocument(po);
876 } else if (PurchaseOrderStatuses.APPDOC_PENDING_CXML.equals(po.getApplicationDocumentStatus())) {
877 completeB2BPurchaseOrder(po);
878 } else if (PurchaseOrderStatuses.APPDOC_PENDING_PRINT.equals(po.getApplicationDocumentStatus())) {
879
880 String userToRouteFyi = po.getDocumentHeader().getWorkflowDocument().getRoutedByPrincipalId();
881 if (po.getPurchaseOrderAutomaticIndicator()) {
882
883 RequisitionDocument req = requisitionService.getRequisitionById(po.getRequisitionIdentifier());
884 userToRouteFyi = req.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
885 }
886
887 po.getDocumentHeader().getWorkflowDocument().adHocToPrincipal(ActionRequestType.FYI, po.getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next(), "This PO is ready for printing and distribution.", userToRouteFyi, "", true, "PRINT");
888 }
889
890 }
891
892
893 protected boolean completeB2BPurchaseOrder(PurchaseOrderDocument po) {
894 String errors = b2bPurchaseOrderService.sendPurchaseOrder(po);
895 if (StringUtils.isEmpty(errors)) {
896
897 attemptSetupOfInitialOpenOfDocument(po);
898 po.setPurchaseOrderLastTransmitTimestamp(dateTimeService.getCurrentTimestamp());
899 return true;
900 } else {
901
902 try {
903 String noteText = "Unable to transmit the PO for the following reasons:\n" + errors;
904 int noteMaxSize = dataDictionaryService.getAttributeMaxLength("Note", "noteText");
905
906
907 while (noteText.length() > noteMaxSize) {
908 int fromIndex = 0;
909 String noteText1 = noteText.substring(0, noteMaxSize);
910 Note note1 = documentService.createNoteFromDocument(po, noteText1);
911 po.addNote(note1);
912 documentService.saveDocumentNotes(po);
913 noteText = noteText.substring(noteMaxSize);
914 }
915
916 Note note = documentService.createNoteFromDocument(po, noteText);
917 po.addNote(note);
918 documentService.saveDocumentNotes(po);
919 } catch (Exception e) {
920 throw new RuntimeException(e);
921 }
922
923 try {
924 po.updateAndSaveAppDocStatus(PurchaseOrderStatuses.APPDOC_CXML_ERROR);
925 } catch (WorkflowException e) {
926 throw new RuntimeException("Error saving routing data while saving document with id " + po.getDocumentNumber(), e);
927 }
928
929 return false;
930 }
931 }
932
933 @Override
934 public void retransmitB2BPurchaseOrder(PurchaseOrderDocument po) {
935 if (completeB2BPurchaseOrder(po)) {
936 KNSGlobalVariables.getMessageList().add(PurapKeyConstants.B2B_PO_RETRANSMIT_SUCCESS);
937 } else {
938 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PurapKeyConstants.B2B_PO_RETRANSMIT_FAILED);
939 }
940 purapService.saveDocumentNoValidation(po);
941 }
942
943 @Override
944 public void completePurchaseOrderAmendment(PurchaseOrderDocument poa) {
945 LOG.debug("completePurchaseOrderAmendment() started");
946
947 setCurrentAndPendingIndicatorsForApprovedPODocuments(poa);
948
949 if (SpringContext.getBean(PaymentRequestService.class).hasActivePaymentRequestsForPurchaseOrder(poa.getPurapDocumentIdentifier())) {
950 poa.setPaymentRequestPositiveApprovalIndicator(true);
951 poa.setReceivingDocumentRequiredIndicator(false);
952 }
953
954 if (!poa.isReceivingDocumentRequiredIndicator() &&
955 !SpringContext.getBean(PaymentRequestService.class).hasActivePaymentRequestsForPurchaseOrder(poa.getPurapDocumentIdentifier())) {
956 setReceivingRequiredIndicatorForPurchaseOrder(poa);
957 }
958
959
960 if (hasNewUnorderedItem(poa)) {
961 sendFyiForNewUnorderedItems(poa);
962 }
963 DocumentRouteHeaderValue routeHeader = ((RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV)).getRouteHeader(poa.getDocumentNumber());
964 String status = routeHeader.getDocRouteStatus();
965 if (status.equals(KewApiConstants.ROUTE_HEADER_PROCESSED_CD)) {
966 List<PurApItem> items = poa.getItems();
967 for (PurApItem item : items) {
968 initiateTransmission(poa, item);
969 }
970
971 }
972
973 }
974
975
976
977
978
979
980
981
982 @Override
983 public void updateVendorCommodityCode(PurchaseOrderDocument po) {
984 String noteText = "";
985 VendorDetail oldVendorDetail = po.getVendorDetail();
986 VendorDetail newVendorDetail = updateVendorWithMissingCommodityCodesIfNecessary(po);
987 if (newVendorDetail != null) {
988 try {
989
990 MaintenanceDocument vendorMaintDoc = null;
991 try {
992 vendorMaintDoc = (MaintenanceDocument) documentService.getNewDocument("PVEN");
993 vendorMaintDoc.getDocumentHeader().setDocumentDescription("Automatically spawned from PO");
994 vendorMaintDoc.getOldMaintainableObject().setBusinessObject(oldVendorDetail);
995 vendorMaintDoc.getNewMaintainableObject().setBusinessObject(newVendorDetail);
996 vendorMaintDoc.getNewMaintainableObject().setMaintenanceAction(OLEConstants.MAINTENANCE_EDIT_ACTION);
997 vendorMaintDoc.getNewMaintainableObject().setDocumentNumber(vendorMaintDoc.getDocumentNumber());
998 boolean isVendorLocked = checkForLockingDocument(vendorMaintDoc);
999 if (!isVendorLocked) {
1000
1001
1002 vendorMaintDoc.validateBusinessRules(new RouteDocumentEvent(vendorMaintDoc));
1003 addNoteForCommodityCodeToVendor(vendorMaintDoc.getNewMaintainableObject(), vendorMaintDoc.getDocumentNumber(), po.getPurapDocumentIdentifier());
1004 documentService.routeDocument(vendorMaintDoc, null, null);
1005 } else {
1006
1007 noteText = "Unable to automatically update vendor because it is locked";
1008 }
1009 } catch (Exception e) {
1010 if (ObjectUtils.isNull(vendorMaintDoc)) {
1011 noteText = "Unable to create a new VendorDetailMaintenanceDocument to update the vendor with new commodity codes";
1012 } else {
1013 noteText = "Unable to route a new VendorDetailMaintenanceDocument to update the vendor with new commodity codes";
1014 }
1015 } finally {
1016 if (StringUtils.isNotBlank(noteText)) {
1017
1018 Note note = documentService.createNoteFromDocument(po, noteText);
1019 po.addNote(note);
1020 noteService.save(note);
1021 }
1022 }
1023 } catch (Exception e) {
1024 LOG.error("updateVendorCommodityCode() unable to add a note(" + noteText + ") to PO document " + po.getDocumentNumber());
1025 throw new RuntimeException(e);
1026 }
1027 }
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 protected void addNoteForCommodityCodeToVendor(Maintainable maintainable, String documentNumber, Integer poID) {
1038 Note newBONote = new Note();
1039 newBONote.setNoteText("Change vendor document ID <" + documentNumber + ">. Document was automatically created from PO <" + poID + "> to add commodity codes used on this PO that were not yet assigned to this vendor.");
1040 try {
1041
1042 newBONote = noteService.createNote(newBONote, maintainable.getBusinessObject(), GlobalVariables.getUserSession().getPrincipalId());
1043 newBONote.setNotePostedTimestampToCurrent();
1044 } catch (Exception e) {
1045 throw new RuntimeException("Caught Exception While Trying To Add Note to Vendor", e);
1046 }
1047 List<Note> noteList = noteService.getByRemoteObjectId(maintainable.getBusinessObject().getObjectId());
1048 noteList.add(newBONote);
1049 noteService.saveNoteList(noteList);
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 protected boolean checkForLockingDocument(MaintenanceDocument document) {
1059 String blockingDocId = maintenanceDocumentService.getLockingDocumentId(document);
1060 if (StringUtils.isBlank(blockingDocId)) {
1061 return false;
1062 } else {
1063 return true;
1064 }
1065 }
1066
1067
1068
1069
1070 @Override
1071 public VendorDetail updateVendorWithMissingCommodityCodesIfNecessary(PurchaseOrderDocument po) {
1072 List<CommodityCode> result = new ArrayList<CommodityCode>();
1073 boolean foundDefault = false;
1074 VendorDetail vendor = (VendorDetail) ObjectUtils.deepCopy(po.getVendorDetail());
1075 for (PurchaseOrderItem item : (List<PurchaseOrderItem>) po.getItems()) {
1076
1077 if (item.getItemType().isLineItemIndicator() && item.isItemActiveIndicator()) {
1078 CommodityCode cc = item.getCommodityCode();
1079 if (cc != null && !result.contains(cc)) {
1080 List<VendorCommodityCode> vendorCommodityCodes = po.getVendorDetail().getVendorCommodities();
1081 boolean foundMatching = false;
1082 for (VendorCommodityCode vcc : vendorCommodityCodes) {
1083 if (vcc.getCommodityCode().getPurchasingCommodityCode().equals(cc.getPurchasingCommodityCode())) {
1084 foundMatching = true;
1085 }
1086 if (!foundDefault && vcc.isCommodityDefaultIndicator()) {
1087 foundDefault = true;
1088 }
1089 }
1090 if (!foundMatching) {
1091 result.add(cc);
1092 VendorCommodityCode vcc = new VendorCommodityCode(vendor.getVendorHeaderGeneratedIdentifier(), vendor.getVendorDetailAssignedIdentifier(), cc, true);
1093 vcc.setActive(true);
1094 if (!foundDefault) {
1095 vcc.setCommodityDefaultIndicator(true);
1096 foundDefault = true;
1097 }
1098 vendor.getVendorCommodities().add(vcc);
1099 }
1100 }
1101 }
1102 }
1103 if (result.size() > 0) {
1104
1105
1106 for (int i = 0; i < result.size(); i++) {
1107 po.getVendorDetail().getVendorCommodities().add(new VendorCommodityCode());
1108 }
1109 return vendor;
1110 } else {
1111 return null;
1112 }
1113 }
1114
1115
1116
1117
1118
1119
1120 protected void setupDocumentForPendingFirstTransmission(PurchaseOrderDocument po) {
1121 if (POTransmissionMethods.PRINT.equals(po.getPurchaseOrderTransmissionMethodCode()) || POTransmissionMethods.FAX.equals(po.getPurchaseOrderTransmissionMethodCode()) || POTransmissionMethods.ELECTRONIC.equals(po.getPurchaseOrderTransmissionMethodCode())) {
1122 String newStatusCode = PurchaseOrderStatuses.STATUSES_BY_TRANSMISSION_TYPE.get(po.getPurchaseOrderTransmissionMethodCode());
1123 if (LOG.isDebugEnabled()) {
1124 LOG.debug("setupDocumentForPendingFirstTransmission() Purchase Order Transmission Type is '" + po.getPurchaseOrderTransmissionMethodCode() + "' setting status to '" + newStatusCode + "'");
1125 }
1126 try {
1127 po.updateAndSaveAppDocStatus(newStatusCode);
1128 } catch (WorkflowException e) {
1129 throw new RuntimeException("Error saving routing data while saving document with id " + po.getDocumentNumber(), e);
1130 }
1131 }
1132 }
1133
1134
1135
1136
1137
1138
1139
1140 protected void attemptSetupOfInitialOpenOfDocument(PurchaseOrderDocument po) {
1141 if (LOG.isInfoEnabled()) {
1142 LOG.info("attemptSetupOfInitialOpenOfDocument() started using document with doc id " + po.getDocumentNumber());
1143 }
1144
1145 if (!PurchaseOrderStatuses.APPDOC_OPEN.equals(po.getApplicationDocumentStatus())) {
1146 if (ObjectUtils.isNull(po.getPurchaseOrderInitialOpenTimestamp())) {
1147 LOG.debug("attemptSetupOfInitialOpenOfDocument() setting initial open date on document");
1148 po.setPurchaseOrderInitialOpenTimestamp(dateTimeService.getCurrentTimestamp());
1149 } else {
1150 throw new RuntimeException("Document does not have status code '" + PurchaseOrderStatuses.APPDOC_OPEN + "' on it but value of initial open date is " + po.getPurchaseOrderInitialOpenTimestamp());
1151 }
1152 LOG.info("attemptSetupOfInitialOpenOfDocument() Setting po document id " + po.getDocumentNumber() + " status from '" + po.getApplicationDocumentStatus() + "' to '" + PurchaseOrderStatuses.APPDOC_OPEN + "'");
1153 try {
1154 po.updateAndSaveAppDocStatus(PurchaseOrderStatuses.APPDOC_OPEN);
1155 } catch (WorkflowException we) {
1156 throw new RuntimeException("Unable to load a WorkflowDocument object for " + po.getDocumentNumber(), we);
1157 }
1158 po.setApplicationDocumentStatus(PurchaseOrderStatuses.APPDOC_OPEN);
1159
1160 }
1161
1162
1163
1164
1165
1166 }
1167
1168
1169
1170
1171 @Override
1172 public PurchaseOrderDocument getCurrentPurchaseOrder(Integer id) {
1173 return getPurchaseOrderByDocumentNumber(purchaseOrderDao.getDocumentNumberForCurrentPurchaseOrder(id));
1174
1175
1176 }
1177
1178
1179
1180
1181 @Override
1182 public PurchaseOrderDocument getPurchaseOrderByDocumentNumber(String documentNumber) {
1183 if (ObjectUtils.isNotNull(documentNumber)) {
1184 try {
1185 PurchaseOrderDocument doc = (PurchaseOrderDocument) documentService.getByDocumentHeaderId(documentNumber);
1186 if (ObjectUtils.isNotNull(doc)) {
1187 WorkflowDocument workflowDocument = doc.getDocumentHeader().getWorkflowDocument();
1188 doc.refreshReferenceObject(OLEPropertyConstants.DOCUMENT_HEADER);
1189 doc.getDocumentHeader().setWorkflowDocument(workflowDocument);
1190 }
1191 return doc;
1192 } catch (WorkflowException e) {
1193 String errorMessage = "Error getting purchase order document from document service";
1194 LOG.error("getPurchaseOrderByDocumentNumber() " + errorMessage, e);
1195 throw new RuntimeException(errorMessage, e);
1196 }
1197 }
1198 return null;
1199 }
1200
1201
1202
1203
1204
1205 @Override
1206 public PurchaseOrderDocument getOldestPurchaseOrder(PurchaseOrderDocument po, PurchaseOrderDocument documentBusinessObject) {
1207 LOG.debug("entering getOldestPO(PurchaseOrderDocument)");
1208 if (ObjectUtils.isNotNull(po)) {
1209 String oldestDocumentNumber = purchaseOrderDao.getOldestPurchaseOrderDocumentNumber(po.getPurapDocumentIdentifier());
1210
1211 if (StringUtils.isBlank(oldestDocumentNumber)) {
1212 return null;
1213 }
1214 if (StringUtils.equals(oldestDocumentNumber, po.getDocumentNumber())) {
1215
1216
1217 updateNotes(po, documentBusinessObject);
1218 LOG.debug("exiting getOldestPO(PurchaseOrderDocument)");
1219 return po;
1220 } else {
1221 PurchaseOrderDocument oldestPurchaseOrder = getPurchaseOrderByDocumentNumber(oldestDocumentNumber);
1222 updateNotes(oldestPurchaseOrder, documentBusinessObject);
1223 LOG.debug("exiting getOldestPO(PurchaseOrderDocument)");
1224 return oldestPurchaseOrder;
1225 }
1226 }
1227 return null;
1228 }
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 protected void updateNotes(PurchaseOrderDocument po, PurchaseOrderDocument documentBusinessObject) {
1241 if (ObjectUtils.isNotNull(documentBusinessObject)) {
1242 if (ObjectUtils.isNotNull(po.getObjectId())) {
1243 List<Note> dbNotes = noteService.getByRemoteObjectId(po.getObjectId());
1244
1245
1246 fixDbNoteFields(documentBusinessObject, dbNotes);
1247 po.setNotes(dbNotes);
1248 } else {
1249 po.setNotes(documentBusinessObject.getNotes());
1250 }
1251 }
1252 }
1253
1254
1255
1256
1257
1258
1259
1260
1261 protected void fixDbNoteFields(PurchaseOrderDocument documentBusinessObject, List<Note> dbNotes) {
1262 for (int i = 0; i < dbNotes.size(); i++) {
1263 Note dbNote = dbNotes.get(i);
1264 List<Note> currentNotes = documentBusinessObject.getNotes();
1265 if (i < currentNotes.size()) {
1266 Note currentNote = (currentNotes).get(i);
1267
1268 AdHocRouteRecipient fyiNoteRecipient = currentNote.getAdHocRouteRecipient();
1269 if (ObjectUtils.isNotNull(fyiNoteRecipient)) {
1270 dbNote.setAdHocRouteRecipient(fyiNoteRecipient);
1271 }
1272 }
1273 }
1274 }
1275
1276
1277
1278
1279 @Override
1280 public List<Note> getPurchaseOrderNotes(Integer id) {
1281 List<Note> notes = new ArrayList<Note>();
1282
1283 PurchaseOrderDocument po = getPurchaseOrderByDocumentNumber(purchaseOrderDao.getOldestPurchaseOrderDocumentNumber(id));
1284 if (ObjectUtils.isNotNull(po)) {
1285 notes = noteService.getByRemoteObjectId(po.getObjectId());
1286 }
1287 return notes;
1288 }
1289
1290
1291
1292
1293 @Override
1294 public void setCurrentAndPendingIndicatorsForApprovedPODocuments(PurchaseOrderDocument newPO) {
1295
1296
1297
1298
1299
1300 PurchaseOrderDocument oldPO = getCurrentPurchaseOrder(newPO.getPurapDocumentIdentifier());
1301
1302 if (oldPO == null) {
1303 return;
1304 }
1305
1306
1307 if (!oldPO.getDocumentNumber().equals(newPO.getDocumentNumber())) {
1308
1309 oldPO.setPurchaseOrderCurrentIndicator(false);
1310 oldPO.setPendingActionIndicator(false);
1311
1312
1313 try {
1314 oldPO.updateAndSaveAppDocStatus(PurapConstants.PurchaseOrderStatuses.APPDOC_RETIRED_VERSION);
1315 } catch (WorkflowException e) {
1316 throw new RuntimeException("Error saving routing data while saving document with id " + oldPO.getDocumentNumber(), e);
1317 }
1318
1319 saveDocumentNoValidationUsingClearMessageMap(oldPO);
1320 }
1321 if (!oldPO.getVendorDetail().getVendorHeaderGeneratedIdentifier().equals(newPO.getVendorDetail().getVendorHeaderGeneratedIdentifier())) {
1322 List<PurApItem> items = oldPO.getItems();
1323 for (PurApItem item : items) {
1324 initiateTransmission(oldPO, item);
1325 }
1326
1327 }
1328
1329 newPO.setPurchaseOrderCurrentIndicator(true);
1330 newPO.setPendingActionIndicator(false);
1331
1332
1333
1334 }
1335
1336
1337
1338
1339 @Override
1340 public void setCurrentAndPendingIndicatorsForDisapprovedChangePODocuments(PurchaseOrderDocument newPO) {
1341 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_DISAPPROVED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN);
1342 }
1343
1344
1345
1346
1347 @Override
1348 public void setCurrentAndPendingIndicatorsForCancelledChangePODocuments(PurchaseOrderDocument newPO) {
1349 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_CANCELLED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN);
1350 }
1351
1352
1353
1354
1355 @Override
1356 public void setCurrentAndPendingIndicatorsForCancelledReopenPODocuments(PurchaseOrderDocument newPO) {
1357 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_CANCELLED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_CLOSED);
1358 }
1359
1360
1361
1362
1363 @Override
1364 public void setCurrentAndPendingIndicatorsForDisapprovedReopenPODocuments(PurchaseOrderDocument newPO) {
1365 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_DISAPPROVED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_CLOSED);
1366 }
1367
1368
1369
1370
1371 @Override
1372 public void setCurrentAndPendingIndicatorsForCancelledRemoveHoldPODocuments(PurchaseOrderDocument newPO) {
1373 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_CANCELLED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_PAYMENT_HOLD);
1374 }
1375
1376
1377
1378
1379 @Override
1380 public void setCurrentAndPendingIndicatorsForDisapprovedRemoveHoldPODocuments(PurchaseOrderDocument newPO) {
1381 updateCurrentDocumentForNoPendingAction(newPO, PurapConstants.PurchaseOrderStatuses.APPDOC_DISAPPROVED_CHANGE, PurapConstants.PurchaseOrderStatuses.APPDOC_PAYMENT_HOLD);
1382 }
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 protected void updateCurrentDocumentForNoPendingAction(PurchaseOrderDocument newPO, String newPOStatus, String oldPOStatus) {
1394
1395 PurchaseOrderDocument oldPO = getCurrentPurchaseOrder(newPO.getPurapDocumentIdentifier());
1396
1397 oldPO.setPendingActionIndicator(false);
1398 try {
1399 oldPO.updateAndSaveAppDocStatus(oldPOStatus);
1400 newPO.updateAndSaveAppDocStatus(newPOStatus);
1401 } catch (WorkflowException e) {
1402 throw new RuntimeException("Error saving routing data while saving document", e);
1403 }
1404
1405
1406 saveDocumentNoValidationUsingClearMessageMap(oldPO);
1407 saveDocumentNoValidationUsingClearMessageMap(newPO);
1408 }
1409
1410 @Override
1411 public List<PurchaseOrderQuoteStatus> getPurchaseOrderQuoteStatusCodes() {
1412 List<PurchaseOrderQuoteStatus> poQuoteStatuses = new ArrayList<PurchaseOrderQuoteStatus>();
1413 poQuoteStatuses = (List<PurchaseOrderQuoteStatus>) businessObjectService.findAll(PurchaseOrderQuoteStatus.class);
1414 return poQuoteStatuses;
1415 }
1416
1417 @Override
1418 public void setReceivingRequiredIndicatorForPurchaseOrder(PurchaseOrderDocument po) {
1419 ThresholdHelper thresholdHelper = new ThresholdHelper(po);
1420 boolean result = thresholdHelper.isReceivingDocumentRequired();
1421 if (result) {
1422 ThresholdSummary thresholdSummary = thresholdHelper.getThresholdSummary();
1423 ReceivingThreshold receivingThreshold = thresholdHelper.getReceivingThreshold();
1424 po.setReceivingDocumentRequiredIndicator(true);
1425
1426 String notetxt = "Receiving is set to be required because the threshold summary with a total amount of " + thresholdSummary.getTotalAmount();
1427 notetxt += " exceeds the receiving threshold of " + receivingThreshold.getThresholdAmount();
1428 notetxt += " with respect to the threshold criteria ";
1429
1430 if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART) {
1431 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1432 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_ACCOUNTTYPE) {
1433 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1434 notetxt += " - Account Type " + receivingThreshold.getAccountTypeCode();
1435 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_SUBFUND) {
1436 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1437 notetxt += " - Sub-Fund " + receivingThreshold.getSubFundGroupCode();
1438 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_COMMODITYCODE) {
1439 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1440 notetxt += " - Commodity Code " + receivingThreshold.getPurchasingCommodityCode();
1441 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_OBJECTCODE) {
1442 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1443 notetxt += " - Object code " + receivingThreshold.getFinancialObjectCode();
1444 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_ORGANIZATIONCODE) {
1445 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1446 notetxt += " - Organization " + receivingThreshold.getOrganizationCode();
1447 } else if (thresholdSummary.getThresholdCriteria() == ThresholdHelper.CHART_AND_VENDOR) {
1448 notetxt += " Chart " + receivingThreshold.getChartOfAccountsCode();
1449 notetxt += " - Vendor " + receivingThreshold.getVendorNumber();
1450 }
1451
1452 try {
1453 Note note = documentService.createNoteFromDocument(po, notetxt);
1454
1455 noteService.save(note);
1456 } catch (Exception e) {
1457 throw new RuntimeException(e);
1458 }
1459 }
1460 }
1461
1462
1463
1464
1465 @Override
1466 public boolean hasNewUnorderedItem(PurchaseOrderDocument po) {
1467
1468 boolean itemAdded = false;
1469
1470 for (PurchaseOrderItem poItem : (List<PurchaseOrderItem>) po.getItems()) {
1471
1472 if (poItem.isItemActiveIndicator() && poItem.getItemType().isLineItemIndicator() && PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(poItem.getItemTypeCode())) {
1473
1474
1475 if (poItem.getItemIdentifier() == null || !purchaseOrderDao.itemExistsOnPurchaseOrder(poItem.getItemLineNumber(), purchaseOrderDao.getDocumentNumberForCurrentPurchaseOrder(po.getPurapDocumentIdentifier()))) {
1476 itemAdded = true;
1477 break;
1478 }
1479 }
1480 }
1481
1482 return itemAdded;
1483 }
1484
1485 @Override
1486 public boolean isNewUnorderedItem(PurchaseOrderItem poItem) {
1487
1488 boolean itemAdded = false;
1489
1490
1491 if (poItem.isItemActiveIndicator() && poItem.getItemType().isLineItemIndicator() && PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(poItem.getItemTypeCode())) {
1492
1493
1494 if (poItem.getItemIdentifier() == null || !purchaseOrderDao.itemExistsOnPurchaseOrder(poItem.getItemLineNumber(), purchaseOrderDao.getDocumentNumberForCurrentPurchaseOrder(poItem.getPurchaseOrder().getPurapDocumentIdentifier()))) {
1495 itemAdded = true;
1496 }
1497 }
1498
1499 return itemAdded;
1500 }
1501
1502 @Override
1503 public boolean isNewItemForAmendment(PurchaseOrderItem poItem) {
1504
1505 boolean itemAdded = false;
1506
1507
1508 if (poItem.isItemActiveIndicator() && poItem.getItemType().isLineItemIndicator()) {
1509
1510
1511 if (poItem.getItemIdentifier() == null || !purchaseOrderDao.itemExistsOnPurchaseOrder(poItem.getItemLineNumber(), purchaseOrderDao.getDocumentNumberForCurrentPurchaseOrder(poItem.getPurchaseOrder().getPurapDocumentIdentifier()))) {
1512 itemAdded = true;
1513 }
1514 }
1515
1516 return itemAdded;
1517 }
1518
1519
1520
1521
1522
1523
1524 protected void sendFyiForNewUnorderedItems(PurchaseOrderDocument po) {
1525
1526 List<AdHocRoutePerson> fyiList = createFyiFiscalOfficerListForNewUnorderedItems(po);
1527 String annotation = "Notification of New Unordered Items for Purchase Order" + po.getPurapDocumentIdentifier() + "(document id " + po.getDocumentNumber() + ")";
1528 String responsibilityNote = "Purchase Order Amendment Routed By User";
1529
1530 for (AdHocRoutePerson adHocPerson : fyiList) {
1531 try {
1532 po.appSpecificRouteDocumentToUser(
1533 po.getDocumentHeader().getWorkflowDocument(),
1534 adHocPerson.getPerson().getPrincipalId(),
1535 annotation,
1536 responsibilityNote);
1537 } catch (WorkflowException e) {
1538 throw new RuntimeException("Error routing fyi for document with id " + po.getDocumentNumber(), e);
1539 }
1540
1541 }
1542 }
1543
1544
1545
1546
1547
1548
1549
1550 protected List<AdHocRoutePerson> createFyiFiscalOfficerListForNewUnorderedItems(PurchaseOrderDocument po) {
1551
1552 List<AdHocRoutePerson> adHocRoutePersons = new ArrayList<AdHocRoutePerson>();
1553 Map fiscalOfficers = new HashMap();
1554 AdHocRoutePerson adHocRoutePerson = null;
1555
1556 for (PurchaseOrderItem poItem : (List<PurchaseOrderItem>) po.getItems()) {
1557
1558 if (poItem.isItemActiveIndicator() && poItem.getItemType().isLineItemIndicator() && PurapConstants.ItemTypeCodes.ITEM_TYPE_UNORDERED_ITEM_CODE.equals(poItem.getItemTypeCode())) {
1559
1560
1561 if (poItem.getItemIdentifier() == null || !purchaseOrderDao.itemExistsOnPurchaseOrder(poItem.getItemLineNumber(), purchaseOrderDao.getDocumentNumberForCurrentPurchaseOrder(po.getPurapDocumentIdentifier()))) {
1562
1563
1564 for (PurApAccountingLine account : poItem.getSourceAccountingLines()) {
1565
1566
1567 if (fiscalOfficers.containsKey(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName()) == false) {
1568
1569
1570 fiscalOfficers.put(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName(), account.getAccount().getAccountFiscalOfficerUser().getPrincipalName());
1571
1572
1573 adHocRoutePerson = new AdHocRoutePerson();
1574 adHocRoutePerson.setId(account.getAccount().getAccountFiscalOfficerUser().getPrincipalName());
1575 adHocRoutePerson.setActionRequested(OLEConstants.WORKFLOW_FYI_REQUEST);
1576 adHocRoutePersons.add(adHocRoutePerson);
1577 }
1578 }
1579 }
1580 }
1581 }
1582
1583 return adHocRoutePersons;
1584 }
1585
1586
1587
1588
1589
1590
1591 @Override
1592 public void sendFyiForGLEntries(PurchaseOrderDocument po) {
1593
1594 List<AdHocRoutePerson> fyiList = createFyiFiscalOfficerListForAmendGlEntries(po);
1595 String annotation = "Amendment to Purchase Order " + po.getPurapDocumentIdentifier() + "( Document id " + po.getDocumentNumber() + ")" +
1596 " resulted in the generation of Pending General Ledger Entries.";
1597 String responsibilityNote = "Purchase Order Amendment Routed By User";
1598
1599 for (AdHocRoutePerson adHocPerson : fyiList) {
1600 try {
1601 po.appSpecificRouteDocumentToUser(
1602 po.getDocumentHeader().getWorkflowDocument(),
1603 adHocPerson.getPerson().getPrincipalId(),
1604 annotation,
1605 responsibilityNote);
1606 } catch (WorkflowException e) {
1607 throw new RuntimeException("Error routing fyi for document with id " + po.getDocumentNumber(), e);
1608 }
1609
1610 }
1611 }
1612
1613
1614
1615
1616
1617
1618
1619 protected List<AdHocRoutePerson> createFyiFiscalOfficerListForAmendGlEntries(PurchaseOrderDocument po) {
1620
1621 List<AdHocRoutePerson> adHocRoutePersons = new ArrayList<AdHocRoutePerson>();
1622 Map fiscalOfficers = new HashMap();
1623 AdHocRoutePerson adHocRoutePerson = null;
1624
1625 for (SourceAccountingLine account : po.getGlOnlySourceAccountingLines()) {
1626
1627
1628
1629 Account acct = SpringContext.getBean(AccountService.class).getByPrimaryId(account.getChartOfAccountsCode(),
1630 account.getAccountNumber());
1631 String principalName = acct.getAccountFiscalOfficerUser().getPrincipalName();
1632
1633 if (fiscalOfficers.containsKey(principalName) == false) {
1634
1635 fiscalOfficers.put(principalName, principalName);
1636
1637 adHocRoutePerson = new AdHocRoutePerson();
1638 adHocRoutePerson.setId(principalName);
1639 adHocRoutePerson.setActionRequested(KewApiConstants.ACTION_REQUEST_FYI_REQ);
1640 adHocRoutePersons.add(adHocRoutePerson);
1641 }
1642
1643 }
1644
1645 return adHocRoutePersons;
1646 }
1647
1648
1649
1650
1651 @Override
1652 public HashMap<String, List<PurchaseOrderItem>> categorizeItemsForSplit(List<PurchaseOrderItem> items) {
1653 HashMap<String, List<PurchaseOrderItem>> movingOrNot = new HashMap<String, List<PurchaseOrderItem>>(3);
1654 List<PurchaseOrderItem> movingPOItems = new ArrayList<PurchaseOrderItem>();
1655 List<PurchaseOrderItem> remainingPOItems = new ArrayList<PurchaseOrderItem>();
1656 List<PurchaseOrderItem> remainingPOLineItems = new ArrayList<PurchaseOrderItem>();
1657 for (PurchaseOrderItem item : items) {
1658 if (item.isMovingToSplit()) {
1659 movingPOItems.add(item);
1660 } else {
1661 remainingPOItems.add(item);
1662 if (item.getItemType().isLineItemIndicator()) {
1663 remainingPOLineItems.add(item);
1664 }
1665 }
1666 }
1667 movingOrNot.put(PODocumentsStrings.ITEMS_MOVING_TO_SPLIT, movingPOItems);
1668 movingOrNot.put(PODocumentsStrings.ITEMS_REMAINING, remainingPOItems);
1669 movingOrNot.put(PODocumentsStrings.LINE_ITEMS_REMAINING, remainingPOLineItems);
1670 return movingOrNot;
1671 }
1672
1673
1674
1675
1676
1677 @Override
1678 public PurchaseOrderVendorQuote populateQuoteWithVendor(Integer headerId, Integer detailId, String documentNumber) {
1679 VendorDetail vendor = vendorService.getVendorDetail(headerId, detailId);
1680 updateDefaultVendorAddress(vendor);
1681 PurchaseOrderVendorQuote newPOVendorQuote = populateAddressForPOVendorQuote(vendor, documentNumber);
1682
1683
1684
1685
1686 for (VendorPhoneNumber phone : vendor.getVendorPhoneNumbers()) {
1687 if (VendorConstants.PhoneTypes.PHONE.equals(phone.getVendorPhoneTypeCode())) {
1688 newPOVendorQuote.setVendorPhoneNumber(phone.getVendorPhoneNumber());
1689 break;
1690 }
1691 }
1692
1693 return newPOVendorQuote;
1694 }
1695
1696
1697
1698
1699
1700
1701
1702
1703 protected PurchaseOrderVendorQuote populateAddressForPOVendorQuote(VendorDetail newVendor, String documentNumber) {
1704 PurchaseOrderVendorQuote newPOVendorQuote = new PurchaseOrderVendorQuote();
1705 newPOVendorQuote.setVendorName(newVendor.getVendorName());
1706 newPOVendorQuote.setVendorHeaderGeneratedIdentifier(newVendor.getVendorHeaderGeneratedIdentifier());
1707 newPOVendorQuote.setVendorDetailAssignedIdentifier(newVendor.getVendorDetailAssignedIdentifier());
1708 newPOVendorQuote.setDocumentNumber(documentNumber);
1709 boolean foundAddress = false;
1710 for (VendorAddress address : newVendor.getVendorAddresses()) {
1711 if (AddressTypes.QUOTE.equals(address.getVendorAddressTypeCode())) {
1712 newPOVendorQuote.setVendorCityName(address.getVendorCityName());
1713 newPOVendorQuote.setVendorCountryCode(address.getVendorCountryCode());
1714 newPOVendorQuote.setVendorLine1Address(address.getVendorLine1Address());
1715 newPOVendorQuote.setVendorLine2Address(address.getVendorLine2Address());
1716 newPOVendorQuote.setVendorPostalCode(address.getVendorZipCode());
1717 newPOVendorQuote.setVendorStateCode(address.getVendorStateCode());
1718 newPOVendorQuote.setVendorFaxNumber(address.getVendorFaxNumber());
1719 foundAddress = true;
1720 break;
1721 }
1722 }
1723 if (!foundAddress) {
1724 newPOVendorQuote.setVendorCityName(newVendor.getDefaultAddressCity());
1725 newPOVendorQuote.setVendorCountryCode(newVendor.getDefaultAddressCountryCode());
1726 newPOVendorQuote.setVendorLine1Address(newVendor.getDefaultAddressLine1());
1727 newPOVendorQuote.setVendorLine2Address(newVendor.getDefaultAddressLine2());
1728 newPOVendorQuote.setVendorPostalCode(newVendor.getDefaultAddressPostalCode());
1729 newPOVendorQuote.setVendorStateCode(newVendor.getDefaultAddressStateCode());
1730 newPOVendorQuote.setVendorFaxNumber(newVendor.getDefaultFaxNumber());
1731 }
1732 return newPOVendorQuote;
1733 }
1734
1735
1736
1737
1738
1739
1740 protected void updateDefaultVendorAddress(VendorDetail vendor) {
1741 VendorAddress defaultAddress = vendorService.getVendorDefaultAddress(vendor.getVendorAddresses(), vendor.getVendorHeader().getVendorType().getAddressType().getVendorAddressTypeCode(), "");
1742 if (defaultAddress != null) {
1743 if (defaultAddress.getVendorState() != null) {
1744 vendor.setVendorStateForLookup(defaultAddress.getVendorState().getName());
1745 }
1746 vendor.setDefaultAddressLine1(defaultAddress.getVendorLine1Address());
1747 vendor.setDefaultAddressLine2(defaultAddress.getVendorLine2Address());
1748 vendor.setDefaultAddressCity(defaultAddress.getVendorCityName());
1749 vendor.setDefaultAddressPostalCode(defaultAddress.getVendorZipCode());
1750 vendor.setDefaultAddressStateCode(defaultAddress.getVendorStateCode());
1751 vendor.setDefaultAddressInternationalProvince(defaultAddress.getVendorAddressInternationalProvinceName());
1752 vendor.setDefaultAddressCountryCode(defaultAddress.getVendorCountryCode());
1753 vendor.setDefaultFaxNumber(defaultAddress.getVendorFaxNumber());
1754 }
1755 }
1756
1757
1758
1759
1760 @Override
1761 public void processACMReq(ContractManagerAssignmentDocument acmDoc) {
1762 List<ContractManagerAssignmentDetail> acmDetails = acmDoc.getContractManagerAssignmentDetails();
1763 for (Object element : acmDetails) {
1764 ContractManagerAssignmentDetail detail = (ContractManagerAssignmentDetail) element;
1765
1766 if (ObjectUtils.isNotNull(detail.getContractManagerCode())) {
1767
1768 RequisitionDocument req = requisitionService.getRequisitionById(detail.getRequisitionIdentifier());
1769
1770 if (PurapConstants.RequisitionStatuses.APPDOC_AWAIT_CONTRACT_MANAGER_ASSGN.equals(req.getApplicationDocumentStatus())) {
1771
1772 try {
1773 req.updateAndSaveAppDocStatus(PurapConstants.RequisitionStatuses.APPDOC_CLOSED);
1774 } catch (WorkflowException e) {
1775 throw new RuntimeException("Error saving routing data while saving document with id " + req.getDocumentNumber(), e);
1776 }
1777
1778 purapService.saveDocumentNoValidation(req);
1779 createPurchaseOrderDocument(req, getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER), detail.getContractManagerCode());
1780 }
1781 }
1782
1783 }
1784 }
1785
1786
1787
1788
1789 @Override
1790 public boolean autoCloseFullyDisencumberedOrders() {
1791 LOG.debug("autoCloseFullyDisencumberedOrders() started");
1792 List<AutoClosePurchaseOrderView> autoCloseList = new ArrayList<AutoClosePurchaseOrderView>();
1793
1794 String autoCloseOrderFromDateString = parameterService.getParameterValueAsString(AutoClosePurchaseOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_PO_FROM_DATE);
1795 String autoCloseOrderToDateString = parameterService.getParameterValueAsString(AutoClosePurchaseOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_PO_TO_DATE);
1796
1797 boolean validFromDate = true;
1798 java.sql.Date autoCloseOrderFromDate = null;
1799 try {
1800 autoCloseOrderFromDate = dateTimeService.convertToSqlDate(autoCloseOrderFromDateString);
1801 } catch (Exception e) {
1802 autoCloseOrderFromDate = null;
1803 }
1804
1805 boolean validToDate = true;
1806 java.sql.Date autoCloseOrderToDate = null;
1807 try {
1808 autoCloseOrderToDate = dateTimeService.convertToSqlDate(autoCloseOrderToDateString);
1809
1810 } catch (Exception e) {
1811 autoCloseOrderToDate = null;
1812 }
1813
1814
1815 autoCloseList = purchaseOrderDao.getAllOpenPurchaseOrders(getExcludedVendorChoiceCodes(), autoCloseOrderFromDate, autoCloseOrderToDate);
1816
1817
1818
1819 List<AutoClosePurchaseOrderView> purchaseOrderAutoCloseList = filterDocumentsForAppDocStatusOpen
1820 (autoCloseList);
1821
1822 for (AutoClosePurchaseOrderView poAutoClose : purchaseOrderAutoCloseList) {
1823 if ((poAutoClose.getTotalAmount() != null) && ((KualiDecimal.ZERO.compareTo(poAutoClose.getTotalAmount())) != 0)) {
1824 if (LOG.isDebugEnabled()) {
1825 LOG.debug("autoCloseFullyDisencumberedOrders() PO ID " + poAutoClose.getPurapDocumentIdentifier() + " with total " + poAutoClose.getTotalAmount().doubleValue() + " will be closed");
1826 }
1827 String newStatus = PurapConstants.PurchaseOrderStatuses.APPDOC_PENDING_CLOSE;
1828 String annotation = "This PO was automatically closed in batch.";
1829 String documentType = PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT;
1830 PurchaseOrderDocument document = getPurchaseOrderByDocumentNumber(poAutoClose.getDocumentNumber());
1831 createNoteForAutoCloseOrders(document, annotation);
1832 createAndRoutePotentialChangeDocument(poAutoClose.getDocumentNumber(), documentType, annotation, null, newStatus);
1833 }
1834
1835 }
1836 LOG.debug("autoCloseFullyDisencumberedOrders() ended");
1837
1838 resetAutoClosePurchaseOrderDateParameter();
1839 return true;
1840 }
1841
1842
1843
1844
1845 @Override
1846 public boolean autoCloseRecurringOrders() {
1847 LOG.debug("autoCloseRecurringOrders() started");
1848 boolean shouldSendEmail = true;
1849 MailMessage message = new MailMessage();
1850 String parameterEmail = parameterService.getParameterValueAsString(AutoCloseRecurringOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_RECURRING_PO_TO_EMAIL_ADDRESSES);
1851
1852 if (StringUtils.isEmpty(parameterEmail)) {
1853
1854 LOG.warn("autoCloseRecurringOrders(): parameterEmail is missing, we'll not send out any emails for this job.");
1855 shouldSendEmail = false;
1856 }
1857 if (shouldSendEmail) {
1858 message = setMessageAddressesAndSubject(message, parameterEmail);
1859 }
1860 StringBuffer emailBody = new StringBuffer();
1861
1862
1863 String recurringOrderDateString = parameterService.getParameterValueAsString(AutoCloseRecurringOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_RECURRING_PO_DATE);
1864 boolean validDate = true;
1865 java.util.Date recurringOrderDate = null;
1866 try {
1867 recurringOrderDate = dateTimeService.convertToDate(recurringOrderDateString);
1868 } catch (ParseException pe) {
1869 validDate = false;
1870 }
1871 if (StringUtils.isEmpty(recurringOrderDateString) || recurringOrderDateString.equalsIgnoreCase("mm/dd/yyyy") || (!validDate)) {
1872 if (recurringOrderDateString.equalsIgnoreCase("mm/dd/yyyy")) {
1873 LOG.debug("autoCloseRecurringOrders(): mm/dd/yyyy " + "was found in the Application Settings table. No orders will be closed, method will end.");
1874 if (shouldSendEmail) {
1875 emailBody.append("The AUTO_CLOSE_RECURRING_ORDER_DT found in the Application Settings table " + "was mm/dd/yyyy. No recurring PO's were closed.");
1876 }
1877 } else {
1878 if (LOG.isDebugEnabled()) {
1879 LOG.debug("autoCloseRecurringOrders(): An invalid autoCloseRecurringOrdersDate " + "was found in the Application Settings table: " + recurringOrderDateString + ". Method will end.");
1880 }
1881 if (shouldSendEmail) {
1882 emailBody.append("An invalid AUTO_CLOSE_RECURRING_ORDER_DT was found in the Application Settings table: " + recurringOrderDateString + ". No recurring PO's were closed.");
1883 }
1884 }
1885 if (shouldSendEmail) {
1886 sendMessage(message, emailBody.toString());
1887 }
1888 LOG.debug("autoCloseRecurringOrders() ended");
1889
1890 return false;
1891 }
1892 if (LOG.isDebugEnabled()) {
1893 LOG.debug("autoCloseRecurringOrders() The autoCloseRecurringOrdersDate found in the Application Settings table was " + recurringOrderDateString);
1894 }
1895 if (shouldSendEmail) {
1896 emailBody.append("The autoCloseRecurringOrdersDate found in the Application Settings table was " + recurringOrderDateString + ".");
1897 }
1898 Calendar appSettingsDate = dateTimeService.getCalendar(recurringOrderDate);
1899 Timestamp appSettingsDay = new Timestamp(appSettingsDate.getTime().getTime());
1900
1901 Calendar todayMinusThreeMonths = getTodayMinusThreeMonths();
1902 Timestamp threeMonthsAgo = new Timestamp(todayMinusThreeMonths.getTime().getTime());
1903
1904 if (appSettingsDate.after(todayMinusThreeMonths)) {
1905 if (LOG.isDebugEnabled()) {
1906 LOG.debug("autoCloseRecurringOrders() The appSettingsDate: " + appSettingsDay + " is after todayMinusThreeMonths: " + threeMonthsAgo + ". The program will end.");
1907 }
1908 if (shouldSendEmail) {
1909 emailBody.append("\n\nThe autoCloseRecurringOrdersDate: " + appSettingsDay + " is after todayMinusThreeMonths: " + threeMonthsAgo + ". The program will end.");
1910 sendMessage(message, emailBody.toString());
1911 }
1912 LOG.debug("autoCloseRecurringOrders() ended");
1913
1914 return false;
1915 }
1916
1917 List<AutoClosePurchaseOrderView> closeList = purchaseOrderDao.getAutoCloseRecurringPurchaseOrders(getExcludedVendorChoiceCodes());
1918
1919
1920
1921 List<AutoClosePurchaseOrderView> purchaseOrderAutoCloseList = filterDocumentsForAppDocStatusOpen(closeList);
1922
1923 LOG.info("autoCloseRecurringOrders(): " + purchaseOrderAutoCloseList.size() + " PO's were returned for processing.");
1924 int counter = 0;
1925 for (AutoClosePurchaseOrderView poAutoClose : purchaseOrderAutoCloseList) {
1926 if (LOG.isDebugEnabled()) {
1927 LOG.debug("autoCloseRecurringOrders(): Testing PO ID " + poAutoClose.getPurapDocumentIdentifier() + ". recurringPaymentEndDate: " + poAutoClose.getRecurringPaymentEndDate());
1928 }
1929 if (poAutoClose.getRecurringPaymentEndDate().before(threeMonthsAgo)) {
1930 String newStatus = PurapConstants.PurchaseOrderStatuses.APPDOC_PENDING_CLOSE;
1931 String annotation = "This recurring PO was automatically closed in batch.";
1932 String documentType = PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT;
1933 PurchaseOrderDocument document = getPurchaseOrderByDocumentNumber(poAutoClose.getDocumentNumber());
1934 boolean rulePassed = kualiRuleService.applyRules(new AttributedRouteDocumentEvent("", document));
1935
1936 boolean success = true;
1937 if (success) {
1938 ++counter;
1939 if (counter == 1) {
1940 emailBody.append("\n\nThe following recurring Purchase Orders will be closed by auto close recurring batch job \n");
1941 }
1942 if (LOG.isDebugEnabled()) {
1943 LOG.debug("autoCloseRecurringOrders() PO ID " + poAutoClose.getPurapDocumentIdentifier() + " will be closed.");
1944 }
1945 createNoteForAutoCloseOrders(document, annotation);
1946 createAndRoutePotentialChangeDocument(poAutoClose.getDocumentNumber(), documentType, annotation, null, newStatus);
1947 if (shouldSendEmail) {
1948 emailBody.append("\n\n" + counter + " PO ID: " + poAutoClose.getPurapDocumentIdentifier() + ", End Date: " + poAutoClose.getRecurringPaymentEndDate() + ", Status: " + poAutoClose.getApplicationDocumentStatus() + ", VendorChoice: " + poAutoClose.getVendorChoiceCode() + ", RecurringPaymentType: " + poAutoClose.getRecurringPaymentTypeCode());
1949 }
1950 } else {
1951
1952
1953 GlobalVariables.getMessageMap().clearErrorMessages();
1954 }
1955 }
1956 }
1957 if (counter == 0) {
1958 LOG.debug("\n\nNo recurring PO's fit the conditions for closing.");
1959 if (shouldSendEmail) {
1960 emailBody.append("\n\nNo recurring PO's fit the conditions for closing.");
1961 }
1962 }
1963 if (shouldSendEmail) {
1964 sendMessage(message, emailBody.toString());
1965 }
1966 resetAutoCloseRecurringOrderDateParameter();
1967 LOG.debug("autoCloseRecurringOrders() ended");
1968
1969 return true;
1970 }
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981 protected List<AutoClosePurchaseOrderView> filterDocumentsForAppDocStatusOpen(List<AutoClosePurchaseOrderView> autoClosePurchaseOrderViews) {
1982 List<AutoClosePurchaseOrderView> filteredAutoClosePOView = new ArrayList<AutoClosePurchaseOrderView>();
1983
1984 for (AutoClosePurchaseOrderView autoClosePurchaseOrderView : autoClosePurchaseOrderViews) {
1985 Document document = findDocument(autoClosePurchaseOrderView.getDocumentNumber());
1986
1987 if (document != null) {
1988 if (PurapConstants.PurchaseOrderStatuses.APPDOC_OPEN.equalsIgnoreCase(
1989 document.getDocumentHeader().getWorkflowDocument().getApplicationDocumentStatus())) {
1990
1991 filteredAutoClosePOView.add(autoClosePurchaseOrderView);
1992 }
1993 }
1994 }
1995
1996 return filteredAutoClosePOView;
1997 }
1998
1999
2000
2001
2002
2003
2004
2005 protected Document findDocument(String documentHeaderId) {
2006 Document document = null;
2007
2008 try {
2009 document = documentService.getByDocumentHeaderId(documentHeaderId);
2010 } catch (WorkflowException ex) {
2011 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex);
2012 } catch (UnknownDocumentTypeException ex) {
2013
2014 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex);
2015 }
2016
2017 return document;
2018 }
2019
2020
2021
2022
2023
2024
2025
2026 protected Calendar getTodayMinusThreeMonths() {
2027 Calendar todayMinusThreeMonths = Calendar.getInstance();
2028 todayMinusThreeMonths.add(Calendar.MONTH, -3);
2029 todayMinusThreeMonths.set(Calendar.HOUR, 12);
2030 todayMinusThreeMonths.set(Calendar.MINUTE, 0);
2031 todayMinusThreeMonths.set(Calendar.SECOND, 0);
2032 todayMinusThreeMonths.set(Calendar.MILLISECOND, 0);
2033 todayMinusThreeMonths.set(Calendar.AM_PM, Calendar.AM);
2034 return todayMinusThreeMonths;
2035 }
2036
2037
2038
2039
2040
2041
2042
2043
2044 protected MailMessage setMessageAddressesAndSubject(MailMessage message, String parameterEmail) {
2045 String toAddressList[] = parameterEmail.split(";");
2046
2047 if (toAddressList.length > 0) {
2048 for (String element : toAddressList) {
2049 if (element != null) {
2050 message.addToAddress(element.trim());
2051 }
2052 }
2053 }
2054
2055 message.setFromAddress(toAddressList[0]);
2056 message.setSubject("Auto Close Recurring Purchase Orders");
2057 return message;
2058 }
2059
2060
2061
2062
2063
2064
2065
2066
2067 protected void sendMessage(MailMessage message, String emailBody) {
2068 message.setMessage(emailBody);
2069 try {
2070 mailService.sendMessage(message);
2071 } catch (Exception e) {
2072
2073 LOG.error("autoCloseRecurringOrders(): email problem. Message not sent.", e);
2074 throw new RuntimeException(e);
2075 }
2076 }
2077
2078
2079
2080
2081 protected void resetAutoCloseRecurringOrderDateParameter() {
2082 Parameter autoCloseRecurringPODate = parameterService.getParameter(AutoCloseRecurringOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_RECURRING_PO_DATE);
2083 if (autoCloseRecurringPODate != null) {
2084 Parameter.Builder updatedParameter = Parameter.Builder.create(autoCloseRecurringPODate);
2085 updatedParameter.setValue("mm/dd/yyyy");
2086 parameterService.updateParameter(updatedParameter.build());
2087 }
2088 }
2089
2090
2091
2092
2093 protected void resetAutoClosePurchaseOrderDateParameter() {
2094 Parameter autoClosePOFromDate = parameterService.getParameter(AutoClosePurchaseOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_PO_FROM_DATE);
2095 Parameter autoClosePOToDate = parameterService.getParameter(AutoClosePurchaseOrdersStep.class, PurapParameterConstants.AUTO_CLOSE_PO_TO_DATE);
2096
2097 if (autoClosePOFromDate != null) {
2098 Parameter.Builder updatedParameter = Parameter.Builder.create(autoClosePOFromDate);
2099 updatedParameter.setValue("mm/dd/yyyy");
2100 parameterService.updateParameter(updatedParameter.build());
2101 }
2102 if (autoClosePOToDate != null) {
2103 Parameter.Builder updatedParameter = Parameter.Builder.create(autoClosePOToDate);
2104 updatedParameter.setValue("mm/dd/yyyy");
2105 parameterService.updateParameter(updatedParameter.build());
2106 }
2107 }
2108
2109
2110
2111
2112
2113
2114 protected List<String> getExcludedVendorChoiceCodes() {
2115 List<String> excludedVendorChoiceCodes = new ArrayList<String>();
2116 for (String excludedCode : PurapConstants.AUTO_CLOSE_EXCLUSION_VNDR_CHOICE_CODES) {
2117 excludedVendorChoiceCodes.add(excludedCode);
2118 }
2119 return excludedVendorChoiceCodes;
2120 }
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130 protected void createNoteForAutoCloseOrders(PurchaseOrderDocument purchaseOrderDocument, String annotation) {
2131 try {
2132 Note noteObj = documentService.createNoteFromDocument(purchaseOrderDocument, annotation);
2133
2134 noteService.save(noteObj);
2135 } catch (Exception e) {
2136 String errorMessage = "Error creating and saving close note for purchase order with document service";
2137 LOG.error("createNoteForAutoCloseRecurringOrders " + errorMessage, e);
2138 throw new RuntimeException(errorMessage, e);
2139 }
2140 }
2141
2142
2143
2144
2145 @Override
2146 public List<PurchasingCapitalAssetItem> retrieveCapitalAssetItemsForIndividual(Integer poId) {
2147 PurchaseOrderDocument po = getCurrentPurchaseOrder(poId);
2148 if (ObjectUtils.isNotNull(po)) {
2149 return po.getPurchasingCapitalAssetItems();
2150 }
2151 return null;
2152 }
2153
2154
2155
2156
2157 @Override
2158 public CapitalAssetSystem retrieveCapitalAssetSystemForOneSystem(Integer poId) {
2159 PurchaseOrderDocument po = getCurrentPurchaseOrder(poId);
2160 if (ObjectUtils.isNotNull(po)) {
2161 List<CapitalAssetSystem> systems = po.getPurchasingCapitalAssetSystems();
2162 if (ObjectUtils.isNotNull(systems)) {
2163
2164 return systems.get(0);
2165 }
2166 }
2167 return null;
2168 }
2169
2170
2171
2172
2173 @Override
2174 public List<CapitalAssetSystem> retrieveCapitalAssetSystemsForMultipleSystem(Integer poId) {
2175 PurchaseOrderDocument po = getCurrentPurchaseOrder(poId);
2176 if (ObjectUtils.isNotNull(po)) {
2177 return po.getPurchasingCapitalAssetSystems();
2178 }
2179 return null;
2180 }
2181
2182
2183
2184
2185 protected void fixItemReferences(PurchaseOrderDocument po) {
2186
2187 for (PurApItem item : (List<PurApItem>) po.getItems()) {
2188 item.setPurapDocument(po);
2189 item.fixAccountReferences();
2190 }
2191 }
2192
2193 @Override
2194 public List getPendingPurchaseOrderFaxes() {
2195 List<PurchaseOrderDocument> purchaseOrderList = purchaseOrderDao.getPendingPurchaseOrdersForFaxing();
2196 return filterPurchaseOrderDocumentByAppDocStatus(purchaseOrderList,
2197 PurapConstants.PurchaseOrderStatuses.APPDOC_PENDING_FAX);
2198 }
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211 protected List<PurchaseOrderDocument> filterPurchaseOrderDocumentByAppDocStatus(Collection<PurchaseOrderDocument> purchaseOrderDocuments, String... appDocStatus) {
2212 List<String> purchaseOrderDocNumbers = new ArrayList<String>();
2213 for (PurchaseOrderDocument purchaseOrder : purchaseOrderDocuments) {
2214 purchaseOrderDocNumbers.add(purchaseOrder.getDocumentNumber());
2215 }
2216
2217 List<String> filteredPurchaseOrderDocNumbers = filterPurchaseOrderDocumentNumbersByAppDocStatus(purchaseOrderDocNumbers, appDocStatus);
2218
2219 List<PurchaseOrderDocument> filteredPaymentRequestDocuments = new ArrayList<PurchaseOrderDocument>();
2220
2221 for (PurchaseOrderDocument po : purchaseOrderDocuments) {
2222 if (filteredPurchaseOrderDocNumbers.contains(po.getDocumentNumber())) {
2223 filteredPaymentRequestDocuments.add(po);
2224 }
2225 }
2226 return filteredPaymentRequestDocuments;
2227 }
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240 protected List<String> filterPurchaseOrderDocumentNumbersByAppDocStatus(List<String> lookupDocNumbers, String... appDocStatus) {
2241 boolean valid = false;
2242
2243 final String DOC_NUM_DELIM = "|";
2244 StrBuilder routerHeaderIdBuilder = new StrBuilder().appendWithSeparators(lookupDocNumbers, DOC_NUM_DELIM);
2245
2246 List<String> purchaseOrderDocNumbers = new ArrayList<String>();
2247
2248 DocumentSearchCriteria.Builder documentSearchCriteriaDTO = DocumentSearchCriteria.Builder.create();
2249 documentSearchCriteriaDTO.setDocumentId(routerHeaderIdBuilder.toString());
2250 documentSearchCriteriaDTO.setDocumentTypeName(PurapConstants.PurapDocTypeCodes.PO_DOCUMENT);
2251
2252 DocumentSearchResults poDocumentsList = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(
2253 GlobalVariables.getUserSession().getPrincipalId(), documentSearchCriteriaDTO.build());
2254
2255 for (DocumentSearchResult poDocument : poDocumentsList.getSearchResults()) {
2256
2257 if (Arrays.asList(appDocStatus).contains(poDocument.getDocument().getApplicationDocumentStatus())) {
2258
2259 purchaseOrderDocNumbers.add(poDocument.getDocument().getDocumentId());
2260 }
2261 }
2262
2263 return purchaseOrderDocNumbers;
2264 }
2265
2266 @Override
2267 public String getPurchaseOrderAppDocStatus(Integer poId) {
2268
2269 PurchaseOrderDocument po = getCurrentPurchaseOrder(poId);
2270 if (ObjectUtils.isNotNull(po)) {
2271 return po.getApplicationDocumentStatus();
2272 }
2273
2274 return null;
2275 }
2276
2277
2278
2279
2280
2281
2282
2283 protected void savePurchaseOrderData(PurchaseOrderDocument po) {
2284
2285
2286
2287
2288
2289 businessObjectService.save(po);
2290
2291
2292 final DocumentAttributeIndexingQueue documentAttributeIndexingQueue = KewApiServiceLocator
2293 .getDocumentAttributeIndexingQueue();
2294 documentAttributeIndexingQueue.indexDocument(po.getDocumentNumber());
2295
2296 }
2297
2298
2299
2300
2301 protected PersonService getPersonService() {
2302 if (personService == null) {
2303 personService = SpringContext.getBean(PersonService.class);
2304 }
2305 return personService;
2306 }
2307
2308 public void setB2bPurchaseOrderService(B2BPurchaseOrderService purchaseOrderService) {
2309 this.b2bPurchaseOrderService = purchaseOrderService;
2310 }
2311
2312 public void setBusinessObjectService(BusinessObjectService boService) {
2313 this.businessObjectService = boService;
2314 }
2315
2316 public void setDateTimeService(DateTimeService dateTimeService) {
2317 this.dateTimeService = dateTimeService;
2318 }
2319
2320 public void setDocumentService(DocumentService documentService) {
2321 this.documentService = documentService;
2322 }
2323
2324 public void setNoteService(NoteService noteService) {
2325 this.noteService = noteService;
2326 }
2327
2328 public void setPurapService(PurapService purapService) {
2329 this.purapService = purapService;
2330 }
2331
2332 public void setPrintService(PrintService printService) {
2333 this.printService = printService;
2334 }
2335
2336 public void setPurchaseOrderDao(PurchaseOrderDao purchaseOrderDao) {
2337 this.purchaseOrderDao = purchaseOrderDao;
2338 }
2339
2340 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
2341 this.workflowDocumentService = workflowDocumentService;
2342 }
2343
2344 public void setConfigurationService(ConfigurationService kualiConfigurationService) {
2345 this.kualiConfigurationService = kualiConfigurationService;
2346 }
2347
2348 public void setKualiRuleService(KualiRuleService kualiRuleService) {
2349 this.kualiRuleService = kualiRuleService;
2350 }
2351
2352 public void setVendorService(VendorService vendorService) {
2353 this.vendorService = vendorService;
2354 }
2355
2356 public void setRequisitionService(RequisitionService requisitionService) {
2357 this.requisitionService = requisitionService;
2358 }
2359
2360 public void setPurapWorkflowIntegrationService(PurApWorkflowIntegrationService purapWorkflowIntegrationService) {
2361 this.purapWorkflowIntegrationService = purapWorkflowIntegrationService;
2362 }
2363
2364 public void setMaintenanceDocumentService(MaintenanceDocumentService maintenanceDocumentService) {
2365 this.maintenanceDocumentService = maintenanceDocumentService;
2366 }
2367
2368 public void setParameterService(ParameterService parameterService) {
2369 this.parameterService = parameterService;
2370 }
2371
2372 public void setMailService(MailService mailService) {
2373 this.mailService = mailService;
2374 }
2375
2376 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
2377 this.dataDictionaryService = dataDictionaryService;
2378 }
2379
2380
2381
2382
2383
2384
2385
2386 @Override
2387 public void initiateTransmission(PurchaseOrderDocument po, PurApItem item) {
2388 if (po.getRequestorPersonEmailAddress() != null) {
2389 fromEmailAddress = po.getRequestorPersonEmailAddress();
2390 }
2391
2392 if (po != null && po.getVendorDetail() != null) {
2393 List<VendorTransmissionFormatDetail> vendorTxFormat = po.getVendorDetail().getVendorTransmissionFormat();
2394 boolean isSuccess = false;
2395 if (vendorTxFormat.size() > 0) {
2396 for (int i = 0; i < vendorTxFormat.size(); i++) {
2397 VendorTransmissionFormatDetail vendorTransmissionFormatDetail = vendorTxFormat.get(i);
2398 boolean isPrefferedTransmissionFormat = vendorTransmissionFormatDetail.isVendorPreferredTransmissionFormat();
2399 if (isPrefferedTransmissionFormat && item.getItemLineNumber() != null) {
2400 String documentType = po.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
2401 String ediFileName = documentType + "_" + po.getPurapDocumentIdentifier().toString() + "_" + PurapConstants.ItemTypeCodes.ITEM_TYPE_ITEM_CODE + item.getItemLineNumber() + "_" + System.currentTimeMillis() + ".edi";
2402 String pdfFileName = documentType + "_" + po.getPurapDocumentIdentifier().toString() + "_" + System.currentTimeMillis() + ".pdf";
2403 String directory = kualiConfigurationService.getPropertyValueAsString(OLEConstants.STAGING_DIRECTORY_KEY);
2404 String fileLocation = directory + getOlePurapService().getParameter(OLEConstants.VENDOR_TRANSMISSION_FILE);
2405 File fileLocationDir = new File(fileLocation);
2406 if (!(fileLocationDir.exists())) {
2407 fileLocationDir.mkdir();
2408 }
2409 String file = fileLocation.trim() + ediFileName.trim();
2410
2411 if (vendorTransmissionFormatDetail.getVendorTransmissionFormat() != null &&
2412 vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat() != null &&
2413 vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat().equalsIgnoreCase("EDI")) {
2414 if (LOG.isDebugEnabled()) {
2415 LOG.debug("EDI File======================>" + file);
2416 }
2417 isSuccess = savePurchaseOrderEdi(po, file, item);
2418 }
2419 if (vendorTransmissionFormatDetail.getVendorTransmissionFormat() != null &&
2420 vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat() != null &&
2421 vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat().equalsIgnoreCase(OLEConstants.OLE_VENDOR_PDF_OPTION)) {
2422 if (!(po.getDocumentNumber().equals(documentNumber))) {
2423 savePurchaseOrderPdf(po, pdfFileName, item);
2424 processFTPTransmission(vendorTransmissionFormatDetail, file, pdfFileName.trim());
2425 documentNumber = po.getDocumentNumber();
2426 }
2427 }
2428 if (isSuccess && vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType() != null) {
2429 processFTPTransmission(vendorTransmissionFormatDetail, file, ediFileName.trim());
2430 }
2431 }
2432 }
2433 }
2434
2435 }
2436 }
2437
2438 public String getEmailAddress(VendorTransmissionFormatDetail vendorTransmissionFormatDetail) {
2439 String toAddress = "";
2440 Integer vendorId = vendorTransmissionFormatDetail.getVendorHeaderGeneratedIdentifier();
2441 if (vendorId != null) {
2442 Map searchMap = new HashMap();
2443 searchMap.put("vendorHeaderGeneratedIdentifier", vendorId);
2444 List<VendorAddress> address = (List<VendorAddress>) SpringContext.getBean(BusinessObjectService.class).findMatching(VendorAddress.class, searchMap);
2445 if (address.size() > 0) {
2446 for (VendorAddress vendorAddress : address) {
2447 if (toAddress == null || (toAddress.isEmpty())) {
2448 toAddress = vendorAddress.getVendorAddressEmailAddress();
2449 }
2450 }
2451
2452 }
2453 if (toAddress == null || toAddress.isEmpty()) {
2454 List<VendorContact> vendorContactList = (List<VendorContact>) SpringContext.getBean(BusinessObjectService.class).findMatching(VendorContact.class, searchMap);
2455 if (vendorContactList.size() > 0) {
2456 for (VendorContact vendorContact : vendorContactList) {
2457 if (toAddress == null || (toAddress.isEmpty())) {
2458 toAddress = vendorContact.getVendorContactEmailAddress();
2459 }
2460 }
2461 }
2462 }
2463 }
2464
2465 return toAddress;
2466 }
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477 public boolean savePurchaseOrderEdi(PurchaseOrderDocument po, String file, PurApItem item) {
2478 LOG.debug("****************savePurchaseOrderEdi() started*******************");
2479 boolean isSuccess = false;
2480 PurchaseOrderEdi purchaseOrderEdi = SpringContext.getBean(PurchaseOrderEdi.class, "purchaseOrderEdi");
2481 try {
2482 isSuccess = purchaseOrderEdi.saveEdi(po, item, file);
2483 LOG.debug("savePurchaseOrderEdi() completed");
2484 } catch (Exception e) {
2485 LOG.error("Caught exception ", e);
2486 throw new RuntimeException(e);
2487 }
2488 return isSuccess;
2489 }
2490
2491 public boolean savePurchaseOrderPdf(PurchaseOrderDocument po, String file, PurApItem item) {
2492 LOG.debug("****************savePurchaseOrderPDF() started*******************");
2493 boolean isSuccess = false;
2494 PurchaseOrderParameters purchaseOrderParameters = getPurchaseOrderParameters();
2495 purchaseOrderParameters.setPurchaseOrderPdfAndFaxParameters(po);
2496 PurchaseOrderTransmitParameters purchaseOrderTransmitParameter = (PurchaseOrderTransmitParameters) purchaseOrderParameters;
2497 String pdfFileLocation = ConfigContext.getCurrentContextConfig().getProperty(org.kuali.ole.OLEConstants.VENDOR_TRANSMISSION_FILE_PATH);
2498 if (pdfFileLocation != null) {
2499 purchaseOrderTransmitParameter.setPdfFileLocation(pdfFileLocation);
2500 purchaseOrderTransmitParameter.setPdfFileName(file);
2501 }
2502 String environment = kualiConfigurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
2503 PurchaseOrderPdf purchaseOrderPdf = SpringContext.getBean(PurchaseOrderPdf.class, "purchaseOrderPdf");
2504 try {
2505 purchaseOrderPdf.savePdf(po, purchaseOrderParameters, isSuccess, environment);
2506 isSuccess = true;
2507 LOG.debug("savePurchaseOrderPdf() completed");
2508 } catch (Exception e) {
2509 LOG.error("Caught exception ", e);
2510 throw new RuntimeException(e);
2511 }
2512 return isSuccess;
2513 }
2514
2515 public PurchaseOrderParameters getPurchaseOrderParameters() {
2516 return SpringContext.getBean(PurchaseOrderParameters.class);
2517 }
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527 @Override
2528 public boolean processFTPTransmission(VendorTransmissionFormatDetail vendorTransmissionFormatDetail, String file, String fileName) {
2529
2530 if (vendorTransmissionFormatDetail != null &&
2531 vendorTransmissionFormatDetail.getVendorEDIConnectionAddress() != null &&
2532 vendorTransmissionFormatDetail.getVendorEDIConnectionUserName() != null &&
2533 vendorTransmissionFormatDetail.getVendorEDIConnectionPassword() != null) {
2534 if (LOG.isDebugEnabled()) {
2535 LOG.debug("Transmission Format==================>" + vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat());
2536 LOG.debug("Connection Type======================>" + vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType());
2537 LOG.debug("Connection Address===================>" + vendorTransmissionFormatDetail.getVendorEDIConnectionAddress());
2538 LOG.debug("Connection User Name=================>" + vendorTransmissionFormatDetail.getVendorEDIConnectionUserName());
2539
2540 LOG.debug("file=================================>" + file);
2541 LOG.debug("ediFileName==========================>" + fileName);
2542 }
2543
2544 OleTransmissionService transmissionService = (OleTransmissionService) SpringContext.getService("transmissionService");
2545 if (vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType().equalsIgnoreCase("SFTP")) {
2546 transmissionService.doSFTPUpload(vendorTransmissionFormatDetail, file, fileName);
2547 } else if (vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType().equalsIgnoreCase("FTP")) {
2548 transmissionService.doFTPUpload(vendorTransmissionFormatDetail, file, fileName);
2549 } else if (vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType().equalsIgnoreCase(OLEConstants.OLE_VENDOR_EMAIL_OPTION)) {
2550 String fileLocation = ConfigContext.getCurrentContextConfig().getProperty(org.kuali.ole.OLEConstants.VENDOR_TRANSMISSION_FILE_PATH) + fileName;
2551 fileNameList.add(fileLocation);
2552 toEmailAddress = getEmailAddress(vendorTransmissionFormatDetail);
2553 }
2554 } else if (vendorTransmissionFormatDetail != null &&
2555 getVendorFormatType(vendorTransmissionFormatDetail.getVendorTransmissionFormatId()).equalsIgnoreCase(OLEConstants.OLE_VENDOR_PDF_OPTION) &&
2556 vendorTransmissionFormatDetail.isVendorPreferredTransmissionFormat() &&
2557 getVendorTransmissionType(vendorTransmissionFormatDetail.getVendorTransmissionTypeId()).equalsIgnoreCase(OLEConstants.OLE_VENDOR_EMAIL_OPTION)) {
2558 if (vendorTransmissionFormatDetail.getVendorTransmissionTypes().getVendorTransmissionType().equalsIgnoreCase(OLEConstants.OLE_VENDOR_EMAIL_OPTION) &&
2559 vendorTransmissionFormatDetail.getVendorTransmissionFormat().getVendorTransmissionFormat().equalsIgnoreCase(OLEConstants.OLE_VENDOR_PDF_OPTION)) {
2560 String fileLocation = ConfigContext.getCurrentContextConfig().getProperty(org.kuali.ole.OLEConstants.VENDOR_TRANSMISSION_FILE_PATH) + fileName;
2561 fileNameList.add(fileLocation);
2562 toEmailAddress = getEmailAddress(vendorTransmissionFormatDetail);
2563 }
2564 } else if (vendorTransmissionFormatDetail != null &&
2565 getVendorFormatType(vendorTransmissionFormatDetail.getVendorTransmissionFormatId()).equalsIgnoreCase(OLEConstants.OLE_VENDOR_EDI_OPTION) &&
2566 vendorTransmissionFormatDetail.isVendorPreferredTransmissionFormat() &&
2567 getVendorTransmissionType(vendorTransmissionFormatDetail.getVendorTransmissionTypeId()).equalsIgnoreCase(OLEConstants.OLE_VENDOR_EMAIL_OPTION)) {
2568 String fileLocation = ConfigContext.getCurrentContextConfig().getProperty(org.kuali.ole.OLEConstants.VENDOR_TRANSMISSION_FILE_PATH) + fileName;
2569 fileNameList.add(fileLocation);
2570 toEmailAddress = getEmailAddress(vendorTransmissionFormatDetail);
2571 }
2572 return true;
2573 }
2574
2575 public String getVendorFormatType(Long id) {
2576 String vendorFormatType = "";
2577 Map searchMap = new HashMap();
2578 searchMap.put(OLEConstants.VENDOR_TRANS_FORMAT_ID, id);
2579 OleVendorTransmissionFormat vendorTransmissionFormat = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(OleVendorTransmissionFormat.class, searchMap);
2580 if (vendorTransmissionFormat != null) {
2581 vendorFormatType = vendorTransmissionFormat.getVendorTransmissionFormat();
2582 }
2583 return vendorFormatType;
2584 }
2585
2586 public String getVendorTransmissionType(Integer id) {
2587 String vendorTransmissionType = "";
2588 Map searchMap = new HashMap();
2589 searchMap.put(OLEConstants.VENDOR_TRANS_TYPE_ID, id);
2590 OleVendorTransmissionType transmissionType = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(OleVendorTransmissionType.class, searchMap);
2591 if (transmissionType != null) {
2592 vendorTransmissionType = transmissionType.getVendorTransmissionType();
2593 }
2594 return vendorTransmissionType;
2595 }
2596
2597 public void sendEmail() {
2598 try {
2599 if (toEmailAddress != null && fromEmailAddress != null && fileNameList.size() > 0) {
2600 String subject = OLEConstants.MAIL_SUBJECT;
2601 String messageBody = OLEConstants.MAIL_MESSAGE_BODY;
2602 OleMailer oleMail = GlobalResourceLoader.getService(OLEConstants.OLE_MAILER);
2603 oleMail.SendEMail(toEmailAddress, fromEmailAddress, fileNameList, subject, messageBody);
2604 }
2605 } catch (Exception e) {
2606 LOG.info("Email Sending Failed for fromAddress [" + fromEmailAddress + "] and toAddress [ " + toEmailAddress + " ]");
2607 e.printStackTrace();
2608 }
2609 }
2610
2611 public OleSelectDocumentService getOleSelectDocumentService() {
2612 if (oleSelectDocumentService == null) {
2613 oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
2614 }
2615 return oleSelectDocumentService;
2616 }
2617
2618 public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
2619 this.oleSelectDocumentService = oleSelectDocumentService;
2620 }
2621 }