/*
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
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.ArKeyConstants;
import org.kuali.kfs.module.ar.ArPropertyConstants;
import org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDocumentErrorLog;
import org.kuali.kfs.module.ar.businessobject.ContractsGrantsLetterOfCreditReviewDetail;
import org.kuali.kfs.module.ar.document.ContractsGrantsLetterOfCreditReviewDocument;
import org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService;
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.config.property.ConfigurationService;
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.kim.api.identity.IdentityService;
import org.kuali.rice.kns.util.WebUtils;
import org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase;
import org.kuali.rice.krad.bo.Note;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.service.NoteService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.ObjectUtils;
import org.kuali.rice.krad.util.UrlFactory;
/**
* Action class for Contracts & Grants LetterOfCredit Review Document.
*/
public class ContractsGrantsLetterOfCreditReviewDocumentAction extends KualiTransactionalDocumentActionBase {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ContractsGrantsLetterOfCreditReviewDocumentAction.class);
/**
* 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 {
ContractsGrantsLetterOfCreditReviewDocumentForm contractsGrantsLetterOfCreditReviewDocumentForm = (ContractsGrantsLetterOfCreditReviewDocumentForm) form;
ContractsGrantsLetterOfCreditReviewDocument contractsGrantsLetterOfCreditReviewDocument = (ContractsGrantsLetterOfCreditReviewDocument) contractsGrantsLetterOfCreditReviewDocumentForm.getDocument();
contractsGrantsLetterOfCreditReviewDocument.clearInitFields();
return super.refresh(mapping, form, request, response);
}
/**
* Handles continue request. This request comes from the initial screen which gives Letter of Credit Fund Group and other
* details Based on that, the Contracts & Grants LetterOfCredit Review document 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 continueLOCReview(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ContractsGrantsLetterOfCreditReviewDocumentForm contractsGrantsLetterOfCreditReviewDocumentForm = (ContractsGrantsLetterOfCreditReviewDocumentForm) form;
ContractsGrantsLetterOfCreditReviewDocument contractsGrantsLetterOfCreditReviewDocument = (ContractsGrantsLetterOfCreditReviewDocument) contractsGrantsLetterOfCreditReviewDocumentForm.getDocument();
if (StringUtils.isBlank(contractsGrantsLetterOfCreditReviewDocument.getLetterOfCreditFundCode()) && StringUtils.isBlank(contractsGrantsLetterOfCreditReviewDocument.getLetterOfCreditFundGroupCode())) {
GlobalVariables.getMessageMap().putError(ArConstants.LETTER_OF_CREDIT_REVIEW_INIT_SECTION, ArKeyConstants.ERROR_LOC_REVIEW_FUND_OR_FUND_GROUP_REQUIRED);
} else if (!StringUtils.isBlank(contractsGrantsLetterOfCreditReviewDocument.getLetterOfCreditFundCode()) && !StringUtils.isBlank(contractsGrantsLetterOfCreditReviewDocument.getLetterOfCreditFundGroupCode())) {
GlobalVariables.getMessageMap().putError(ArConstants.LETTER_OF_CREDIT_REVIEW_INIT_SECTION, ArKeyConstants.ERROR_LOC_REVIEW_ONLY_ONE_FUND_OR_FUND_GROUP);
}
else {
ContractsGrantsLetterOfCreditReviewDocument document = (ContractsGrantsLetterOfCreditReviewDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(contractsGrantsLetterOfCreditReviewDocument.getDocumentNumber());
if (ObjectUtils.isNull(document)) {
contractsGrantsLetterOfCreditReviewDocument.getDocumentHeader().setDocumentDescription(ArConstants.LETTER_OF_CREDIT_REVIEW_DOCUMENT);
Collection<ContractsGrantsInvoiceDocumentErrorLog> contractsGrantsInvoiceDocumentErrorLogs = new ArrayList<ContractsGrantsInvoiceDocumentErrorLog>();
if (contractsGrantsLetterOfCreditReviewDocument.populateContractsGrantsLOCReviewDetails(contractsGrantsInvoiceDocumentErrorLogs)) {
saveDocumentAndNote(contractsGrantsLetterOfCreditReviewDocument, contractsGrantsInvoiceDocumentErrorLogs);
}
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* To recalculate the amount to Draw for every contract control account
*
* @param mapping An ActionMapping
* @param form An ActionForm
* @param request The HttpServletRequest
* @param response The HttpServletResponse
* @throws Exception
* @return An ActionForward
*/
public ActionForward recalculateAmountToDraw(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ContractsGrantsLetterOfCreditReviewDocumentForm contractsGrantsLetterOfCreditReviewDocumentForm = (ContractsGrantsLetterOfCreditReviewDocumentForm) form;
ContractsGrantsLetterOfCreditReviewDocument contractsGrantsLetterOfCreditReviewDocument = (ContractsGrantsLetterOfCreditReviewDocument) contractsGrantsLetterOfCreditReviewDocumentForm.getDocument();
int indexOfLineToRecalculate = getSelectedLine(request);
ContractsGrantsLetterOfCreditReviewDetail contractsGrantsLetterOfCreditReviewDetail = contractsGrantsLetterOfCreditReviewDocument.getHeaderReviewDetails().get(indexOfLineToRecalculate);
contractsGrantsLetterOfCreditReviewDetail.setAmountToDraw(KualiDecimal.ZERO); // clear the cca amount to draw.
contractsGrantsLetterOfCreditReviewDetail.setClaimOnCashBalance(KualiDecimal.ZERO); // clear the cca claim on cash balance
for (ContractsGrantsLetterOfCreditReviewDetail detail : contractsGrantsLetterOfCreditReviewDocument.getAccountReviewDetails()) {
// To set amount to Draw to 0 if there are blank values, to avoid exceptions.
if (ObjectUtils.isNull(detail.getAmountToDraw())) {
detail.setAmountToDraw(KualiDecimal.ZERO);
}
if (detail.getProposalNumber().equals(contractsGrantsLetterOfCreditReviewDetail.getProposalNumber())) { // To get the appropriate individual award account rows.
contractsGrantsLetterOfCreditReviewDetail.setAmountToDraw(contractsGrantsLetterOfCreditReviewDetail.getAmountToDraw().add(detail.getAmountToDraw()));
contractsGrantsLetterOfCreditReviewDetail.setClaimOnCashBalance(contractsGrantsLetterOfCreditReviewDetail.getClaimOnCashBalance().add(detail.getClaimOnCashBalance()));
}
// Now to set funds Not Drawn as a difference betwen amountToDraw and hiddenAmountToDraw.
detail.setFundsNotDrawn(detail.getHiddenAmountToDraw().subtract(detail.getAmountToDraw()));
if (detail.getFundsNotDrawn().isNegative()) {
GlobalVariables.getMessageMap().putError(ArPropertyConstants.FUNDS_NOT_DRAWN, ArKeyConstants.ContractsGrantsInvoiceConstants.ERROR_DOCUMENT_AMOUNT_TO_DRAW_INVALID);
detail.setFundsNotDrawn(KualiDecimal.ZERO);
detail.setAmountToDraw(detail.getHiddenAmountToDraw().subtract(detail.getFundsNotDrawn()));
}
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* This method is called when export button is clicked and export a csv file.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward export(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ContractsGrantsLetterOfCreditReviewDocumentForm locForm = (ContractsGrantsLetterOfCreditReviewDocumentForm) form;
ContractsGrantsLetterOfCreditReviewDocument document = (ContractsGrantsLetterOfCreditReviewDocument) locForm.getDocument();
ContractsGrantsInvoiceReportService reportService = SpringContext.getBean(ContractsGrantsInvoiceReportService.class);
byte[] report = reportService.convertLetterOfCreditReviewToCSV(document);
if (report.length == 0) {
throw new RuntimeException("Error: non-existent file or directory provided");
}
final String fundforFile = !StringUtils.isBlank(document.getLetterOfCreditFundGroupCode())
? document.getLetterOfCreditFundGroupCode()
: document.getLetterOfCreditFundCode();
WebUtils.saveMimeInputStreamAsFile(response, KFSConstants.ReportGeneration.CSV_MIME_TYPE, new ByteArrayInputStream(report), "CSV-Export-" + document.getDocumentNumber() + "-" + fundforFile + KFSConstants.ReportGeneration.CSV_FILE_EXTENSION, report.length);
return null;
}
/**
* This method forward the action to printInvoicePDF after checking the JS compatibility with the browser.
*
* @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();
ContractsGrantsLetterOfCreditReviewDocumentForm locForm = (ContractsGrantsLetterOfCreditReviewDocumentForm) form;
ContractsGrantsLetterOfCreditReviewDocument document = (ContractsGrantsLetterOfCreditReviewDocument) locForm.getDocument();
String printInvoicePDFUrl = getUrlForPrintInvoice(basePath, document.getDocumentNumber(), ArConstants.PRINT_INVOICE_PDF_METHOD);
String displayInvoiceTabbedPageUrl = getUrlForPrintInvoice(basePath, document.getDocumentNumber(), KFSConstants.DOC_HANDLER_METHOD);
request.setAttribute(ArPropertyConstants.PRINT_PDF_URL, printInvoicePDFUrl);
request.setAttribute(ArPropertyConstants.DISPLAY_TABBED_PAGE_URL, displayInvoiceTabbedPageUrl);
return mapping.findForward(ArConstants.MAPPING_PRINT_PDF);
}
/**
* This method generates the invoice and provides it to the user to Print it.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward printInvoicePDF(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String invoiceDocId = request.getParameter(KFSConstants.PARAMETER_DOC_ID);
ContractsGrantsLetterOfCreditReviewDocument contractsGrantsLOCReviewDocument = (ContractsGrantsLetterOfCreditReviewDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invoiceDocId);
if (ObjectUtils.isNotNull(contractsGrantsLOCReviewDocument)) {
ContractsGrantsInvoiceReportService reportService = SpringContext.getBean(ContractsGrantsInvoiceReportService.class);
byte[] report = reportService.generateLOCReviewAsPdf(contractsGrantsLOCReviewDocument);
if (report.length == 0) {
LOG.warn("No Report Generated");
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
ByteArrayOutputStream baos = SpringContext.getBean(AccountsReceivablePdfHelperService.class).buildPdfOutputStream(report);
StringBuilder fileName = new StringBuilder();
fileName.append(contractsGrantsLOCReviewDocument.getLetterOfCreditFundCode());
fileName.append(KFSConstants.DASH);
fileName.append(contractsGrantsLOCReviewDocument.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;
}
/**
* Saves the ContractsGrantsLetterOfCreditReviewDocument and if necessary (i.e. there were validation errors for some
* of the awards) saves a note indicating some awards didn't pass validation and aren't included on the document.
*
* @param contractsGrantsLetterOfCreditReviewDocument document to save
* @param contractsGrantsInvoiceDocumentErrorLogs Collection of validation errors, if any
* @throws WorkflowException
*/
protected void saveDocumentAndNote(ContractsGrantsLetterOfCreditReviewDocument contractsGrantsLetterOfCreditReviewDocument, Collection<ContractsGrantsInvoiceDocumentErrorLog> contractsGrantsInvoiceDocumentErrorLogs) throws WorkflowException {
SpringContext.getBean(DocumentService.class).saveDocument(contractsGrantsLetterOfCreditReviewDocument);
if (contractsGrantsInvoiceDocumentErrorLogs.size() > 0) {
String noteText = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(ArKeyConstants.ContractsGrantsInvoiceConstants.ERROR_SOME_AWARDS_INVALID);
Note note = SpringContext.getBean(DocumentService.class).createNoteFromDocument(contractsGrantsLetterOfCreditReviewDocument, noteText);
note.setAuthorUniversalIdentifier(SpringContext.getBean(IdentityService.class).getPrincipalByPrincipalName(KFSConstants.SYSTEM_USER).getPrincipalId());
contractsGrantsLetterOfCreditReviewDocument.addNote(note);
SpringContext.getBean(NoteService.class).save(note);
}
}
/**
* Creates a URL to be used in printing the customer invoice document.
*
* @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 getUrlForPrintInvoice(String basePath, String docId, String methodToCall) {
String baseUrl = basePath + "/" + ArConstants.UrlActions.CONTRACTS_GRANTS_LETTER_OF_CREDIT_REVIEW_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);
}
}