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