001 /*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kfs.module.ar.document.web.struts;
017
018 import java.io.ByteArrayOutputStream;
019 import java.io.File;
020 import java.util.ArrayList;
021 import java.util.Iterator;
022 import java.util.List;
023
024 import javax.servlet.ServletOutputStream;
025 import javax.servlet.http.HttpServletRequest;
026 import javax.servlet.http.HttpServletResponse;
027
028 import org.apache.struts.action.ActionForm;
029 import org.apache.struts.action.ActionForward;
030 import org.apache.struts.action.ActionMapping;
031 import org.kuali.kfs.module.ar.businessobject.CustomerCreditMemoDetail;
032 import org.kuali.kfs.module.ar.document.CustomerCreditMemoDocument;
033 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
034 import org.kuali.kfs.module.ar.document.service.CustomerCreditMemoDetailService;
035 import org.kuali.kfs.module.ar.document.service.CustomerCreditMemoDocumentService;
036 import org.kuali.kfs.module.ar.document.validation.event.ContinueCustomerCreditMemoDocumentEvent;
037 import org.kuali.kfs.module.ar.document.validation.event.RecalculateCustomerCreditMemoDetailEvent;
038 import org.kuali.kfs.module.ar.document.validation.event.RecalculateCustomerCreditMemoDocumentEvent;
039 import org.kuali.kfs.module.ar.report.service.AccountsReceivableReportService;
040 import org.kuali.kfs.module.ar.web.struts.CustomerStatementForm;
041 import org.kuali.kfs.sys.KFSConstants;
042 import org.kuali.kfs.sys.context.SpringContext;
043 import org.kuali.rice.kew.exception.WorkflowException;
044 import org.kuali.rice.kns.service.DataDictionaryService;
045 import org.kuali.rice.kns.service.DocumentService;
046 import org.kuali.rice.kns.service.KualiRuleService;
047 import org.kuali.rice.kns.util.KualiDecimal;
048 import org.kuali.rice.kns.util.WebUtils;
049 import org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase;
050 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
051
052 import com.lowagie.text.Document;
053 import com.lowagie.text.pdf.PdfCopy;
054 import com.lowagie.text.pdf.PdfImportedPage;
055 import com.lowagie.text.pdf.PdfReader;
056 import com.lowagie.text.pdf.SimpleBookmark;
057
058 public class CustomerCreditMemoDocumentAction extends KualiTransactionalDocumentActionBase {
059
060 public CustomerCreditMemoDocumentAction() {
061 super();
062 }
063
064 /**
065 * Do initialization for a new customer credit memo.
066 *
067 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase)
068 */
069 @Override
070 protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
071 super.createDocument(kualiDocumentFormBase);
072 ((CustomerCreditMemoDocument) kualiDocumentFormBase.getDocument()).initiateDocument();
073 }
074
075 /**
076 * This method loads the document by its provided document header id. This has been abstracted out so that it can be overridden
077 * in children if the need arises.
078 *
079 * @param kualiDocumentFormBase
080 * @throws WorkflowException
081 */
082 @Override
083 protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
084 super.loadDocument(kualiDocumentFormBase);
085 ((CustomerCreditMemoDocument)kualiDocumentFormBase.getDocument()).populateCustomerCreditMemoDetailsAfterLoad();
086 }
087
088 /**
089 * Clears out init tab.
090 *
091 * @param mapping An ActionMapping
092 * @param form An ActionForm
093 * @param request The HttpServletRequest
094 * @param response The HttpServletResponse
095 * @throws Exception
096 * @return An ActionForward
097 */
098 public ActionForward clearInitTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
099
100 CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form;
101 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) customerCreditMemoDocumentForm.getDocument();
102 customerCreditMemoDocument.clearInitFields();
103
104 return super.refresh(mapping, form, request, response);
105 }
106
107 /**
108 * Handles continue request. This request comes from the initial screen which gives ref. invoice number.
109 * Based on that, the customer credit memo is initially populated.
110 *
111 * @param mapping An ActionMapping
112 * @param form An ActionForm
113 * @param request The HttpServletRequest
114 * @param response The HttpServletResponse
115 * @throws Exception
116 * @return An ActionForward
117 */
118 public ActionForward continueCreditMemo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
119
120 CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form;
121 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) customerCreditMemoDocumentForm.getDocument();
122
123 String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME;
124 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new ContinueCustomerCreditMemoDocumentEvent(errorPath,customerCreditMemoDocument));
125 if (rulePassed)
126 customerCreditMemoDocument.populateCustomerCreditMemoDetails();
127
128 return mapping.findForward(KFSConstants.MAPPING_BASIC);
129 }
130
131 /**
132 * Based on user input this method recalculates a customer credit memo detail
133 *
134 * @param mapping action mapping
135 * @param form action form
136 * @param request
137 * @param response
138 * @return action forward
139 * @throws Exception
140 */
141 public ActionForward recalculateCustomerCreditMemoDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
142
143 CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form;
144 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocumentForm.getDocument();
145
146 int indexOfLineToRecalculate = getSelectedLine(request);
147 CustomerCreditMemoDetail customerCreditMemoDetail = customerCreditMemoDocument.getCreditMemoDetails().get(indexOfLineToRecalculate);
148
149 String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSConstants.CUSTOMER_CREDIT_MEMO_DETAIL_PROPERTY_NAME + "[" + indexOfLineToRecalculate + "]";
150
151 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new RecalculateCustomerCreditMemoDetailEvent(errorPath, customerCreditMemoDocument, customerCreditMemoDetail));
152 if (rulePassed) {
153 CustomerCreditMemoDetailService customerCreditMemoDetailService = SpringContext.getBean(CustomerCreditMemoDetailService.class);
154 customerCreditMemoDetailService.recalculateCustomerCreditMemoDetail(customerCreditMemoDetail,customerCreditMemoDocument);
155 } else {
156 customerCreditMemoDocument.recalculateTotals(customerCreditMemoDetail);
157 }
158 return mapping.findForward(KFSConstants.MAPPING_BASIC);
159 }
160
161 /**
162 * This method refreshes a customer credit memo detail
163 *
164 * @param mapping action mapping
165 * @param form action form
166 * @param request
167 * @param response
168 * @return action forward
169 * @throws Exception
170 */
171 public ActionForward refreshCustomerCreditMemoDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
172
173 CustomerCreditMemoDocumentForm customerCreditMemoDocForm = (CustomerCreditMemoDocumentForm) form;
174 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocForm.getDocument();
175 int indexOfLineToRefresh = getSelectedLine(request);
176
177 CustomerCreditMemoDetail customerCreditMemoDetail = customerCreditMemoDocument.getCreditMemoDetails().get(indexOfLineToRefresh);
178
179 customerCreditMemoDetail.setCreditMemoItemQuantity(null);
180 customerCreditMemoDetail.setCreditMemoItemTotalAmount(null);
181 customerCreditMemoDetail.setCreditMemoItemTaxAmount(KualiDecimal.ZERO);
182 customerCreditMemoDetail.setCreditMemoLineTotalAmount(KualiDecimal.ZERO);
183
184 customerCreditMemoDocument.recalculateTotals(customerCreditMemoDetail);
185
186 return mapping.findForward(KFSConstants.MAPPING_BASIC);
187 }
188
189 /**
190 * This method refreshes customer credit memo details and line with totals
191 *
192 * @param mapping action mapping
193 * @param form action form
194 * @param request
195 * @param response
196 * @return action forward
197 * @throws Exception
198 */
199 public ActionForward refreshCustomerCreditMemoDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
200 CustomerCreditMemoDocumentForm customerCreditMemoDocForm = (CustomerCreditMemoDocumentForm) form;
201 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocForm.getDocument();
202
203 List<CustomerCreditMemoDetail> customerCreditMemoDetails = customerCreditMemoDocument.getCreditMemoDetails();
204 for( CustomerCreditMemoDetail customerCreditMemoDetail : customerCreditMemoDetails ){
205 customerCreditMemoDetail.setCreditMemoItemQuantity(null);
206 customerCreditMemoDetail.setCreditMemoItemTotalAmount(null);
207 customerCreditMemoDetail.setCreditMemoItemTaxAmount(KualiDecimal.ZERO);
208 customerCreditMemoDetail.setCreditMemoLineTotalAmount(KualiDecimal.ZERO);
209 customerCreditMemoDetail.setDuplicateCreditMemoItemTotalAmount(null);
210 }
211 customerCreditMemoDocument.setCrmTotalItemAmount(KualiDecimal.ZERO);
212 customerCreditMemoDocument.setCrmTotalTaxAmount(KualiDecimal.ZERO);
213 customerCreditMemoDocument.setCrmTotalAmount(KualiDecimal.ZERO);
214
215 return mapping.findForward(KFSConstants.MAPPING_BASIC);
216 }
217
218 /**
219 * Based on user input this method recalculates customer credit memo document <=> all customer credit memo details
220 *
221 * @param mapping action mapping
222 * @param form action form
223 * @param request
224 * @param response
225 * @return action forward
226 * @throws Exception
227 */
228 public ActionForward recalculateCustomerCreditMemoDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
229
230 CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form;
231 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocumentForm.getDocument();
232
233 String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME;
234 boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new RecalculateCustomerCreditMemoDocumentEvent(errorPath,customerCreditMemoDocument,false));
235 if (rulePassed) {
236 CustomerCreditMemoDocumentService customerCreditMemoDocumentService = SpringContext.getBean(CustomerCreditMemoDocumentService.class);
237 customerCreditMemoDocumentService.recalculateCustomerCreditMemoDocument(customerCreditMemoDocument,false);
238 }
239 return mapping.findForward(KFSConstants.MAPPING_BASIC);
240 }
241
242 /**
243 *
244 * This method...
245 * @param mapping
246 * @param form
247 * @param request
248 * @param response
249 * @return
250 * @throws Exception
251 */
252 public ActionForward print(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
253 String basePath = getBasePath(request);
254 String docId = ((CustomerCreditMemoDocumentForm) form).getDocument().getDocumentNumber();
255 String methodToCallPrintCreditMemoPDF = "printCreditMemoPDF";
256 String methodToCallDocHandler = "docHandler";
257 String printCreditMemoPDFUrl = getUrlForPrintCreditMemo(basePath, docId, methodToCallPrintCreditMemoPDF);
258 String displayInvoiceTabbedPageUrl = getUrlForPrintCreditMemo(basePath, docId, methodToCallDocHandler);
259
260 request.setAttribute("printPDFUrl", printCreditMemoPDFUrl);
261 request.setAttribute("displayTabbedPageUrl", displayInvoiceTabbedPageUrl);
262 request.setAttribute("docId", docId);
263 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.CUSTOMER_CREDIT_MEMO);
264 request.setAttribute("printLabel", label);
265 return mapping.findForward("arPrintPDF");
266
267 }
268
269 /**
270 *
271 * This method...
272 * @param mapping
273 * @param form
274 * @param request
275 * @param response
276 * @return
277 * @throws Exception
278 */
279 public ActionForward printCreditMemoPDF(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
280 String creditMemoDocId = request.getParameter(KFSConstants.PARAMETER_DOC_ID);
281 CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(creditMemoDocId);
282
283 AccountsReceivableReportService reportService = SpringContext.getBean(AccountsReceivableReportService.class);
284 File report = reportService.generateCreditMemo(customerCreditMemoDocument);
285
286 StringBuilder fileName = new StringBuilder();
287 fileName.append(customerCreditMemoDocument.getFinancialDocumentReferenceInvoiceNumber());
288 fileName.append("-");
289 fileName.append(customerCreditMemoDocument.getDocumentNumber());
290 fileName.append(".pdf");
291
292 if (report.length() == 0) {
293 //csForm.setMessage("No Report Generated");
294 return mapping.findForward(KFSConstants.MAPPING_BASIC);
295 }
296
297 ByteArrayOutputStream baos = new ByteArrayOutputStream();
298 String contentDisposition = "";
299 try {
300 ArrayList master = new ArrayList();
301 PdfCopy writer = null;
302
303 // create a reader for the document
304 String reportName = report.getAbsolutePath();
305 PdfReader reader = new PdfReader(reportName);
306 reader.consolidateNamedDestinations();
307
308 // retrieve the total number of pages
309 int n = reader.getNumberOfPages();
310 List bookmarks = SimpleBookmark.getBookmark(reader);
311 if (bookmarks != null)
312 master.addAll(bookmarks);
313
314 // step 1: create a document-object
315 Document document = new Document(reader.getPageSizeWithRotation(1));
316 // step 2: create a writer that listens to the document
317 writer = new PdfCopy(document, baos);
318 // step 3: open the document
319 document.open();
320 // step 4: add content
321 PdfImportedPage page;
322 for (int i = 0; i < n; ) {
323 ++i;
324 page = writer.getImportedPage(reader, i);
325 writer.addPage(page);
326 }
327 writer.freeReader(reader);
328 if (!master.isEmpty())
329 writer.setOutlines(master);
330 // step 5: we close the document
331 document.close();
332
333 StringBuffer sbContentDispValue = new StringBuffer();
334 String useJavascript = request.getParameter("useJavascript");
335 if (useJavascript == null || useJavascript.equalsIgnoreCase("false")) {
336 sbContentDispValue.append("attachment");
337 }
338 else {
339 sbContentDispValue.append("inline");
340 }
341 sbContentDispValue.append("; filename=");
342 sbContentDispValue.append(fileName);
343
344 contentDisposition = sbContentDispValue.toString();
345 }
346 catch(Exception e) {
347 e.printStackTrace();
348 }
349
350 response.setContentType("application/pdf");
351 response.setHeader("Content-Disposition", contentDisposition);
352 response.setHeader("Expires", "0");
353 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
354 response.setHeader("Pragma", "public");
355 response.setContentLength(baos.size());
356
357 // write to output
358 ServletOutputStream sos;
359 sos = response.getOutputStream();
360 baos.writeTo(sos);
361 sos.flush();
362 sos.close();
363
364 return null;
365 }
366
367 /**
368 * Creates a URL to be used in printing the customer credit memo.
369 *
370 * @param basePath String: The base path of the current URL
371 * @param docId String: The document ID of the document to be printed
372 * @param methodToCall String: The name of the method that will be invoked to do this particular print
373 * @return The URL
374 */
375 protected String getUrlForPrintCreditMemo(String basePath, String docId, String methodToCall) {
376 StringBuffer result = new StringBuffer(basePath);
377 result.append("/arCustomerCreditMemoDocument.do?methodToCall=");
378 result.append(methodToCall);
379 result.append("&docId=");
380 result.append(docId);
381 result.append("&command=displayDocSearchView");
382
383 return result.toString();
384 }
385
386
387 }