1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.module.ar.document.service.impl;
20
21 import java.math.BigDecimal;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.kuali.kfs.module.ar.businessobject.CustomerCreditMemoDetail;
28 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
29 import org.kuali.kfs.module.ar.businessobject.InvoicePaidApplied;
30 import org.kuali.kfs.module.ar.document.CustomerCreditMemoDocument;
31 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
32 import org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService;
33 import org.kuali.kfs.module.ar.document.service.CustomerCreditMemoDocumentService;
34 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService;
35 import org.kuali.kfs.module.ar.document.service.InvoicePaidAppliedService;
36 import org.kuali.kfs.sys.service.UniversityDateService;
37 import org.kuali.rice.core.api.datetime.DateTimeService;
38 import org.kuali.rice.core.api.util.type.KualiDecimal;
39 import org.kuali.rice.kew.api.exception.WorkflowException;
40 import org.kuali.rice.krad.service.BusinessObjectService;
41 import org.kuali.rice.krad.service.DocumentService;
42 import org.kuali.rice.krad.util.ObjectUtils;
43 import org.springframework.transaction.annotation.Transactional;
44
45 @Transactional
46 public class CustomerCreditMemoDocumentServiceImpl implements CustomerCreditMemoDocumentService {
47
48 private DocumentService documentService;
49 private InvoicePaidAppliedService<CustomerInvoiceDetail> paidAppliedService;
50 private UniversityDateService universityDateService;
51 private BusinessObjectService businessObjectService;
52 private DateTimeService dateTimeService;
53 protected CustomerInvoiceDocumentService customerInvoiceDocumentService;
54
55 private AccountsReceivableTaxService accountsReceivableTaxService;
56
57 @Override
58 public void completeCustomerCreditMemo(CustomerCreditMemoDocument creditMemo) {
59
60
61 String invoiceNumber = creditMemo.getFinancialDocumentReferenceInvoiceNumber();
62 CustomerInvoiceDocument invoice;
63 try {
64 invoice = (CustomerInvoiceDocument) documentService.getByDocumentHeaderId(invoiceNumber);
65 }
66 catch (WorkflowException e) {
67 throw new RuntimeException("A WorkflowException was generated when trying to load Customer Invoice #" + invoiceNumber + ".", e);
68 }
69 if (!invoice.isOpenInvoiceIndicator()) {
70 throw new UnsupportedOperationException("The CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted to credit " +
71 "an Invoice [#" + invoiceNumber + "] that was already closed. This is not supported.");
72 }
73
74
75
76
77
78
79 KualiDecimal openAmount = invoice.getOpenAmount();
80
81 Integer paidAppliedItemNumber = 0;
82
83
84 List<CustomerCreditMemoDetail> details = creditMemo.getCreditMemoDetails();
85 for (CustomerCreditMemoDetail detail : details) {
86 CustomerInvoiceDetail invoiceDetail = detail.getCustomerInvoiceDetail();
87
88
89 if (detail.getCreditMemoLineTotalAmount().isZero()) {
90 continue;
91 }
92
93
94 if (detail.getCreditMemoLineTotalAmount().abs().isGreaterThan(invoiceDetail.getAmountOpen())) {
95 throw new UnsupportedOperationException("The credit detail for CreditMemo Document #" + creditMemo.getDocumentNumber() + " attempted " +
96 "to credit more than the Open Amount on the Invoice Detail. This is not supported.");
97 }
98
99
100 if (paidAppliedItemNumber == 0) {
101 paidAppliedItemNumber = paidAppliedService.getNumberOfInvoicePaidAppliedsForInvoiceDetail(invoiceNumber,
102 invoiceDetail.getInvoiceItemNumber());
103 }
104
105
106
107 InvoicePaidApplied invoicePaidApplied = new InvoicePaidApplied();
108 invoicePaidApplied.setDocumentNumber(creditMemo.getDocumentNumber());
109 invoicePaidApplied.setPaidAppliedItemNumber(paidAppliedItemNumber++);
110 invoicePaidApplied.setFinancialDocumentReferenceInvoiceNumber(invoiceNumber);
111 invoicePaidApplied.setInvoiceItemNumber(invoiceDetail.getInvoiceItemNumber());
112 invoicePaidApplied.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear());
113 invoicePaidApplied.setUniversityFiscalPeriodCode(universityDateService.getCurrentUniversityDate().getUniversityFiscalAccountingPeriod());
114 invoicePaidApplied.setInvoiceItemAppliedAmount(detail.getCreditMemoLineTotalAmount().abs());
115 openAmount = openAmount.subtract(detail.getCreditMemoLineTotalAmount().abs());
116 businessObjectService.save(invoicePaidApplied);
117 }
118
119
120 if (invoice.isOpenInvoiceIndicator() && KualiDecimal.ZERO.equals(openAmount)) {
121 customerInvoiceDocumentService.addCloseNote(invoice, creditMemo.getDocumentHeader().getWorkflowDocument());
122 invoice.setOpenInvoiceIndicator(false);
123 invoice.setClosedDate(dateTimeService.getCurrentSqlDate());
124 documentService.updateDocument(invoice);
125 }
126 }
127
128 @Override
129 public void recalculateCustomerCreditMemoDocument(CustomerCreditMemoDocument customerCreditMemoDocument, boolean blanketApproveDocumentEventFlag) {
130 KualiDecimal customerCreditMemoDetailItemAmount;
131 BigDecimal itemQuantity;
132
133 String invDocumentNumber = customerCreditMemoDocument.getFinancialDocumentReferenceInvoiceNumber();
134 List<CustomerCreditMemoDetail> customerCreditMemoDetails = customerCreditMemoDocument.getCreditMemoDetails();
135
136 if (!blanketApproveDocumentEventFlag) {
137 customerCreditMemoDocument.resetTotals();
138 }
139
140 for (CustomerCreditMemoDetail customerCreditMemoDetail:customerCreditMemoDetails) {
141
142 itemQuantity = customerCreditMemoDetail.getCreditMemoItemQuantity();
143 customerCreditMemoDetailItemAmount = customerCreditMemoDetail.getCreditMemoItemTotalAmount();
144 if (ObjectUtils.isNull(itemQuantity) && ObjectUtils.isNull(customerCreditMemoDetailItemAmount)) {
145 if (!blanketApproveDocumentEventFlag) {
146 customerCreditMemoDetail.setDuplicateCreditMemoItemTotalAmount(null);
147 }
148 continue;
149 }
150
151
152 if (ObjectUtils.isNotNull(customerCreditMemoDetailItemAmount)) {
153 customerCreditMemoDetail.recalculateBasedOnEnteredItemAmount(customerCreditMemoDocument);
154 }
155 else {
156 customerCreditMemoDetail.recalculateBasedOnEnteredItemQty(customerCreditMemoDocument);
157 if (!blanketApproveDocumentEventFlag) {
158 customerCreditMemoDetailItemAmount = customerCreditMemoDetail.getCreditMemoItemTotalAmount();
159 }
160 }
161
162 if (!blanketApproveDocumentEventFlag) {
163 customerCreditMemoDetail.setDuplicateCreditMemoItemTotalAmount(customerCreditMemoDetailItemAmount);
164 boolean isCustomerInvoiceDetailTaxable = accountsReceivableTaxService.isCustomerInvoiceDetailTaxable(customerCreditMemoDocument.getInvoice(), customerCreditMemoDetail.getCustomerInvoiceDetail());
165 customerCreditMemoDocument.recalculateTotals(customerCreditMemoDetailItemAmount,isCustomerInvoiceDetailTaxable);
166 }
167 }
168
169
170 customerCreditMemoDocument.getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(customerCreditMemoDocument.getCrmTotalAmount());
171 }
172
173 @Override
174 public Collection<CustomerCreditMemoDocument> getCustomerCreditMemoDocumentByInvoiceDocument(String invoiceNumber) {
175 Map<String, String> fieldValues = new HashMap<String, String>();
176 fieldValues.put("financialDocumentReferenceInvoiceNumber", invoiceNumber);
177
178 Collection<CustomerCreditMemoDocument> creditMemos =
179 businessObjectService.findMatching(CustomerCreditMemoDocument.class, fieldValues);
180
181 return creditMemos;
182 }
183
184 @Override
185 public boolean isThereNoDataToSubmit(CustomerCreditMemoDocument customerCreditMemoDocument) {
186 boolean isSuccess = true;
187 KualiDecimal customerCreditMemoDetailItemAmount;
188 BigDecimal itemQuantity;
189 List<CustomerCreditMemoDetail> customerCreditMemoDetails = customerCreditMemoDocument.getCreditMemoDetails();
190
191 for (CustomerCreditMemoDetail customerCreditMemoDetail:customerCreditMemoDetails) {
192
193 itemQuantity = customerCreditMemoDetail.getCreditMemoItemQuantity();
194 customerCreditMemoDetailItemAmount = customerCreditMemoDetail.getCreditMemoItemTotalAmount();
195 if (ObjectUtils.isNotNull(itemQuantity) || ObjectUtils.isNotNull(customerCreditMemoDetailItemAmount)) {
196 isSuccess = false;
197 break;
198 }
199 }
200 return isSuccess;
201 }
202
203 public void setDocumentService(DocumentService documentService) {
204 this.documentService = documentService;
205 }
206
207 public void setPaidAppliedService(InvoicePaidAppliedService<CustomerInvoiceDetail> paidAppliedService) {
208 this.paidAppliedService = paidAppliedService;
209 }
210
211 public void setUniversityDateService(UniversityDateService universityDateService) {
212 this.universityDateService = universityDateService;
213 }
214
215 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
216 this.businessObjectService = businessObjectService;
217 }
218
219 public void setDateTimeService(DateTimeService dateTimeService) {
220 this.dateTimeService = dateTimeService;
221 }
222
223 public AccountsReceivableTaxService getAccountsReceivableTaxService() {
224 return accountsReceivableTaxService;
225 }
226
227 public void setAccountsReceivableTaxService(AccountsReceivableTaxService accountsReceivableTaxService) {
228 this.accountsReceivableTaxService = accountsReceivableTaxService;
229 }
230 public void setCustomerInvoiceDocumentService(CustomerInvoiceDocumentService customerInvoiceDocumentService) {
231 this.customerInvoiceDocumentService = customerInvoiceDocumentService;
232 }
233 }