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