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.List; 022 023 import javax.servlet.ServletOutputStream; 024 import javax.servlet.http.HttpServletRequest; 025 import javax.servlet.http.HttpServletResponse; 026 027 import org.apache.commons.lang.StringUtils; 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.coa.service.AccountService; 032 import org.kuali.kfs.module.ar.ArConstants; 033 import org.kuali.kfs.module.ar.businessobject.CustomerAddress; 034 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail; 035 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument; 036 import org.kuali.kfs.module.ar.document.service.CustomerAddressService; 037 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDetailService; 038 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService; 039 import org.kuali.kfs.module.ar.document.validation.event.DiscountCustomerInvoiceDetailEvent; 040 import org.kuali.kfs.module.ar.document.validation.event.RecalculateCustomerInvoiceDetailEvent; 041 import org.kuali.kfs.module.ar.report.service.AccountsReceivableReportService; 042 import org.kuali.kfs.sys.KFSConstants; 043 import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader; 044 import org.kuali.kfs.sys.context.SpringContext; 045 import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent; 046 import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase; 047 import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase; 048 import org.kuali.rice.kew.exception.WorkflowException; 049 import org.kuali.rice.kns.question.ConfirmationQuestion; 050 import org.kuali.rice.kns.service.DataDictionaryService; 051 import org.kuali.rice.kns.service.DocumentService; 052 import org.kuali.rice.kns.service.KualiRuleService; 053 import org.kuali.rice.kns.util.ObjectUtils; 054 import org.kuali.rice.kns.util.WebUtils; 055 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 056 import org.kuali.rice.kns.web.struts.form.KualiForm; 057 058 import com.lowagie.text.Document; 059 import com.lowagie.text.pdf.PdfCopy; 060 import com.lowagie.text.pdf.PdfImportedPage; 061 import com.lowagie.text.pdf.PdfReader; 062 import com.lowagie.text.pdf.SimpleBookmark; 063 064 public class CustomerInvoiceDocumentAction extends KualiAccountingDocumentActionBase { 065 066 067 /** 068 * Overriding to make it easier to distinguish discount lines and lines that are associated to discounts 069 * 070 * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#execute(org.apache.struts.action.ActionMapping, 071 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 072 */ 073 @Override 074 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 075 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 076 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 077 if(StringUtils.isBlank(customerInvoiceDocument.getDocumentNumber())) { 078 String docId = request.getParameter(KFSConstants.PARAMETER_DOC_ID); 079 customerInvoiceDocument.setDocumentNumber(docId); 080 customerInvoiceDocument.refresh(); 081 } 082 customerInvoiceDocument.updateAccountReceivableObjectCodes(); 083 try { 084 // proceed as usual 085 customerInvoiceDocumentForm.getCustomerInvoiceDocument().updateDiscountAndParentLineReferences(); 086 ActionForward result = super.execute(mapping, form, request, response); 087 return result; 088 } 089 finally { 090 // update it again for display purposes 091 customerInvoiceDocumentForm.getCustomerInvoiceDocument().updateDiscountAndParentLineReferences(); 092 } 093 } 094 095 /** 096 * Called when customer invoice document is initiated. 097 * 098 * Makes a call to parent's createDocument method, but also defaults values for customer invoice document. Line which inserts 099 * Customer Invoice Detail (i.e. insertSourceLine) has its values defaulted by 100 * CustomerInvoiceDocumentForm.createNewSourceAccountingLine() 101 * 102 * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#createDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase) 103 */ 104 @Override 105 protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { 106 super.createDocument(kualiDocumentFormBase); 107 108 // set up the default values for customer invoice document 109 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) kualiDocumentFormBase; 110 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 111 SpringContext.getBean(CustomerInvoiceDocumentService.class).setupDefaultValuesForNewCustomerInvoiceDocument(customerInvoiceDocument); 112 } 113 114 /** 115 * All document-load operations get routed through here 116 * 117 * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase) 118 */ 119 @Override 120 protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { 121 super.loadDocument(kualiDocumentFormBase); 122 123 CustomerInvoiceDocumentForm form = (CustomerInvoiceDocumentForm) kualiDocumentFormBase; 124 form.getCustomerInvoiceDocument().updateDiscountAndParentLineReferences(); 125 126 } 127 128 /** 129 * Method that will take the current document, copy it, replace all references to doc header id with a new one, clear pending 130 * entries, clear notes, and reset version numbers 131 * 132 * @param mapping 133 * @param form 134 * @param request 135 * @param response 136 * @return 137 * @throws Exception 138 */ 139 public ActionForward copy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 140 141 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 142 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 143 144 // perform discount check 145 ActionForward forward = performInvoiceWithDiscountsCheck(mapping, form, request, response, customerInvoiceDocument); 146 if (forward != null) { 147 return forward; 148 } 149 150 return super.copy(mapping, form, request, response); 151 } 152 153 154 /** 155 * This method checks if the user wants to copy a document that contains a discount line. If yes, this method returns null. If no, 156 * this method returns the "basic" forward. 157 * 158 * @param mapping 159 * @param form 160 * @param request 161 * @param response 162 * @param customerInvoiceDocument 163 * @return 164 * @throws Exception 165 */ 166 protected ActionForward performInvoiceWithDiscountsCheck(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, CustomerInvoiceDocument customerInvoiceDocument) throws Exception { 167 ActionForward forward = null; 168 169 if( customerInvoiceDocument.hasAtLeastOneDiscount() ){ 170 171 Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME); 172 if (question == null) { 173 return this.performQuestionWithoutInput(mapping, form, request, response, ArConstants.COPY_CUSTOMER_INVOICE_DOCUMENT_WITH_DISCOUNTS_QUESTION, 174 "This document contains a discount line. Are you sure you want to copy this document?", KFSConstants.CONFIRMATION_QUESTION, 175 KFSConstants.ROUTE_METHOD, ""); 176 } 177 178 Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); 179 if (ArConstants.COPY_CUSTOMER_INVOICE_DOCUMENT_WITH_DISCOUNTS_QUESTION.equals(question) && ConfirmationQuestion.NO.equals(buttonClicked)) { 180 forward = mapping.findForward(KFSConstants.MAPPING_BASIC); 181 } 182 } 183 184 return forward; 185 } 186 187 /** 188 * This method is the action for refreshing the added source line (or customer invoice detail) based off a provided invoice item 189 * code. 190 * 191 * @param mapping 192 * @param form 193 * @param request 194 * @param response 195 * @return 196 * @throws Exception 197 */ 198 public ActionForward refreshNewSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 199 200 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 201 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 202 CustomerInvoiceDetail newCustomerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocumentForm.getNewSourceLine(); 203 204 CustomerInvoiceDetailService customerInvoiceDetailService = SpringContext.getBean(CustomerInvoiceDetailService.class); 205 CustomerInvoiceDetail loadedCustomerInvoiceDetail = customerInvoiceDetailService.getCustomerInvoiceDetailFromCustomerInvoiceItemCode(newCustomerInvoiceDetail.getInvoiceItemCode(), customerInvoiceDocument.getBillByChartOfAccountCode(), customerInvoiceDocument.getBilledByOrganizationCode()); 206 if (loadedCustomerInvoiceDetail == null) { 207 loadedCustomerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocumentForm.getNewSourceLine(); 208 } 209 210 customerInvoiceDocumentForm.setNewSourceLine(loadedCustomerInvoiceDetail); 211 212 return mapping.findForward(KFSConstants.MAPPING_BASIC); 213 } 214 215 216 /** 217 * This method is the action for recalculating the amount added line assuming that the unit price or quantity has changed 218 * 219 * @param mapping 220 * @param form 221 * @param request 222 * @param response 223 * @return 224 * @throws Exception 225 */ 226 public ActionForward recalculateSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 227 228 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 229 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 230 231 int index = getSelectedLine(request); 232 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocument.getSourceAccountingLine(index); 233 234 String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME + "[" + index + "]"; 235 236 boolean rulePassed = true; 237 rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new RecalculateCustomerInvoiceDetailEvent(errorPath, customerInvoiceDocumentForm.getDocument(), customerInvoiceDetail)); 238 if (rulePassed) { 239 240 CustomerInvoiceDetailService customerInvoiceDetailService = SpringContext.getBean(CustomerInvoiceDetailService.class); 241 customerInvoiceDetailService.recalculateCustomerInvoiceDetail(customerInvoiceDocument, customerInvoiceDetail); 242 customerInvoiceDetailService.updateAccountsForCorrespondingDiscount(customerInvoiceDetail); 243 } 244 245 // Update the doc total 246 ((FinancialSystemDocumentHeader) customerInvoiceDocumentForm.getDocument().getDocumentHeader()).setFinancialDocumentTotalAmount(customerInvoiceDocument.getTotalDollarAmount()); 247 248 return mapping.findForward(KFSConstants.MAPPING_BASIC); 249 } 250 251 252 /** 253 * This method is used for inserting a discount line based on a selected source line. 254 * 255 * @param mapping 256 * @param form 257 * @param request 258 * @param response 259 * @return 260 * @throws Exception 261 */ 262 public ActionForward discountSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 263 264 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 265 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 266 267 int index = getSelectedLine(request); 268 CustomerInvoiceDetail parentCustomerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocument.getSourceAccountingLine(index); 269 270 // document.sourceAccountingLine[0].invoiceItemUnitPrice 271 String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME + "[" + index + "]"; 272 273 boolean rulePassed = true; 274 rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new DiscountCustomerInvoiceDetailEvent(errorPath, customerInvoiceDocumentForm.getDocument(), parentCustomerInvoiceDetail)); 275 if (rulePassed) { 276 277 CustomerInvoiceDetail discountCustomerInvoiceDetail = SpringContext.getBean(CustomerInvoiceDetailService.class).getDiscountCustomerInvoiceDetailForCurrentYear(parentCustomerInvoiceDetail, customerInvoiceDocument); 278 discountCustomerInvoiceDetail.refreshNonUpdateableReferences(); 279 insertAccountingLine(true, customerInvoiceDocumentForm, discountCustomerInvoiceDetail); 280 281 // also set parent customer invoice detail line to have discount line seq number 282 parentCustomerInvoiceDetail.setInvoiceItemDiscountLineNumber(discountCustomerInvoiceDetail.getSequenceNumber()); 283 } 284 285 return mapping.findForward(KFSConstants.MAPPING_BASIC); 286 } 287 288 289 /** 290 * Removed salesTax checking. Need to verify if this check has be moved out later of the KualiAccountingDocumentActionBase 291 * class. If so just use the parent class' insertSourceLine method. 292 * 293 * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#insertSourceLine(org.apache.struts.action.ActionMapping, 294 * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 295 */ 296 @Override 297 public ActionForward insertSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 298 299 CustomerInvoiceDocumentForm customerInvoiceDocumentForm = (CustomerInvoiceDocumentForm) form; 300 CustomerInvoiceDocument customerInvoiceDocument = customerInvoiceDocumentForm.getCustomerInvoiceDocument(); 301 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocumentForm.getNewSourceLine(); 302 303 // populate chartOfAccountsCode from account number if accounts cant cross chart and Javascript is turned off 304 //SpringContext.getBean(AccountService.class).populateAccountingLineChartIfNeeded(customerInvoiceDetail); 305 306 // make sure amount is up to date before rules 307 CustomerInvoiceDetailService service = SpringContext.getBean(CustomerInvoiceDetailService.class); 308 service.recalculateCustomerInvoiceDetail(customerInvoiceDocument, customerInvoiceDetail); 309 310 boolean rulePassed = true; 311 // check any business rules 312 rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AddAccountingLineEvent(KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME, customerInvoiceDocumentForm.getDocument(), customerInvoiceDetail)); 313 314 if (rulePassed) { 315 316 // add accountingLine 317 customerInvoiceDetail.refreshNonUpdateableReferences(); 318 service.prepareCustomerInvoiceDetailForAdd(customerInvoiceDetail, customerInvoiceDocument); 319 insertAccountingLine(true, customerInvoiceDocumentForm, customerInvoiceDetail); 320 321 // clear the used newTargetLine 322 customerInvoiceDocumentForm.setNewSourceLine(null); 323 } 324 325 return mapping.findForward(KFSConstants.MAPPING_BASIC); 326 } 327 328 329 /** 330 * Overrides method to delete accounting line. If line to be deleted has a corresponding discount line, the corresponding 331 * discount line is also deleted. If the line to be delete is a discount line, set the reference for the parent to null 332 * 333 * @param isSource 334 * @param financialDocumentForm 335 * @param deleteIndex 336 */ 337 @Override 338 protected void deleteAccountingLine(boolean isSource, KualiAccountingDocumentFormBase financialDocumentForm, int deleteIndex) { 339 340 CustomerInvoiceDocument customerInvoiceDocument = ((CustomerInvoiceDocumentForm) financialDocumentForm).getCustomerInvoiceDocument(); 341 342 // if line to delete is a discount parent discountLine, remove discount line too 343 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) customerInvoiceDocument.getSourceAccountingLine(deleteIndex); 344 if (customerInvoiceDetail.isDiscountLineParent()) { 345 customerInvoiceDocument.removeDiscountLineBasedOnParentLineIndex(deleteIndex); 346 } 347 else if (customerInvoiceDocument.isDiscountLineBasedOnSequenceNumber(customerInvoiceDetail.getSequenceNumber())) { 348 349 // if line to delete is a discount line, set discount line reference for parent to null 350 CustomerInvoiceDetail parentCustomerInvoiceDetail = customerInvoiceDetail.getParentDiscountCustomerInvoiceDetail(); 351 if (ObjectUtils.isNotNull(parentCustomerInvoiceDetail)) { 352 parentCustomerInvoiceDetail.setInvoiceItemDiscountLineNumber(null); 353 } 354 } 355 356 // delete line like normal 357 super.deleteAccountingLine(isSource, financialDocumentForm, deleteIndex); 358 } 359 360 @Override 361 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 362 super.refresh(mapping, form, request, response); 363 refreshBillToAddress(mapping, form, request, response); 364 refreshShipToAddress(mapping, form, request, response); 365 return mapping.findForward(KFSConstants.MAPPING_BASIC); 366 } 367 368 /** 369 * This method refresh the ShipToAddress CustomerAddress object 370 * @param mapping 371 * @param form 372 * @param request 373 * @param response 374 * @return 375 * @throws Exception 376 */ 377 public ActionForward refreshBillToAddress(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 378 379 CustomerInvoiceDocument customerInvoiceDocument = ((CustomerInvoiceDocumentForm) form).getCustomerInvoiceDocument(); 380 381 CustomerAddress customerBillToAddress = null; 382 if (ObjectUtils.isNotNull(customerInvoiceDocument.getCustomerBillToAddressIdentifier())) { 383 int customerBillToAddressIdentifier = customerInvoiceDocument.getCustomerBillToAddressIdentifier(); 384 385 customerBillToAddress = SpringContext.getBean(CustomerAddressService.class).getByPrimaryKey(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerBillToAddressIdentifier); 386 if (ObjectUtils.isNotNull(customerBillToAddress)) { 387 customerInvoiceDocument.setCustomerBillToAddress(customerBillToAddress); 388 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(customerBillToAddress); 389 customerInvoiceDocument.setCustomerBillToAddressIdentifier(customerBillToAddressIdentifier); 390 } else { 391 customerBillToAddress = SpringContext.getBean(CustomerAddressService.class).getPrimaryAddress(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber()); 392 393 if (ObjectUtils.isNotNull(customerBillToAddress)) { 394 customerInvoiceDocument.setCustomerBillToAddress(customerBillToAddress); 395 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(customerBillToAddress); 396 customerInvoiceDocument.setCustomerBillToAddressIdentifier(customerBillToAddress.getCustomerAddressIdentifier()); 397 } else { 398 customerInvoiceDocument.setCustomerBillToAddress(null); 399 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(null); 400 customerInvoiceDocument.setCustomerBillToAddressIdentifier(null); 401 } 402 } 403 404 } else { 405 customerBillToAddress = SpringContext.getBean(CustomerAddressService.class).getPrimaryAddress(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber()); 406 407 if (ObjectUtils.isNotNull(customerBillToAddress)) { 408 customerInvoiceDocument.setCustomerBillToAddress(customerBillToAddress); 409 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(customerBillToAddress); 410 customerInvoiceDocument.setCustomerBillToAddressIdentifier(customerBillToAddress.getCustomerAddressIdentifier()); 411 } else { 412 customerInvoiceDocument.setCustomerBillToAddress(null); 413 customerInvoiceDocument.setCustomerBillToAddressOnInvoice(null); 414 customerInvoiceDocument.setCustomerBillToAddressIdentifier(null); 415 } 416 } 417 418 return mapping.findForward(KFSConstants.MAPPING_BASIC); 419 } 420 421 /** 422 * This method refresh the ShipToAddress CustomerAddress object 423 * @param mapping 424 * @param form 425 * @param request 426 * @param response 427 * @return 428 * @throws Exception 429 */ 430 public ActionForward refreshShipToAddress(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 431 CustomerInvoiceDocument customerInvoiceDocument = ((CustomerInvoiceDocumentForm) form).getCustomerInvoiceDocument(); 432 433 CustomerAddress customerShipToAddress = null; 434 if (ObjectUtils.isNotNull(customerInvoiceDocument.getCustomerShipToAddressIdentifier())) { 435 int customerShipToAddressIdentifier = customerInvoiceDocument.getCustomerShipToAddressIdentifier(); 436 437 customerShipToAddress = SpringContext.getBean(CustomerAddressService.class).getByPrimaryKey(customerInvoiceDocument.getAccountsReceivableDocumentHeader().getCustomerNumber(), customerShipToAddressIdentifier); 438 if (ObjectUtils.isNotNull(customerShipToAddress)) { 439 customerInvoiceDocument.setCustomerShipToAddress(customerShipToAddress); 440 customerInvoiceDocument.setCustomerShipToAddressOnInvoice(customerShipToAddress); 441 customerInvoiceDocument.setCustomerShipToAddressIdentifier(customerShipToAddressIdentifier); 442 } 443 } 444 if (ObjectUtils.isNull(customerInvoiceDocument.getCustomerShipToAddressIdentifier()) | ObjectUtils.isNull(customerShipToAddress)) { 445 customerInvoiceDocument.setCustomerShipToAddress(null); 446 customerInvoiceDocument.setCustomerShipToAddressOnInvoice(null); 447 customerInvoiceDocument.setCustomerShipToAddressIdentifier(null); 448 } 449 450 451 return mapping.findForward(KFSConstants.MAPPING_BASIC); 452 } 453 454 /** 455 * 456 * This method... 457 * @param mapping 458 * @param form 459 * @param request 460 * @param response 461 * @return 462 * @throws Exception 463 */ 464 public ActionForward print(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 465 String basePath = getBasePath(request); 466 String docId = ((CustomerInvoiceDocumentForm) form).getCustomerInvoiceDocument().getDocumentNumber(); 467 String methodToCallPrintInvoicePDF = "printInvoicePDF"; 468 String methodToCallDocHandler = "docHandler"; 469 String printInvoicePDFUrl = getUrlForPrintInvoice(basePath, docId, methodToCallPrintInvoicePDF); 470 String displayInvoiceTabbedPageUrl = getUrlForPrintInvoice(basePath, docId, methodToCallDocHandler); 471 472 request.setAttribute("printPDFUrl", printInvoicePDFUrl); 473 request.setAttribute("displayTabbedPageUrl", displayInvoiceTabbedPageUrl); 474 request.setAttribute(KFSConstants.PARAMETER_DOC_ID, docId); 475 String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.CUSTOMER_INVOICE); 476 request.setAttribute("printLabel", label); 477 return mapping.findForward("arPrintPDF"); 478 479 } 480 481 /** 482 * 483 * This method... 484 * @param mapping 485 * @param form 486 * @param request 487 * @param response 488 * @return 489 * @throws Exception 490 */ 491 public ActionForward printInvoicePDF(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 492 String invoiceDocId = request.getParameter(KFSConstants.PARAMETER_DOC_ID); 493 CustomerInvoiceDocument customerInvoiceDocument = (CustomerInvoiceDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invoiceDocId); 494 495 AccountsReceivableReportService reportService = SpringContext.getBean(AccountsReceivableReportService.class); 496 File report = reportService.generateInvoice(customerInvoiceDocument); 497 498 StringBuilder fileName = new StringBuilder(); 499 fileName.append(customerInvoiceDocument.getOrganizationInvoiceNumber()); 500 fileName.append("-"); 501 fileName.append(customerInvoiceDocument.getDocumentNumber()); 502 fileName.append(".pdf"); 503 504 if (report.length() == 0) { 505 //csForm.setMessage("No Report Generated"); 506 return mapping.findForward(KFSConstants.MAPPING_BASIC); 507 } 508 509 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 510 String contentDisposition = ""; 511 try { 512 ArrayList master = new ArrayList(); 513 PdfCopy writer = null; 514 515 // create a reader for the document 516 String reportName = report.getAbsolutePath(); 517 PdfReader reader = new PdfReader(reportName); 518 reader.consolidateNamedDestinations(); 519 520 // retrieve the total number of pages 521 int n = reader.getNumberOfPages(); 522 List bookmarks = SimpleBookmark.getBookmark(reader); 523 if (bookmarks != null) { 524 master.addAll(bookmarks); 525 } 526 527 // step 1: create a document-object 528 Document document = new Document(reader.getPageSizeWithRotation(1)); 529 // step 2: create a writer that listens to the document 530 writer = new PdfCopy(document, baos); 531 // step 3: open the document 532 document.open(); 533 // step 4: add content 534 PdfImportedPage page; 535 for (int i = 0; i < n; ) { 536 ++i; 537 page = writer.getImportedPage(reader, i); 538 writer.addPage(page); 539 } 540 writer.freeReader(reader); 541 if (!master.isEmpty()) { 542 writer.setOutlines(master); 543 } 544 // step 5: we close the document 545 document.close(); 546 547 StringBuffer sbContentDispValue = new StringBuffer(); 548 String useJavascript = request.getParameter("useJavascript"); 549 if (useJavascript == null || useJavascript.equalsIgnoreCase("false")) { 550 sbContentDispValue.append("attachment"); 551 } 552 else { 553 sbContentDispValue.append("inline"); 554 } 555 sbContentDispValue.append("; filename="); 556 sbContentDispValue.append(fileName); 557 558 contentDisposition = sbContentDispValue.toString(); 559 560 } 561 catch(Exception e) { 562 e.printStackTrace(); 563 } 564 565 response.setContentType("application/pdf"); 566 response.setHeader("Content-Disposition", contentDisposition); 567 response.setHeader("Expires", "0"); 568 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 569 response.setHeader("Pragma", "public"); 570 response.setContentLength(baos.size()); 571 572 // write to output 573 ServletOutputStream sos; 574 sos = response.getOutputStream(); 575 baos.writeTo(sos); 576 sos.flush(); 577 sos.close(); 578 579 return null; 580 } 581 582 /** 583 * Creates a URL to be used in printing the customer invoice document. 584 * 585 * @param basePath String: The base path of the current URL 586 * @param docId String: The document ID of the document to be printed 587 * @param methodToCall String: The name of the method that will be invoked to do this particular print 588 * @return The URL 589 */ 590 protected String getUrlForPrintInvoice(String basePath, String docId, String methodToCall) { 591 StringBuffer result = new StringBuffer(basePath); 592 result.append("/arCustomerInvoiceDocument.do?methodToCall="); 593 result.append(methodToCall); 594 result.append("&docId="); 595 result.append(docId); 596 result.append("&command=displayDocSearchView"); 597 598 return result.toString(); 599 } 600 601 602 603 }