/*
* 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.web.struts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.CollectionUtils;
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.integration.cg.ContractsAndGrantsBillingAward;
import org.kuali.kfs.module.ar.ArConstants;
import org.kuali.kfs.module.ar.ArKeyConstants;
import org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceDocumentErrorLog;
import org.kuali.kfs.module.ar.businessobject.ContractsGrantsInvoiceLookupResult;
import org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService;
import org.kuali.kfs.module.ar.service.ContractsGrantsInvoiceCreateDocumentService;
import org.kuali.kfs.module.ar.web.ui.ContractsGrantsLookupResultRow;
import org.kuali.kfs.sys.FinancialSystemModuleConfiguration;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.service.SegmentedLookupResultsService;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kns.util.KNSGlobalVariables;
import org.kuali.rice.kns.web.ui.Column;
import org.kuali.rice.kns.web.ui.ResultRow;
import org.kuali.rice.krad.bo.ModuleConfiguration;
import org.kuali.rice.krad.service.KualiModuleService;
import org.kuali.rice.krad.util.ErrorMessage;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* Action class for Contracts & Grants Invoice Summary.
*/
public class ContractsGrantsInvoiceSummaryAction extends ContractsGrantsBillingSummaryActionBase {
private static volatile ContractsGrantsInvoiceReportService contractsGrantsInvoiceReportService;
private static volatile SegmentedLookupResultsService segmentedLookupResultsService;
/**
* 1. This method passes the control from Contracts & Grants Invoice lookup to the Contracts & Grants Invoice
* Summary page. 2. Retrieves the list of selected awards by agency for creating invoices.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward viewSummary(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ContractsGrantsInvoiceSummaryForm contractsGrantsInvoiceSummaryForm = (ContractsGrantsInvoiceSummaryForm) form;
String lookupResultsSequenceNumber = contractsGrantsInvoiceSummaryForm.getLookupResultsSequenceNumber();
if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) {
String personId = GlobalVariables.getUserSession().getPerson().getPrincipalId();
Collection<ContractsGrantsInvoiceLookupResult> contractsGrantsInvoiceLookupResults = getContractsGrantsInvoiceResultsFromLookupResultsSequenceNumber(lookupResultsSequenceNumber, personId);
contractsGrantsInvoiceSummaryForm.setContractsGrantsInvoiceLookupResults(contractsGrantsInvoiceLookupResults);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
* This method would create invoices for the list of awards. It calls the batch process to reuse the functionality to create the
* invoices.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward createInvoices(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ContractsGrantsInvoiceSummaryForm contractsGrantsInvoiceSummaryForm = (ContractsGrantsInvoiceSummaryForm) form;
ContractsGrantsInvoiceCreateDocumentService cgInvoiceDocumentCreateService = SpringContext.getBean(ContractsGrantsInvoiceCreateDocumentService.class);
Person person = GlobalVariables.getUserSession().getPerson();
String lookupResultsSequenceNumber = "";
String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
if (StringUtils.isNotBlank(parameterName)) {
lookupResultsSequenceNumber = StringUtils.substringBetween(parameterName, ".number", ".");
}
Collection<ContractsGrantsInvoiceLookupResult> lookupResults = getContractsGrantsInvoiceResultsFromLookupResultsSequenceNumber(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId());
// To retrieve the batch file directory name as "reports/cg"
ModuleConfiguration systemConfiguration = SpringContext.getBean(KualiModuleService.class).getModuleServiceByNamespaceCode("KFS-AR").getModuleConfiguration();
String destinationFolderPath = StringUtils.EMPTY;
List<String> batchFileDirectories = ((FinancialSystemModuleConfiguration) systemConfiguration).getBatchFileDirectories();
if ( CollectionUtils.isNotEmpty(batchFileDirectories)){
destinationFolderPath = ((FinancialSystemModuleConfiguration) systemConfiguration).getBatchFileDirectories().get(0);
}
String runtimeStamp = getDateTimeService().toDateTimeStringForFilename(new java.util.Date());
contractsGrantsInvoiceSummaryForm.setAwardInvoiced(true);
int validationErrors = 0;
int validAwards = 0;
// Create Invoices from list of Awards.
List<ErrorMessage> errorMessages = null;
for (ContractsGrantsInvoiceLookupResult contractsGrantsInvoiceLookupResult : lookupResults) {
Collection<ContractsAndGrantsBillingAward> awards = contractsGrantsInvoiceLookupResult.getAwards();
Collection<ContractsGrantsInvoiceDocumentErrorLog> contractsGrantsInvoiceDocumentErrorLogs = new ArrayList<ContractsGrantsInvoiceDocumentErrorLog>();
awards = cgInvoiceDocumentCreateService.validateAwards(awards, contractsGrantsInvoiceDocumentErrorLogs, null, ArConstants.ContractsAndGrantsInvoiceDocumentCreationProcessType.MANUAL.getCode());
validationErrors += contractsGrantsInvoiceDocumentErrorLogs.size();
validAwards += awards.size();
if (awards.size() > 0) {
errorMessages = cgInvoiceDocumentCreateService.createCGInvoiceDocumentsByAwards(awards, ArConstants.ContractsAndGrantsInvoiceDocumentCreationProcessType.MANUAL);
}
}
if (validationErrors > 0) {
// At a minimum, show users a message that errors occurred, check report for details.
KNSGlobalVariables.getMessageList().add(ArKeyConstants.ContractsGrantsInvoiceConstants.ERROR_AWARDS_INVALID);
}
if (validAwards > 0) {
KNSGlobalVariables.getMessageList().add(ArKeyConstants.ContractsGrantsInvoiceConstants.MESSAGE_CONTRACTS_GRANTS_INVOICE_BATCH_SENT);
}
if (ObjectUtils.isNotNull(errorMessages)) {
KNSGlobalVariables.getMessageList().addAll(errorMessages);
}
return mapping.findForward(KFSConstants.MAPPING_BASIC);
}
/**
*
* @param lookupResultsSequenceNumber
* @param personId
* @return
* @throws Exception
*/
protected Collection<ContractsGrantsInvoiceLookupResult> getContractsGrantsInvoiceResultsFromLookupResultsSequenceNumber(String lookupResultsSequenceNumber, String personId) throws Exception {
return getContractsGrantsInvoiceReportService().getPopulatedContractsGrantsInvoiceLookupResults(getAwardsFromLookupResultsSequenceNumber(lookupResultsSequenceNumber, personId));
}
/**
* Get the Awards based on what the user selected in the lookup results.
*
* @param lookupResultsSequenceNumber sequence number used to retrieve the lookup results
* @param personId person who performed the lookup
* @return Collection of ContractsAndGrantsBillingAwards
* @throws Exception if there was a problem getting the selected proposal numbers from the lookup results
*/
protected Collection<ContractsAndGrantsBillingAward> getAwardsFromLookupResultsSequenceNumber(String lookupResultsSequenceNumber, String personId) throws Exception {
KualiModuleService kualiModuleService = SpringContext.getBean(KualiModuleService.class);
Collection<ContractsAndGrantsBillingAward> awards = new ArrayList<ContractsAndGrantsBillingAward>();
List<String> selectedProposalNumbers = getSelectedProposalNumbersFromLookupResultsSequenceNumber(lookupResultsSequenceNumber, personId);
ContractsAndGrantsBillingAward award = null;
for (String selectedProposalNumber: selectedProposalNumbers) {
Map<String, Object> map = new HashMap<String, Object>();
map.put(KFSPropertyConstants.PROPOSAL_NUMBER, selectedProposalNumber);
award = kualiModuleService.getResponsibleModuleService(ContractsAndGrantsBillingAward.class).getExternalizableBusinessObject(ContractsAndGrantsBillingAward.class, map);
if (ObjectUtils.isNotNull(award)) {
awards.add(award);
}
}
return awards;
}
/**
* Get the selected proposal numbers to be used as keys to retrieve the awards by retrieving the selected object ids
* and then matching them against the results from the lookup.
*
* @param lookupResultsSequenceNumber sequence number used to retrieve the lookup results and selected object ids
* @param personId person who performed the lookup
* @return List of proposalNumber Strings that the user selected
* @throws Exception if there was a problem getting the selected object ids or the lookup results
*/
protected List getSelectedProposalNumbersFromLookupResultsSequenceNumber(String lookupResultsSequenceNumber, String personId) throws Exception {
List<String> selectedProposalNumbers = new ArrayList<String>();
Set<String> selectedIds = getSegmentedLookupResultsService().retrieveSetOfSelectedObjectIds(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId());
if (CollectionUtils.isNotEmpty(selectedIds)) {
List<ResultRow> results = getLookupResultsService().retrieveResultsTable(lookupResultsSequenceNumber, personId);
for (ResultRow result:results) {
List<Column> columns = result.getColumns();
if (result instanceof ContractsGrantsLookupResultRow) {
for (ResultRow subResultRow : ((ContractsGrantsLookupResultRow) result).getSubResultRows()) {
String objId = subResultRow.getObjectId();
if (selectedIds.contains(objId)) {
// This is somewhat brittle - it depends on the fact that the Proposal Number is one of
// the columns in the sub result rows. If that changes, this will no longer work and will
// need to be changed.
for (Column column: subResultRow.getColumns()) {
if (StringUtils.equals(column.getPropertyName(), KFSPropertyConstants.PROPOSAL_NUMBER)) {
selectedProposalNumbers.add(subResultRow.getColumns().get(0).getPropertyValue());
break;
}
}
}
}
}
}
}
return selectedProposalNumbers;
}
/**
* To cancel the document, invoices are not created when the cancel method is called.
*
* @param mapping
* @param form
* @param request
* @param response
* @return
* @throws Exception
*/
public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return mapping.findForward(KFSConstants.MAPPING_CANCEL);
}
public static ContractsGrantsInvoiceReportService getContractsGrantsInvoiceReportService() {
if (contractsGrantsInvoiceReportService == null) {
contractsGrantsInvoiceReportService = SpringContext.getBean(ContractsGrantsInvoiceReportService.class);
}
return contractsGrantsInvoiceReportService;
}
public static SegmentedLookupResultsService getSegmentedLookupResultsService() {
if (segmentedLookupResultsService == null) {
segmentedLookupResultsService = SpringContext.getBean(SegmentedLookupResultsService.class);
}
return segmentedLookupResultsService;
}
}