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