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 }