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.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.text.StrBuilder;
21 import org.kuali.ole.module.purap.PurapConstants;
22 import org.kuali.ole.module.purap.PurapConstants.CreditMemoStatuses;
23 import org.kuali.ole.module.purap.PurapKeyConstants;
24 import org.kuali.ole.module.purap.PurapParameterConstants;
25 import org.kuali.ole.module.purap.PurapPropertyConstants;
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.CreditMemoDao;
29 import org.kuali.ole.module.purap.document.service.*;
30 import org.kuali.ole.module.purap.document.validation.event.AttributedContinuePurapEvent;
31 import org.kuali.ole.module.purap.service.PurapAccountingService;
32 import org.kuali.ole.module.purap.service.PurapGeneralLedgerService;
33 import org.kuali.ole.module.purap.util.ExpiredOrClosedAccountEntry;
34 import org.kuali.ole.module.purap.util.VendorGroupingHelper;
35 import org.kuali.ole.select.document.OleVendorCreditMemoDocument;
36 import org.kuali.ole.sys.businessobject.Bank;
37 import org.kuali.ole.sys.businessobject.SourceAccountingLine;
38 import org.kuali.ole.sys.context.SpringContext;
39 import org.kuali.ole.sys.service.BankService;
40 import org.kuali.ole.vnd.VendorConstants;
41 import org.kuali.ole.vnd.VendorUtils;
42 import org.kuali.ole.vnd.businessobject.VendorAddress;
43 import org.kuali.ole.vnd.businessobject.VendorDetail;
44 import org.kuali.ole.vnd.document.service.VendorService;
45 import org.kuali.rice.core.api.config.property.ConfigurationService;
46 import org.kuali.rice.core.api.util.type.KualiDecimal;
47 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
48 import org.kuali.rice.kew.api.KewApiServiceLocator;
49 import org.kuali.rice.kew.api.WorkflowDocument;
50 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
51 import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
52 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
53 import org.kuali.rice.kew.api.exception.WorkflowException;
54 import org.kuali.rice.kim.api.identity.Person;
55 import org.kuali.rice.kns.service.DataDictionaryService;
56 import org.kuali.rice.krad.bo.DocumentHeader;
57 import org.kuali.rice.krad.bo.Note;
58 import org.kuali.rice.krad.exception.ValidationException;
59 import org.kuali.rice.krad.service.DocumentService;
60 import org.kuali.rice.krad.service.NoteService;
61 import org.kuali.rice.krad.util.GlobalVariables;
62 import org.kuali.rice.krad.util.KRADPropertyConstants;
63 import org.kuali.rice.krad.util.ObjectUtils;
64 import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
65 import org.springframework.transaction.annotation.Transactional;
66
67 import java.math.BigDecimal;
68 import java.sql.Date;
69 import java.sql.Timestamp;
70 import java.util.*;
71
72
73
74
75 @Transactional
76 public class CreditMemoServiceImpl implements CreditMemoService {
77 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CreditMemoServiceImpl.class);
78
79 private AccountsPayableService accountsPayableService;
80 private CreditMemoDao creditMemoDao;
81 private DataDictionaryService dataDictionaryService;
82 private DocumentService documentService;
83 private ConfigurationService kualiConfigurationService;
84 private NoteService noteService;
85 private PaymentRequestService paymentRequestService;
86 private PurapAccountingService purapAccountingService;
87 private PurapGeneralLedgerService purapGeneralLedgerService;
88 private PurapService purapService;
89 private PurchaseOrderService purchaseOrderService;
90 private VendorService vendorService;
91 private WorkflowDocumentService workflowDocumentService;
92
93
94 public void setAccountsPayableService(AccountsPayableService accountsPayableService) {
95 this.accountsPayableService = accountsPayableService;
96 }
97
98 public void setCreditMemoDao(CreditMemoDao creditMemoDao) {
99 this.creditMemoDao = creditMemoDao;
100 }
101
102 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
103 this.dataDictionaryService = dataDictionaryService;
104 }
105
106 public void setDocumentService(DocumentService documentService) {
107 this.documentService = documentService;
108 }
109
110 public void setConfigurationService(ConfigurationService kualiConfigurationService) {
111 this.kualiConfigurationService = kualiConfigurationService;
112 }
113
114 public void setNoteService(NoteService noteService) {
115 this.noteService = noteService;
116 }
117
118 public void setPaymentRequestService(PaymentRequestService paymentRequestService) {
119 this.paymentRequestService = paymentRequestService;
120 }
121
122 public void setPurapAccountingService(PurapAccountingService purapAccountingService) {
123 this.purapAccountingService = purapAccountingService;
124 }
125
126 public void setPurapGeneralLedgerService(PurapGeneralLedgerService purapGeneralLedgerService) {
127 this.purapGeneralLedgerService = purapGeneralLedgerService;
128 }
129
130 public void setPurapService(PurapService purapService) {
131 this.purapService = purapService;
132 }
133
134 public void setPurchaseOrderService(PurchaseOrderService purchaseOrderService) {
135 this.purchaseOrderService = purchaseOrderService;
136 }
137
138 public void setVendorService(VendorService vendorService) {
139 this.vendorService = vendorService;
140 }
141
142 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
143 this.workflowDocumentService = workflowDocumentService;
144 }
145
146
147
148
149
150 @Override
151 public List<VendorCreditMemoDocument> getCreditMemosToExtract(String chartCode) {
152 LOG.debug("getCreditMemosToExtract() started");
153
154 List<VendorCreditMemoDocument> docs = creditMemoDao.getCreditMemosToExtract(chartCode);
155 docs = (List<VendorCreditMemoDocument>) filterCreditMemoByAppDocStatus(docs, CreditMemoStatuses.STATUSES_ALLOWED_FOR_EXTRACTION);
156
157 return docs;
158
159 }
160
161 @Override
162 public Collection<VendorCreditMemoDocument> getCreditMemosToExtractByVendor(String chartCode, VendorGroupingHelper vendor) {
163 LOG.debug("getCreditMemosToExtractByVendor() started");
164
165 Collection<VendorCreditMemoDocument> docs = creditMemoDao.getCreditMemosToExtractByVendor(chartCode, vendor);
166 docs = filterCreditMemoByAppDocStatus(docs, CreditMemoStatuses.STATUSES_ALLOWED_FOR_EXTRACTION);
167 return docs;
168
169 }
170
171 @Override
172 public Set<VendorGroupingHelper> getVendorsOnCreditMemosToExtract(String chartCode) {
173 LOG.debug("getVendorsOnCreditMemosToExtract() started");
174 HashSet<VendorGroupingHelper> vendors = new HashSet<VendorGroupingHelper>();
175
176 List<VendorCreditMemoDocument> docs = this.getCreditMemosToExtract(chartCode);
177
178 for(VendorCreditMemoDocument vendorCreditMemoDocument : docs) {
179 vendors.add(new VendorGroupingHelper(vendorCreditMemoDocument));
180 }
181
182
183
184
185
186 return vendors;
187 }
188
189
190
191
192
193
194
195
196
197
198
199
200 private List<String> filterCreditMemoByAppDocStatus(List<String> lookupDocNumbers, String... appDocStatus) {
201 boolean valid = false;
202
203 final String DOC_NUM_DELIM = "|";
204 StrBuilder routerHeaderIdBuilder = new StrBuilder().appendWithSeparators(lookupDocNumbers, DOC_NUM_DELIM);
205
206 List<String> creditMemoDocNumbers = new ArrayList<String>();
207
208 DocumentSearchCriteria.Builder documentSearchCriteriaDTO = DocumentSearchCriteria.Builder.create();
209 documentSearchCriteriaDTO.setDocumentId(routerHeaderIdBuilder.toString());
210 documentSearchCriteriaDTO.setDocumentTypeName(PurapConstants.PurapDocTypeCodes.CREDIT_MEMO_DOCUMENT);
211
212 DocumentSearchResults creditMemoDocumentsList = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(
213 GlobalVariables.getUserSession().getPrincipalId(), documentSearchCriteriaDTO.build());
214
215 for (DocumentSearchResult creditMemoDocument : creditMemoDocumentsList.getSearchResults()) {
216
217 if (Arrays.asList(appDocStatus).contains(creditMemoDocument.getDocument().getApplicationDocumentStatus())) {
218
219 creditMemoDocNumbers.add(creditMemoDocument.getDocument().getDocumentId());
220 }
221 }
222
223 return creditMemoDocNumbers;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237 private Collection<VendorCreditMemoDocument> filterCreditMemoByAppDocStatus(Collection<VendorCreditMemoDocument> creditMemoDocuments, String... appDocStatus) {
238 List<String> creditMemoDocNumbers = new ArrayList<String>();
239 for (VendorCreditMemoDocument creditMemo : creditMemoDocuments) {
240 creditMemoDocNumbers.add(creditMemo.getDocumentNumber());
241 }
242
243 List<String> filteredCreditMemoDocNumbers = filterCreditMemoByAppDocStatus(creditMemoDocNumbers, appDocStatus);
244
245 Collection<VendorCreditMemoDocument> filteredCreditMemoDocuments = new ArrayList<VendorCreditMemoDocument>();
246
247 for (VendorCreditMemoDocument creditMemo : creditMemoDocuments) {
248 if (filteredCreditMemoDocNumbers.contains(creditMemo.getDocumentNumber())) {
249 filteredCreditMemoDocuments.add(creditMemo);
250 }
251 }
252 return filteredCreditMemoDocuments;
253 }
254
255
256
257
258
259
260
261
262
263
264
265
266 private Iterator<VendorCreditMemoDocument> filterCreditMemoByAppDocStatus(Iterator<VendorCreditMemoDocument> creditMemoIterator, String... appDocStatus) {
267 Collection<VendorCreditMemoDocument> creditMemoDocuments = new ArrayList<VendorCreditMemoDocument>();
268 for (; creditMemoIterator.hasNext(); ) {
269 creditMemoDocuments.add(creditMemoIterator.next());
270 }
271
272 return filterCreditMemoByAppDocStatus(creditMemoDocuments, appDocStatus).iterator();
273 }
274
275
276
277
278 @Override
279 public String creditMemoDuplicateMessages(VendorCreditMemoDocument cmDocument) {
280 String duplicateMessage = null;
281
282 String vendorNumber = cmDocument.getVendorNumber();
283 if (StringUtils.isEmpty(vendorNumber)) {
284 PurchasingAccountsPayableDocument sourceDocument = cmDocument.getPurApSourceDocumentIfPossible();
285 if (ObjectUtils.isNotNull(sourceDocument)) {
286 vendorNumber = sourceDocument.getVendorNumber();
287 }
288 }
289
290 if (StringUtils.isNotEmpty(vendorNumber)) {
291
292 if (creditMemoDao.duplicateExists(VendorUtils.getVendorHeaderId(vendorNumber), VendorUtils.getVendorDetailId(vendorNumber), cmDocument.getCreditMemoNumber())) {
293 duplicateMessage = kualiConfigurationService.getPropertyValueAsString(PurapKeyConstants.MESSAGE_DUPLICATE_CREDIT_MEMO_VENDOR_NUMBER);
294 }
295
296
297 if (creditMemoDao.duplicateExists(VendorUtils.getVendorHeaderId(vendorNumber), VendorUtils.getVendorDetailId(vendorNumber), cmDocument.getCreditMemoDate(), cmDocument.getCreditMemoAmount())) {
298 duplicateMessage = kualiConfigurationService.getPropertyValueAsString(PurapKeyConstants.MESSAGE_DUPLICATE_CREDIT_MEMO_VENDOR_NUMBER_DATE_AMOUNT);
299 }
300 }
301
302 return duplicateMessage;
303 }
304
305
306
307
308 @Override
309 public List<PurchaseOrderItem> getPOInvoicedItems(PurchaseOrderDocument poDocument) {
310 List<PurchaseOrderItem> invoicedItems = new ArrayList<PurchaseOrderItem>();
311
312 for (Iterator iter = poDocument.getItems().iterator(); iter.hasNext(); ) {
313 PurchaseOrderItem poItem = (PurchaseOrderItem) iter.next();
314
315
316 if (poItem.getItemType().isAdditionalChargeIndicator()) {
317 continue;
318 }
319
320 if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && poItem.getItemInvoicedTotalQuantity().isGreaterThan(KualiDecimal.ZERO)) {
321 invoicedItems.add(poItem);
322 } else {
323 BigDecimal unitPrice = (poItem.getItemUnitPrice() == null ? new BigDecimal(0) : poItem.getItemUnitPrice());
324 if (unitPrice.doubleValue() > poItem.getItemOutstandingEncumberedAmount().doubleValue()) {
325 invoicedItems.add(poItem);
326 }
327 }
328 }
329
330 return invoicedItems;
331 }
332
333
334
335
336
337 @Override
338 public void calculateCreditMemo(VendorCreditMemoDocument cmDocument) {
339
340 cmDocument.updateExtendedPriceOnItems();
341
342 for (CreditMemoItem item : (List<CreditMemoItem>) cmDocument.getItems()) {
343
344 if (StringUtils.equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_RESTCK_FEE_CODE, item.getItemTypeCode())) {
345 if (item.getItemUnitPrice() != null) {
346 item.setExtendedPrice(item.getExtendedPrice().abs().negated());
347 item.setItemUnitPrice(item.getItemUnitPrice().abs().negate());
348 }
349 }
350 }
351
352
353 if (cmDocument.isSourceVendor() == false) {
354 purapService.calculateTax(cmDocument);
355 }
356
357
358 if (cmDocument.isSourceVendor()) {
359
360 return;
361 }
362
363 for (CreditMemoItem item : (List<CreditMemoItem>) cmDocument.getItems()) {
364
365
366 if (item.getItemType().isLineItemIndicator()) {
367 continue;
368 }
369
370 if ((item.getSourceAccountingLines().isEmpty()) && (ObjectUtils.isNotNull(item.getExtendedPrice())) && (KualiDecimal.ZERO.compareTo(item.getExtendedPrice()) != 0)) {
371
372 KualiDecimal totalAmount = KualiDecimal.ZERO;
373 List<PurApAccountingLine> distributedAccounts = null;
374 List<SourceAccountingLine> summaryAccounts = null;
375
376 totalAmount = cmDocument.getPurApSourceDocumentIfPossible().getTotalDollarAmount();
377
378 purapAccountingService.updateAccountAmounts(cmDocument.getPurApSourceDocumentIfPossible());
379 summaryAccounts = purapAccountingService.generateSummary(cmDocument.getPurApSourceDocumentIfPossible().getItems());
380 distributedAccounts = purapAccountingService.generateAccountDistributionForProration(summaryAccounts, totalAmount, PurapConstants.PRORATION_SCALE, CreditMemoAccount.class);
381
382 if (CollectionUtils.isNotEmpty(distributedAccounts) && CollectionUtils.isEmpty(item.getSourceAccountingLines())) {
383 item.setSourceAccountingLines(distributedAccounts);
384 }
385 }
386 }
387
388 }
389
390
391
392
393 @Override
394 public VendorCreditMemoDocument getCreditMemoByDocumentNumber(String documentNumber) {
395 LOG.debug("getCreditMemoByDocumentNumber() started");
396
397 if (ObjectUtils.isNotNull(documentNumber)) {
398 try {
399 VendorCreditMemoDocument doc = (VendorCreditMemoDocument) documentService.getByDocumentHeaderId(documentNumber);
400 return doc;
401 } catch (WorkflowException e) {
402 String errorMessage = "Error getting credit memo document from document service";
403 LOG.error("getCreditMemoByDocumentNumber() " + errorMessage, e);
404 throw new RuntimeException(errorMessage, e);
405 }
406 }
407 return null;
408 }
409
410
411
412
413 @Override
414 public VendorCreditMemoDocument getCreditMemoDocumentById(Integer purchasingDocumentIdentifier) {
415 return getCreditMemoByDocumentNumber(creditMemoDao.getDocumentNumberByCreditMemoId(purchasingDocumentIdentifier));
416 }
417
418
419
420
421 @Override
422 public void populateAndSaveCreditMemo(VendorCreditMemoDocument document) {
423 try {
424
425
426 document.updateAndSaveAppDocStatus(PurapConstants.CreditMemoStatuses.APPDOC_IN_PROCESS);
427
428 if (document.isSourceDocumentPaymentRequest()) {
429 document.setBankCode(document.getPaymentRequestDocument().getBankCode());
430 document.setBank(document.getPaymentRequestDocument().getBank());
431 } else {
432
433 Bank defaultBank = SpringContext.getBean(BankService.class).getDefaultBankByDocType(document.getClass());
434 if (defaultBank != null) {
435 document.setBankCode(defaultBank.getBankCode());
436 document.setBank(defaultBank);
437 }
438 }
439
440 documentService.saveDocument(document, AttributedContinuePurapEvent.class);
441 } catch (ValidationException ve) {
442
443 try {
444 document.updateAndSaveAppDocStatus(PurapConstants.CreditMemoStatuses.APPDOC_INITIATE);
445 } catch (WorkflowException workflowException) {
446
447 }
448 } catch (WorkflowException we) {
449
450 try {
451 document.updateAndSaveAppDocStatus(PurapConstants.CreditMemoStatuses.APPDOC_INITIATE);
452 } catch (WorkflowException workflowException) {
453
454 }
455 String errorMsg = "Error saving document # " + document.getDocumentNumber() + " " + we.getMessage();
456 LOG.error(errorMsg, we);
457 throw new RuntimeException(errorMsg, we);
458 }
459 }
460
461
462
463
464 @Override
465 public void reopenClosedPO(VendorCreditMemoDocument cmDocument) {
466
467 Integer purchaseOrderDocumentId = cmDocument.getPurchaseOrderIdentifier();
468 if (cmDocument.isSourceDocumentPaymentRequest() && ObjectUtils.isNull(purchaseOrderDocumentId)) {
469 PaymentRequestDocument paymentRequestDocument = paymentRequestService.getPaymentRequestById(cmDocument.getPaymentRequestIdentifier());
470 purchaseOrderDocumentId = paymentRequestDocument.getPurchaseOrderIdentifier();
471 }
472
473 if (ObjectUtils.isNotNull(purchaseOrderDocumentId)) {
474 PurchaseOrderDocument purchaseOrderDocument = purchaseOrderService.getCurrentPurchaseOrder(purchaseOrderDocumentId);
475
476 if (ObjectUtils.isNotNull(purchaseOrderDocument) && (!purchaseOrderDocument.isPendingActionIndicator()) && PurapConstants.PurchaseOrderStatuses.APPDOC_CLOSED.equals(purchaseOrderDocument.getApplicationDocumentStatus())) {
477
478 }
479 }
480 }
481
482
483
484
485
486 @Override
487 public VendorCreditMemoDocument addHoldOnCreditMemo(VendorCreditMemoDocument cmDocument, String note) throws Exception {
488
489 Note noteObj = documentService.createNoteFromDocument(cmDocument, note);
490 cmDocument.addNote(noteObj);
491 noteService.save(noteObj);
492
493
494 VendorCreditMemoDocument cmDoc = getCreditMemoDocumentById(cmDocument.getPurapDocumentIdentifier());
495 cmDoc.setHoldIndicator(true);
496 cmDoc.setLastActionPerformedByPersonId(GlobalVariables.getUserSession().getPerson().getPrincipalId());
497 purapService.saveDocumentNoValidation(cmDoc);
498
499
500 cmDocument.setHoldIndicator(true);
501 cmDocument.setLastActionPerformedByPersonId(GlobalVariables.getUserSession().getPerson().getPrincipalId());
502
503 return cmDoc;
504 }
505
506
507
508
509
510 @Override
511 public VendorCreditMemoDocument removeHoldOnCreditMemo(VendorCreditMemoDocument cmDocument, String note) throws Exception {
512
513 Note noteObj = documentService.createNoteFromDocument(cmDocument, note);
514 cmDocument.addNote(noteObj);
515 noteService.save(noteObj);
516
517
518 VendorCreditMemoDocument cmDoc = getCreditMemoDocumentById(cmDocument.getPurapDocumentIdentifier());
519 cmDoc.setHoldIndicator(false);
520 cmDoc.setLastActionPerformedByPersonId(null);
521 purapService.saveDocumentNoValidation(cmDoc);
522
523
524 cmDocument.setHoldIndicator(false);
525 cmDocument.setLastActionPerformedByPersonId(null);
526
527 return cmDoc;
528 }
529
530
531
532
533 @Override
534 public String updateStatusByNode(String currentNodeName, AccountsPayableDocument apDoc) {
535 return updateStatusByNode(currentNodeName, (VendorCreditMemoDocument) apDoc);
536 }
537
538
539
540
541
542
543
544
545 protected String updateStatusByNode(String currentNodeName, VendorCreditMemoDocument cmDoc) {
546
547
548 String cancelledStatusCode = "";
549 if (StringUtils.isEmpty(currentNodeName)) {
550 cancelledStatusCode = PurapConstants.CreditMemoStatuses.APPDOC_CANCELLED_POST_AP_APPROVE;
551 } else {
552 cancelledStatusCode = CreditMemoStatuses.getCreditMemoAppDocDisapproveStatuses().get(currentNodeName);
553 }
554
555 if (StringUtils.isNotBlank(cancelledStatusCode)) {
556 try {
557 cmDoc.updateAndSaveAppDocStatus(cancelledStatusCode);
558 } catch (WorkflowException we) {
559 throw new RuntimeException("Unable to save the workflow document with document id: " + cmDoc.getDocumentNumber());
560 }
561 purapService.saveDocumentNoValidation(cmDoc);
562 return cancelledStatusCode;
563 } else {
564 logAndThrowRuntimeException("No status found to set for document being disapproved in node '" + currentNodeName + "'");
565 }
566 return cancelledStatusCode;
567 }
568
569
570
571
572
573 @Override
574 public void cancelExtractedCreditMemo(VendorCreditMemoDocument cmDocument, String note) {
575 LOG.debug("cancelExtractedCreditMemo() started");
576 if (CreditMemoStatuses.CANCELLED_STATUSES.contains(cmDocument.getApplicationDocumentStatus())) {
577 LOG.debug("cancelExtractedCreditMemo() ended");
578 return;
579 }
580
581 try {
582 Note noteObj = documentService.createNoteFromDocument(cmDocument, note);
583 cmDocument.addNote(noteObj);
584 } catch (Exception e) {
585 throw new RuntimeException(e.getMessage());
586 }
587
588 accountsPayableService.cancelAccountsPayableDocument(cmDocument, "");
589 if (LOG.isDebugEnabled()) {
590 LOG.debug("cancelExtractedCreditMemo() CM " + cmDocument.getPurapDocumentIdentifier() + " Cancelled Without Workflow");
591 }
592 LOG.debug("cancelExtractedCreditMemo() ended");
593
594 }
595
596
597
598
599
600 @Override
601 public void resetExtractedCreditMemo(VendorCreditMemoDocument cmDocument, String note) {
602 LOG.debug("resetExtractedCreditMemo() started");
603 if (CreditMemoStatuses.CANCELLED_STATUSES.contains(cmDocument.getApplicationDocumentStatus())) {
604 LOG.debug("resetExtractedCreditMemo() ended");
605 return;
606 }
607 cmDocument.setExtractedTimestamp(null);
608 cmDocument.setCreditMemoPaidTimestamp(null);
609
610 Note noteObj;
611 try {
612 noteObj = documentService.createNoteFromDocument(cmDocument, note);
613 cmDocument.addNote(noteObj);
614 } catch (Exception e) {
615 throw new RuntimeException(e.getMessage());
616 }
617 purapService.saveDocumentNoValidation(cmDocument);
618
619 if (LOG.isDebugEnabled()) {
620 LOG.debug("resetExtractedCreditMemo() CM " + cmDocument.getPurapDocumentIdentifier() + " Cancelled Without Workflow");
621 }
622 LOG.debug("resetExtractedCreditMemo() ended");
623 }
624
625
626
627
628 @Override
629 public boolean shouldPurchaseOrderBeReversed(AccountsPayableDocument apDoc) {
630
631 return false;
632 }
633
634
635
636
637 @Override
638 public Person getPersonForCancel(AccountsPayableDocument apDoc) {
639
640 return null;
641 }
642
643
644
645
646 @Override
647 public void takePurchaseOrderCancelAction(AccountsPayableDocument apDoc) {
648 VendorCreditMemoDocument cmDocument = (VendorCreditMemoDocument) apDoc;
649 if (cmDocument.isReopenPurchaseOrderIndicator()) {
650 String docType = PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT;
651 purchaseOrderService.createAndRoutePotentialChangeDocument(cmDocument.getPurchaseOrderDocument().getDocumentNumber(), docType, "reopened by Payment Request " + apDoc.getPurapDocumentIdentifier() + "cancel", new ArrayList(), PurapConstants.PurchaseOrderStatuses.APPDOC_PENDING_CLOSE);
652 }
653 }
654
655
656
657
658
659 @Override
660 public void markPaid(VendorCreditMemoDocument cm, Date processDate) {
661 LOG.debug("markPaid() started");
662
663 cm.setCreditMemoPaidTimestamp(new Timestamp(processDate.getTime()));
664 purapService.saveDocumentNoValidation(cm);
665 }
666
667
668
669
670 @Override
671 public boolean poItemEligibleForAp(AccountsPayableDocument apDoc, PurchaseOrderItem poItem) {
672
673 if (!poItem.isItemActiveIndicator()) {
674 return false;
675 }
676
677 if (poItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && poItem.getItemInvoicedTotalQuantity().isGreaterThan(KualiDecimal.ZERO)) {
678 return true;
679 } else {
680 BigDecimal unitPrice = (poItem.getItemUnitPrice() == null ? new BigDecimal(0) : poItem.getItemUnitPrice());
681 if (unitPrice.doubleValue() > poItem.getItemOutstandingEncumberedAmount().doubleValue()) {
682 return true;
683 }
684 }
685 return false;
686 }
687
688
689
690
691
692
693 @Override
694 public void generateGLEntriesCreateAccountsPayableDocument(AccountsPayableDocument apDocument) {
695 VendorCreditMemoDocument creditMemo = (VendorCreditMemoDocument) apDocument;
696 purapGeneralLedgerService.generateEntriesCreateCreditMemo(creditMemo);
697 }
698
699
700
701
702
703
704 protected void logAndThrowRuntimeException(String errorMessage) {
705 this.logAndThrowRuntimeException(errorMessage, null);
706 }
707
708
709
710
711
712
713
714 protected void logAndThrowRuntimeException(String errorMessage, Exception e) {
715 if (ObjectUtils.isNotNull(e)) {
716 LOG.error(errorMessage, e);
717 throw new RuntimeException(errorMessage, e);
718 } else {
719 LOG.error(errorMessage);
720 throw new RuntimeException(errorMessage);
721 }
722 }
723
724
725
726
727 @Override
728 public boolean hasActiveCreditMemosForPurchaseOrder(Integer purchaseOrderIdentifier) {
729
730 boolean hasActiveCreditMemos = false;
731 List<String> docNumbers = null;
732 WorkflowDocument workflowDocument = null;
733
734 docNumbers = creditMemoDao.getActiveCreditMemoDocumentNumbersForPurchaseOrder(purchaseOrderIdentifier);
735 docNumbers = filterCreditMemoByAppDocStatus(docNumbers, CreditMemoStatuses.STATUSES_POTENTIALLY_ACTIVE);
736
737 for (String docNumber : docNumbers) {
738 try {
739 workflowDocument = workflowDocumentService.loadWorkflowDocument(docNumber, GlobalVariables.getUserSession().getPerson());
740 } catch (WorkflowException we) {
741 throw new RuntimeException(we);
742 }
743
744
745 if (!(workflowDocument.isCanceled() ||
746 workflowDocument.isException() ||
747 workflowDocument.isFinal())) {
748 hasActiveCreditMemos = true;
749 break;
750 }
751
752 }
753
754 return hasActiveCreditMemos;
755 }
756
757
758
759
760 @Override
761 public void populateDocumentAfterInit(VendorCreditMemoDocument cmDocument) {
762
763 OleVendorCreditMemoDocument vendorCreditMemoDocument = (OleVendorCreditMemoDocument) cmDocument;
764
765 HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList = accountsPayableService.getExpiredOrClosedAccountList(cmDocument);
766
767 if (vendorCreditMemoDocument.isSourceDocumentPaymentRequest() && vendorCreditMemoDocument.getInvoiceIdentifier() == null) {
768 populateDocumentFromPreq(vendorCreditMemoDocument, expiredOrClosedAccountList);
769 } else if (vendorCreditMemoDocument.isSourceDocumentPurchaseOrder() && vendorCreditMemoDocument.getInvoiceIdentifier() == null) {
770 populateDocumentFromPO(vendorCreditMemoDocument, expiredOrClosedAccountList);
771 } else if (vendorCreditMemoDocument.getInvoiceIdentifier() != null) {
772 populateDocumentFromVendor(vendorCreditMemoDocument);
773 }
774
775 populateDocumentDescription(vendorCreditMemoDocument);
776
777
778
779 accountsPayableService.generateExpiredOrClosedAccountNote(cmDocument, expiredOrClosedAccountList);
780
781
782 if (ObjectUtils.isNotNull(expiredOrClosedAccountList) && !expiredOrClosedAccountList.isEmpty()) {
783 cmDocument.setContinuationAccountIndicator(true);
784 }
785
786 }
787
788
789
790
791
792
793 protected void populateDocumentFromPreq(VendorCreditMemoDocument cmDocument, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
794 PaymentRequestDocument paymentRequestDocument = paymentRequestService.getPaymentRequestById(cmDocument.getPaymentRequestIdentifier());
795 cmDocument.getDocumentHeader().setOrganizationDocumentNumber(paymentRequestDocument.getDocumentHeader().getOrganizationDocumentNumber());
796 cmDocument.setPaymentRequestDocument(paymentRequestDocument);
797 cmDocument.setPurchaseOrderDocument(paymentRequestDocument.getPurchaseOrderDocument());
798 cmDocument.setUseTaxIndicator(paymentRequestDocument.isUseTaxIndicator());
799
800
801 cmDocument.setVendorHeaderGeneratedIdentifier(paymentRequestDocument.getVendorHeaderGeneratedIdentifier());
802 cmDocument.setVendorDetailAssignedIdentifier(paymentRequestDocument.getVendorDetailAssignedIdentifier());
803 cmDocument.setVendorAddressGeneratedIdentifier(paymentRequestDocument.getVendorAddressGeneratedIdentifier());
804 cmDocument.setVendorCustomerNumber(paymentRequestDocument.getVendorCustomerNumber());
805 cmDocument.setVendorName(paymentRequestDocument.getVendorName());
806 cmDocument.setVendorLine1Address(paymentRequestDocument.getVendorLine1Address());
807 cmDocument.setVendorLine2Address(paymentRequestDocument.getVendorLine2Address());
808 cmDocument.setVendorCityName(paymentRequestDocument.getVendorCityName());
809 cmDocument.setVendorStateCode(paymentRequestDocument.getVendorStateCode());
810 cmDocument.setVendorPostalCode(paymentRequestDocument.getVendorPostalCode());
811 cmDocument.setVendorCountryCode(paymentRequestDocument.getVendorCountryCode());
812 cmDocument.setVendorAttentionName(paymentRequestDocument.getVendorAttentionName());
813 cmDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(paymentRequestDocument.getAccountsPayablePurchasingDocumentLinkIdentifier());
814 cmDocument.setPaymentMethodId(paymentRequestDocument.getVendorDetail().getPaymentMethodId());
815
816 purapAccountingService.convertMoneyToPercent(paymentRequestDocument);
817 populateItemLinesFromPreq(cmDocument, expiredOrClosedAccountList);
818 }
819
820
821
822
823
824
825 protected void populateItemLinesFromPreq(VendorCreditMemoDocument cmDocument, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
826 PaymentRequestDocument preqDocument = cmDocument.getPaymentRequestDocument();
827
828 for (PaymentRequestItem preqItemToTemplate : (List<PaymentRequestItem>) preqDocument.getItems()) {
829 preqItemToTemplate.refreshReferenceObject(PurapPropertyConstants.ITEM_TYPE);
830
831 if (preqItemToTemplate.getItemType().isLineItemIndicator() && ((preqItemToTemplate.getItemType().isQuantityBasedGeneralLedgerIndicator() && preqItemToTemplate.getItemQuantity().isNonZero())
832 || (preqItemToTemplate.getItemType().isAmountBasedGeneralLedgerIndicator() && preqItemToTemplate.getTotalAmount().isNonZero()))) {
833 cmDocument.getItems().add(new CreditMemoItem(cmDocument, preqItemToTemplate, preqItemToTemplate.getPurchaseOrderItem(), expiredOrClosedAccountList));
834 }
835 }
836
837
838 purapService.addBelowLineItems(cmDocument);
839
840 cmDocument.fixItemReferences();
841 }
842
843
844
845
846
847
848 protected void populateDocumentFromPO(VendorCreditMemoDocument cmDocument, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
849 PurchaseOrderDocument purchaseOrderDocument = purchaseOrderService.getCurrentPurchaseOrder(cmDocument.getPurchaseOrderIdentifier());
850 cmDocument.setPurchaseOrderDocument(purchaseOrderDocument);
851 cmDocument.getDocumentHeader().setOrganizationDocumentNumber(purchaseOrderDocument.getDocumentHeader().getOrganizationDocumentNumber());
852 cmDocument.setUseTaxIndicator(cmDocument.isUseTaxIndicator());
853
854 cmDocument.setVendorHeaderGeneratedIdentifier(purchaseOrderDocument.getVendorHeaderGeneratedIdentifier());
855 cmDocument.setVendorDetailAssignedIdentifier(purchaseOrderDocument.getVendorDetailAssignedIdentifier());
856 cmDocument.setVendorCustomerNumber(purchaseOrderDocument.getVendorCustomerNumber());
857 cmDocument.setVendorName(purchaseOrderDocument.getVendorName());
858 cmDocument.setAccountsPayablePurchasingDocumentLinkIdentifier(purchaseOrderDocument.getAccountsPayablePurchasingDocumentLinkIdentifier());
859 cmDocument.setPaymentMethodId(purchaseOrderDocument.getVendorDetail().getPaymentMethodId());
860
861 String userCampus = GlobalVariables.getUserSession().getPerson().getCampusCode();
862 VendorAddress vendorAddress = vendorService.getVendorDefaultAddress(purchaseOrderDocument.getVendorHeaderGeneratedIdentifier(), purchaseOrderDocument.getVendorDetailAssignedIdentifier(), VendorConstants.AddressTypes.REMIT, userCampus);
863 if (vendorAddress != null) {
864 cmDocument.templateVendorAddress(vendorAddress);
865 cmDocument.setVendorAddressGeneratedIdentifier(vendorAddress.getVendorAddressGeneratedIdentifier());
866 cmDocument.setVendorAttentionName(StringUtils.defaultString(vendorAddress.getVendorAttentionName()));
867 } else {
868
869 cmDocument.setVendorAddressGeneratedIdentifier(purchaseOrderDocument.getVendorAddressGeneratedIdentifier());
870 cmDocument.setVendorLine1Address(purchaseOrderDocument.getVendorLine1Address());
871 cmDocument.setVendorLine2Address(purchaseOrderDocument.getVendorLine2Address());
872 cmDocument.setVendorCityName(purchaseOrderDocument.getVendorCityName());
873 cmDocument.setVendorStateCode(purchaseOrderDocument.getVendorStateCode());
874 cmDocument.setVendorPostalCode(purchaseOrderDocument.getVendorPostalCode());
875 cmDocument.setVendorCountryCode(purchaseOrderDocument.getVendorCountryCode());
876
877 boolean blankAttentionLine = StringUtils.equalsIgnoreCase("Y", SpringContext.getBean(ParameterService.class).getParameterValueAsString(PurapConstants.PURAP_NAMESPACE, "Document", PurapParameterConstants.BLANK_ATTENTION_LINE_FOR_PO_TYPE_ADDRESS));
878 if (blankAttentionLine) {
879 cmDocument.setVendorAttentionName(StringUtils.EMPTY);
880 } else {
881 cmDocument.setVendorAttentionName(StringUtils.defaultString(purchaseOrderDocument.getVendorAttentionName()));
882 }
883 }
884
885 populateItemLinesFromPO(cmDocument, expiredOrClosedAccountList);
886 }
887
888
889
890
891
892
893 protected void populateItemLinesFromPO(VendorCreditMemoDocument cmDocument, HashMap<String, ExpiredOrClosedAccountEntry> expiredOrClosedAccountList) {
894 List<PurchaseOrderItem> invoicedItems = getPOInvoicedItems(cmDocument.getPurchaseOrderDocument());
895 for (PurchaseOrderItem poItem : invoicedItems) {
896 if ((poItem.getItemType().isQuantityBasedGeneralLedgerIndicator() && poItem.getItemInvoicedTotalQuantity().isNonZero())
897 || (poItem.getItemType().isAmountBasedGeneralLedgerIndicator() && poItem.getItemInvoicedTotalAmount().isNonZero())) {
898 CreditMemoItem creditMemoItem = new CreditMemoItem(cmDocument, poItem, expiredOrClosedAccountList);
899 cmDocument.getItems().add(creditMemoItem);
900 PurchasingCapitalAssetItem purchasingCAMSItem = cmDocument.getPurchaseOrderDocument().getPurchasingCapitalAssetItemByItemIdentifier(poItem.getItemIdentifier());
901 if (purchasingCAMSItem != null) {
902 creditMemoItem.setCapitalAssetTransactionTypeCode(purchasingCAMSItem.getCapitalAssetTransactionTypeCode());
903 }
904 }
905 }
906
907
908 purapService.addBelowLineItems(cmDocument);
909
910 cmDocument.fixItemReferences();
911 }
912
913
914
915
916
917
918 protected void populateDocumentFromVendor(VendorCreditMemoDocument cmDocument) {
919 Integer vendorHeaderId = VendorUtils.getVendorHeaderId(cmDocument.getVendorNumber());
920 Integer vendorDetailId = VendorUtils.getVendorDetailId(cmDocument.getVendorNumber());
921
922 VendorDetail vendorDetail = vendorService.getVendorDetail(vendorHeaderId, vendorDetailId);
923 cmDocument.setVendorDetail(vendorDetail);
924
925 cmDocument.setVendorHeaderGeneratedIdentifier(vendorDetail.getVendorHeaderGeneratedIdentifier());
926 cmDocument.setVendorDetailAssignedIdentifier(vendorDetail.getVendorDetailAssignedIdentifier());
927 cmDocument.setVendorCustomerNumber(vendorDetail.getVendorNumber());
928 cmDocument.setVendorName(vendorDetail.getVendorName());
929 cmDocument.setPaymentMethodId(vendorDetail.getPaymentMethodId());
930
931
932 String userCampus = GlobalVariables.getUserSession().getPerson().getCampusCode();
933 VendorAddress vendorAddress = vendorService.getVendorDefaultAddress(vendorHeaderId, vendorDetailId, VendorConstants.AddressTypes.REMIT, userCampus);
934 if (vendorAddress == null) {
935
936 vendorAddress = vendorService.getVendorDefaultAddress(vendorHeaderId, vendorDetailId, VendorConstants.AddressTypes.PURCHASE_ORDER, userCampus);
937 }
938
939 cmDocument.setVendorAddressGeneratedIdentifier(vendorAddress.getVendorAddressGeneratedIdentifier());
940 cmDocument.templateVendorAddress(vendorAddress);
941
942
943 purapService.addBelowLineItems(cmDocument);
944 }
945
946
947
948
949
950
951 protected void populateDocumentDescription(VendorCreditMemoDocument cmDocument) {
952 String description = "";
953 if (cmDocument.isSourceVendor()) {
954 description = "Vendor: " + cmDocument.getVendorName();
955 } else {
956 description = "PO: " + cmDocument.getPurchaseOrderDocument().getPurapDocumentIdentifier() + " Vendor: " + cmDocument.getVendorName();
957 }
958
959
960 int noteTextMaxLength = dataDictionaryService.getAttributeMaxLength(DocumentHeader.class, KRADPropertyConstants.DOCUMENT_DESCRIPTION).intValue();
961 if (noteTextMaxLength < description.length()) {
962 description = description.substring(0, noteTextMaxLength);
963 }
964
965 cmDocument.getDocumentHeader().setDocumentDescription(description);
966 }
967
968 }
969