/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.ar.document.web.struts; import java.io.ByteArrayOutputStream; import java.io.File; import java.nio.file.Files; import java.util.List; import java.util.Properties; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.kuali.kfs.module.ar.ArConstants; import org.kuali.kfs.module.ar.ArPropertyConstants; import org.kuali.kfs.module.ar.businessobject.CustomerCreditMemoDetail; import org.kuali.kfs.module.ar.document.CustomerCreditMemoDocument; import org.kuali.kfs.module.ar.document.service.CustomerCreditMemoDetailService; import org.kuali.kfs.module.ar.document.service.CustomerCreditMemoDocumentService; import org.kuali.kfs.module.ar.document.validation.event.ContinueCustomerCreditMemoDocumentEvent; import org.kuali.kfs.module.ar.document.validation.event.RecalculateCustomerCreditMemoDetailEvent; import org.kuali.kfs.module.ar.document.validation.event.RecalculateCustomerCreditMemoDocumentEvent; import org.kuali.kfs.module.ar.report.service.AccountsReceivableReportService; import org.kuali.kfs.module.ar.service.AccountsReceivablePdfHelperService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.util.KfsWebUtils; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.kew.api.KewApiConstants; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kns.service.DataDictionaryService; import org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase; import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; import org.kuali.rice.krad.service.DocumentService; import org.kuali.rice.krad.service.KualiRuleService; import org.kuali.rice.krad.util.UrlFactory; public class CustomerCreditMemoDocumentAction extends KualiTransactionalDocumentActionBase { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CustomerCreditMemoDocumentAction.class); public CustomerCreditMemoDocumentAction() { super(); } /** * Do initialization for a new customer credit memo. * * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#createDocument(org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase) */ @Override protected void createDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { super.createDocument(kualiDocumentFormBase); ((CustomerCreditMemoDocument) kualiDocumentFormBase.getDocument()).initiateDocument(); } /** * This method loads the document by its provided document header id. This has been abstracted out so that it can be overridden * in children if the need arises. * * @param kualiDocumentFormBase * @throws WorkflowException */ @Override protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException { super.loadDocument(kualiDocumentFormBase); ((CustomerCreditMemoDocument)kualiDocumentFormBase.getDocument()).populateCustomerCreditMemoDetailsAfterLoad(); } /** * Clears out init tab. * * @param mapping An ActionMapping * @param form An ActionForm * @param request The HttpServletRequest * @param response The HttpServletResponse * @throws Exception * @return An ActionForward */ public ActionForward clearInitTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) customerCreditMemoDocumentForm.getDocument(); customerCreditMemoDocument.clearInitFields(); return super.refresh(mapping, form, request, response); } /** * Handles continue request. This request comes from the initial screen which gives ref. invoice number. * Based on that, the customer credit memo is initially populated. * * @param mapping An ActionMapping * @param form An ActionForm * @param request The HttpServletRequest * @param response The HttpServletResponse * @throws Exception * @return An ActionForward */ public ActionForward continueCreditMemo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) customerCreditMemoDocumentForm.getDocument(); String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME; boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new ContinueCustomerCreditMemoDocumentEvent(errorPath,customerCreditMemoDocument)); if (rulePassed) { customerCreditMemoDocument.populateCustomerCreditMemoDetails(); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * Based on user input this method recalculates a customer credit memo detail * * @param mapping action mapping * @param form action form * @param request * @param response * @return action forward * @throws Exception */ public ActionForward recalculateCustomerCreditMemoDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocumentForm.getDocument(); int indexOfLineToRecalculate = getSelectedLine(request); CustomerCreditMemoDetail customerCreditMemoDetail = customerCreditMemoDocument.getCreditMemoDetails().get(indexOfLineToRecalculate); String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSConstants.CUSTOMER_CREDIT_MEMO_DETAIL_PROPERTY_NAME + "[" + indexOfLineToRecalculate + "]"; boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new RecalculateCustomerCreditMemoDetailEvent(errorPath, customerCreditMemoDocument, customerCreditMemoDetail)); if (rulePassed) { CustomerCreditMemoDetailService customerCreditMemoDetailService = SpringContext.getBean(CustomerCreditMemoDetailService.class); customerCreditMemoDetailService.recalculateCustomerCreditMemoDetail(customerCreditMemoDetail,customerCreditMemoDocument); } else { customerCreditMemoDocument.recalculateTotals(customerCreditMemoDetail); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * This method refreshes a customer credit memo detail * * @param mapping action mapping * @param form action form * @param request * @param response * @return action forward * @throws Exception */ public ActionForward refreshCustomerCreditMemoDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocForm.getDocument(); int indexOfLineToRefresh = getSelectedLine(request); CustomerCreditMemoDetail customerCreditMemoDetail = customerCreditMemoDocument.getCreditMemoDetails().get(indexOfLineToRefresh); customerCreditMemoDetail.setCreditMemoItemQuantity(null); customerCreditMemoDetail.setCreditMemoItemTotalAmount(null); customerCreditMemoDetail.setCreditMemoItemTaxAmount(KualiDecimal.ZERO); customerCreditMemoDetail.setCreditMemoLineTotalAmount(KualiDecimal.ZERO); customerCreditMemoDocument.recalculateTotals(customerCreditMemoDetail); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * This method refreshes customer credit memo details and line with totals * * @param mapping action mapping * @param form action form * @param request * @param response * @return action forward * @throws Exception */ public ActionForward refreshCustomerCreditMemoDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocForm.getDocument(); List<CustomerCreditMemoDetail> customerCreditMemoDetails = customerCreditMemoDocument.getCreditMemoDetails(); for( CustomerCreditMemoDetail customerCreditMemoDetail : customerCreditMemoDetails ){ customerCreditMemoDetail.setCreditMemoItemQuantity(null); customerCreditMemoDetail.setCreditMemoItemTotalAmount(null); customerCreditMemoDetail.setCreditMemoItemTaxAmount(KualiDecimal.ZERO); customerCreditMemoDetail.setCreditMemoLineTotalAmount(KualiDecimal.ZERO); customerCreditMemoDetail.setDuplicateCreditMemoItemTotalAmount(null); } customerCreditMemoDocument.setCrmTotalItemAmount(KualiDecimal.ZERO); customerCreditMemoDocument.setCrmTotalTaxAmount(KualiDecimal.ZERO); customerCreditMemoDocument.setCrmTotalAmount(KualiDecimal.ZERO); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * Based on user input this method recalculates customer credit memo document <=> all customer credit memo details * * @param mapping action mapping * @param form action form * @param request * @param response * @return action forward * @throws Exception */ public ActionForward recalculateCustomerCreditMemoDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CustomerCreditMemoDocumentForm customerCreditMemoDocumentForm = (CustomerCreditMemoDocumentForm) form; CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument)customerCreditMemoDocumentForm.getDocument(); String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME; boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new RecalculateCustomerCreditMemoDocumentEvent(errorPath,customerCreditMemoDocument,false)); if (rulePassed) { CustomerCreditMemoDocumentService customerCreditMemoDocumentService = SpringContext.getBean(CustomerCreditMemoDocumentService.class); customerCreditMemoDocumentService.recalculateCustomerCreditMemoDocument(customerCreditMemoDocument,false); } return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * * This method... * @param mapping * @param form * @param request * @param response * @return * @throws Exception */ public ActionForward print(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String basePath = getApplicationBaseUrl(); String docId = ((CustomerCreditMemoDocumentForm) form).getDocument().getDocumentNumber(); String printCreditMemoPDFUrl = getUrlForPrintCreditMemo(basePath, docId, ArConstants.PRINT_CREDIT_MEMO_PDF_METHOD); String displayInvoiceTabbedPageUrl = getUrlForPrintCreditMemo(basePath, docId, KFSConstants.DOC_HANDLER_METHOD); request.setAttribute(ArPropertyConstants.PRINT_PDF_URL, printCreditMemoPDFUrl); request.setAttribute(ArPropertyConstants.DISPLAY_TABBED_PAGE_URL, displayInvoiceTabbedPageUrl); request.setAttribute(KFSConstants.PARAMETER_DOC_ID, docId); String label = SpringContext.getBean(DataDictionaryService.class).getDocumentLabelByTypeName(KFSConstants.FinancialDocumentTypeCodes.CUSTOMER_CREDIT_MEMO); request.setAttribute(ArPropertyConstants.PRINT_LABEL, label); return mapping.findForward(ArConstants.MAPPING_PRINT_PDF); } /** * This method generates the Customer Credit Memo PDF * * @param mapping * @param form * @param request * @param response * @return * @throws Exception */ public ActionForward printCreditMemoPDF(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String creditMemoDocId = request.getParameter(KFSConstants.PARAMETER_DOC_ID); CustomerCreditMemoDocument customerCreditMemoDocument = (CustomerCreditMemoDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(creditMemoDocId); AccountsReceivableReportService reportService = SpringContext.getBean(AccountsReceivableReportService.class); File report = reportService.generateCreditMemo(customerCreditMemoDocument); if (report.length() == 0) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } byte[] content = Files.readAllBytes(report.toPath()); ByteArrayOutputStream baos = SpringContext.getBean(AccountsReceivablePdfHelperService.class).buildPdfOutputStream(content); StringBuilder fileName = new StringBuilder(); fileName.append(customerCreditMemoDocument.getFinancialDocumentReferenceInvoiceNumber()); fileName.append(KFSConstants.DASH); fileName.append(customerCreditMemoDocument.getDocumentNumber()); fileName.append(KFSConstants.ReportGeneration.PDF_FILE_EXTENSION); KfsWebUtils.saveMimeOutputStreamAsFile(response, KFSConstants.ReportGeneration.PDF_MIME_TYPE, baos, fileName.toString(), Boolean.parseBoolean(request.getParameter(KFSConstants.ReportGeneration.USE_JAVASCRIPT))); return null; } /** * Creates a URL to be used in printing the customer credit memo. * * @param basePath String: The base path of the current URL * @param docId String: The document ID of the document to be printed * @param methodToCall String: The name of the method that will be invoked to do this particular print * @return The URL */ protected String getUrlForPrintCreditMemo(String basePath, String docId, String methodToCall) { String baseUrl = basePath + "/" + ArConstants.UrlActions.CUSTOMER_CREDIT_MEMO_DOCUMENT; Properties parameters = new Properties(); parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, methodToCall); parameters.put(KFSConstants.PARAMETER_DOC_ID, docId); parameters.put(KFSConstants.PARAMETER_COMMAND, KewApiConstants.ACTIONLIST_COMMAND); return UrlFactory.parameterizeUrl(baseUrl, parameters); } }