/*
* 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.report.service.impl;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.IndirectCostRecoveryRateDetail;
import org.kuali.kfs.coa.businessobject.Organization;
import org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAgency;
import org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAward;
import org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAwardAccount;
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.ContractsGrantsInvoiceLookupResult;
import org.kuali.kfs.module.ar.businessobject.ContractsGrantsLetterOfCreditReviewDetail;
import org.kuali.kfs.module.ar.businessobject.CustomerAddress;
import org.kuali.kfs.module.ar.businessobject.InvoiceAddressDetail;
import org.kuali.kfs.module.ar.businessobject.InvoicePaidApplied;
import org.kuali.kfs.module.ar.businessobject.SystemInformation;
import org.kuali.kfs.module.ar.document.ContractsGrantsInvoiceDocument;
import org.kuali.kfs.module.ar.document.ContractsGrantsLetterOfCreditReviewDocument;
import org.kuali.kfs.module.ar.document.service.ContractsGrantsInvoiceDocumentService;
import org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService;
import org.kuali.kfs.module.ar.service.ContractsGrantsBillingUtilityService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.PdfFormFillerUtil;
import org.kuali.kfs.sys.businessobject.SystemOptions;
import org.kuali.kfs.sys.report.ReportInfo;
import org.kuali.kfs.sys.service.NonTransactional;
import org.kuali.kfs.sys.service.OptionsService;
import org.kuali.kfs.sys.service.ReportGenerationService;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.PersonService;
import org.kuali.rice.kns.service.DataDictionaryService;
import org.kuali.rice.krad.bo.Note;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.service.KualiModuleService;
import org.kuali.rice.krad.service.NoteService;
import org.kuali.rice.krad.util.KRADConstants;
import org.kuali.rice.krad.util.ObjectUtils;
import au.com.bytecode.opencsv.CSVWriter;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfCopyFields;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
/**
* This class implements the methods for report generation services for Contracts & Grants.
*/
public class ContractsGrantsInvoiceReportServiceImpl implements ContractsGrantsInvoiceReportService {
private final static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ContractsGrantsInvoiceReportServiceImpl.class);
protected DateTimeService dateTimeService;
protected DataDictionaryService dataDictionaryService;
protected PersonService personService;
protected BusinessObjectService businessObjectService;
protected ParameterService parameterService;
protected ConfigurationService configService;
protected KualiModuleService kualiModuleService;
protected DocumentService documentService;
protected NoteService noteService;
protected ReportInfo reportInfo;
protected ReportGenerationService reportGenerationService;
protected ContractsGrantsInvoiceDocumentService contractsGrantsInvoiceDocumentService;
protected ContractsGrantsBillingUtilityService contractsGrantsBillingUtilityService;
protected OptionsService optionsService;
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#generateInvoice(org.kuali.kfs.module.ar.document.ContractsGrantsLOCReviewDocument)
*/
@Override
public byte[] generateLOCReviewAsPdf(ContractsGrantsLetterOfCreditReviewDocument document) {
Date runDate = new Date(new java.util.Date().getTime());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this.generateLOCReviewInPdf(baos, document);
return baos.toByteArray();
}
/**
* this method generated the actual pdf for the Contracts & Grants LOC Review Document.
*
* @param os
* @param LOCDocument
*/
protected void generateLOCReviewInPdf(OutputStream os, ContractsGrantsLetterOfCreditReviewDocument locDocument) {
try {
Document document = new Document(new Rectangle(ArConstants.LOCReviewPdf.LENGTH, ArConstants.LOCReviewPdf.WIDTH));
PdfWriter.getInstance(document, os);
document.open();
Paragraph header = new Paragraph();
Paragraph text = new Paragraph();
Paragraph title = new Paragraph();
// Lets write the header
header.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_TITLE), ArConstants.PdfReportFonts.LOC_REVIEW_TITLE_FONT));
if (StringUtils.isNotEmpty(locDocument.getLetterOfCreditFundGroupCode())) {
header.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_FUND_GROUP_CODE) + locDocument.getLetterOfCreditFundGroupCode(), ArConstants.PdfReportFonts.LOC_REVIEW_TITLE_FONT));
}
if (StringUtils.isNotEmpty(locDocument.getLetterOfCreditFundCode())) {
header.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_FUND_CODE) + locDocument.getLetterOfCreditFundCode(), ArConstants.PdfReportFonts.LOC_REVIEW_TITLE_FONT));
}
header.add(new Paragraph(KFSConstants.BLANK_SPACE));
header.setAlignment(Element.ALIGN_CENTER);
title.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_DOCUMENT_NUMBER) + locDocument.getDocumentNumber(), ArConstants.PdfReportFonts.LOC_REVIEW_HEADER_FONT));
Person person = getPersonService().getPerson(locDocument.getFinancialSystemDocumentHeader().getInitiatorPrincipalId());
// writing the Document details
title.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_APP_DOC_STATUS) + locDocument.getFinancialSystemDocumentHeader().getApplicationDocumentStatus(), ArConstants.PdfReportFonts.LOC_REVIEW_HEADER_FONT));
title.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_DOCUMENT_INITIATOR) + person.getName(), ArConstants.PdfReportFonts.LOC_REVIEW_HEADER_FONT));
title.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_HEADER_DOCUMENT_CREATE_DATE) + getDateTimeService().toDateString(locDocument.getFinancialSystemDocumentHeader().getWorkflowCreateDate()), ArConstants.PdfReportFonts.LOC_REVIEW_HEADER_FONT));
title.add(new Paragraph(KFSConstants.BLANK_SPACE));
title.setAlignment(Element.ALIGN_RIGHT);
text.add(new Paragraph(configService.getPropertyValueAsString(ArKeyConstants.LOC_REVIEW_PDF_SUBHEADER_AWARDS), ArConstants.PdfReportFonts.LOC_REVIEW_SMALL_BOLD));
text.add(new Paragraph(KFSConstants.BLANK_SPACE));
document.add(header);
document.add(title);
document.add(text);
PdfPTable table = new PdfPTable(11);
table.setTotalWidth(ArConstants.LOCReviewPdf.RESULTS_TABLE_WIDTH);
// fix the absolute width of the table
table.setLockedWidth(true);
// relative col widths in proportions - 1/11
float[] widths = new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f };
table.setWidths(widths);
table.setHorizontalAlignment(0);
addAwardHeaders(table);
if (CollectionUtils.isNotEmpty(locDocument.getHeaderReviewDetails()) && CollectionUtils.isNotEmpty(locDocument.getAccountReviewDetails())) {
for (ContractsGrantsLetterOfCreditReviewDetail item : locDocument.getHeaderReviewDetails()) {
table.addCell(Long.toString(item.getProposalNumber()));
table.addCell(item.getAwardDocumentNumber());
table.addCell(item.getAgencyNumber());
table.addCell(item.getCustomerNumber());
table.addCell(getDateTimeService().toDateString(item.getAwardBeginningDate()));
table.addCell(getDateTimeService().toDateString(item.getAwardEndingDate()));
table.addCell(contractsGrantsBillingUtilityService.formatForCurrency(item.getAwardBudgetAmount()));
table.addCell(contractsGrantsBillingUtilityService.formatForCurrency(item.getLetterOfCreditAmount()));
table.addCell(contractsGrantsBillingUtilityService.formatForCurrency(item.getClaimOnCashBalance()));
table.addCell(contractsGrantsBillingUtilityService.formatForCurrency(item.getAmountToDraw()));
table.addCell(contractsGrantsBillingUtilityService.formatForCurrency(item.getAmountAvailableToDraw()));
PdfPCell cell = new PdfPCell();
cell.setPadding(ArConstants.LOCReviewPdf.RESULTS_TABLE_CELL_PADDING);
cell.setColspan(ArConstants.LOCReviewPdf.RESULTS_TABLE_COLSPAN);
PdfPTable newTable = new PdfPTable(ArConstants.LOCReviewPdf.INNER_TABLE_COLUMNS);
newTable.setTotalWidth(ArConstants.LOCReviewPdf.INNER_TABLE_WIDTH);
// fix the absolute width of the newTable
newTable.setLockedWidth(true);
// relative col widths in proportions - 1/8
float[] newWidths = new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f };
newTable.setWidths(newWidths);
newTable.setHorizontalAlignment(0);
addAccountsHeaders(newTable);
for (ContractsGrantsLetterOfCreditReviewDetail newItem : locDocument.getAccountReviewDetails()) {
if (item.getProposalNumber().equals(newItem.getProposalNumber())) {
newTable.addCell(newItem.getAccountDescription());
newTable.addCell(newItem.getChartOfAccountsCode());
newTable.addCell(newItem.getAccountNumber());
String accountExpirationDate = KFSConstants.EMPTY_STRING;
if (!ObjectUtils.isNull(newItem.getAccountExpirationDate())) {
accountExpirationDate = getDateTimeService().toDateString(newItem.getAccountExpirationDate());
}
newTable.addCell(accountExpirationDate);
newTable.addCell(contractsGrantsBillingUtilityService.formatForCurrency(newItem.getAwardBudgetAmount()));
newTable.addCell(contractsGrantsBillingUtilityService.formatForCurrency(newItem.getClaimOnCashBalance()));
newTable.addCell(contractsGrantsBillingUtilityService.formatForCurrency(newItem.getAmountToDraw()));
newTable.addCell(contractsGrantsBillingUtilityService.formatForCurrency(newItem.getFundsNotDrawn()));
}
}
cell.addElement(newTable);
table.addCell(cell);
}
document.add(table);
}
document.close();
}
catch (DocumentException e) {
LOG.error("problem during ContractsGrantsInvoiceReportServiceImpl.generateInvoiceInPdf()", e);
}
}
/**
* This method is used to set the headers for the CG LOC review Document
*
* @param table
*/
protected void addAccountsHeaders(PdfPTable table) {
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_DESCRIPTION));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_EXPIRATION_DATE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AWARD_BUDGET_AMOUNT));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.CLAIM_ON_CASH_BALANCE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AMOUNT_TO_DRAW));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.FUNDS_NOT_DRAWN));
}
/**
* This method is used to set the headers for the CG LOC review Document
*
* @param table
*/
protected void addAwardHeaders(PdfPTable table) {
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.PROPOSAL_NUMBER));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.AWARD_DOCUMENT_NUMBER));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.AGENCY_NUMBER));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.CUSTOMER_NUMBER));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.AWARD_BEGINNING_DATE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.AWARD_ENDING_DATE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AWARD_BUDGET_AMOUNT));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.LETTER_OF_CREDIT_AMOUNT));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.CLAIM_ON_CASH_BALANCE));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AMOUNT_TO_DRAW));
table.addCell(getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.FUNDS_NOT_DRAWN));
}
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#generateFederalFinancialForm(org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAward,
* java.lang.String, java.lang.String, java.lang.String, org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAgency)
*/
@Override
public File generateFederalFinancialForm(ContractsAndGrantsBillingAward award, String period, String year, String formType, ContractsAndGrantsBillingAgency agency) {
Map<String, String> replacementList = new HashMap<String, String>();
Date runDate = new Date(new java.util.Date().getTime());
String reportFileName = getReportInfo().getReportFileName();
String reportDirectory = getReportInfo().getReportsDirectory();
try {
if (formType.equals(ArConstants.FEDERAL_FORM_425) && ObjectUtils.isNotNull(award)) {
String fullReportFileName = reportGenerationService.buildFullFileName(runDate, reportDirectory, reportFileName, ArConstants.FEDERAL_FUND_425_REPORT_ABBREVIATION) + KFSConstants.ReportGeneration.PDF_FILE_EXTENSION;
File file = new File(fullReportFileName);
FileOutputStream fos = new FileOutputStream(file);
stampPdfFormValues425(award, period, year, fos, replacementList);
return file;
}
else if (formType.equals(ArConstants.FEDERAL_FORM_425A) && ObjectUtils.isNotNull(agency)) {
String fullReportFileName = reportGenerationService.buildFullFileName(runDate, reportDirectory, reportFileName, ArConstants.FEDERAL_FUND_425A_REPORT_ABBREVIATION) + KFSConstants.ReportGeneration.PDF_FILE_EXTENSION;
File file = new File(fullReportFileName);
FileOutputStream fos = new FileOutputStream(file);
stampPdfFormValues425A(agency, period, year, fos, replacementList);
return file;
}
}
catch (FileNotFoundException ex) {
throw new RuntimeException("Cannot find pdf to stamp for federal financial form", ex);
}
return null;
}
/**
* @param award
* @return
*/
protected KualiDecimal getCashReceipts(ContractsAndGrantsBillingAward award) {
KualiDecimal cashReceipt = KualiDecimal.ZERO;
Map<String,String> fieldValues = new HashMap<String,String>();
if (ObjectUtils.isNotNull(award) && ObjectUtils.isNotNull(award.getProposalNumber())){
fieldValues.put(KFSPropertyConstants.PROPOSAL_NUMBER, award.getProposalNumber().toString());
}
List<ContractsGrantsInvoiceDocument> list = (List<ContractsGrantsInvoiceDocument>) contractsGrantsInvoiceDocumentService.retrieveAllCGInvoicesByCriteria(fieldValues);
if (!CollectionUtils.isEmpty(list)) {
for(ContractsGrantsInvoiceDocument invoice: list){
Map primaryKeys = new HashMap<String, Object>();
primaryKeys.put(ArPropertyConstants.CustomerInvoiceDocumentFields.FINANCIAL_DOCUMENT_REF_INVOICE_NUMBER, invoice.getDocumentNumber());
List<InvoicePaidApplied> ipas = (List<InvoicePaidApplied>)businessObjectService.findMatching(InvoicePaidApplied.class, primaryKeys);
if(ObjectUtils.isNotNull(ipas)) {
for(InvoicePaidApplied ipa : ipas) {
cashReceipt = cashReceipt.add(ipa.getInvoiceItemAppliedAmount());
}
}
}
}
return cashReceipt;
}
/**
* This method is used to populate the replacement list to replace values from pdf template to actual values for Federal Form
* 425
*
* @param award
* @param reportingPeriod
* @param year
*/
protected void populateListByAward(ContractsAndGrantsBillingAward award, String reportingPeriod, String year, Map<String, String> replacementList) {
KualiDecimal cashDisbursement = KualiDecimal.ZERO;
final SystemOptions systemOption = optionsService.getCurrentYearOptions();
for (ContractsAndGrantsBillingAwardAccount awardAccount : award.getActiveAwardAccounts()) {
int index = 0;
KualiDecimal baseSum = KualiDecimal.ZERO;
KualiDecimal amountSum = KualiDecimal.ZERO;
cashDisbursement = cashDisbursement.add(contractsGrantsInvoiceDocumentService.getBudgetAndActualsForAwardAccount(awardAccount, systemOption.getActualFinancialBalanceTypeCd(), award.getAwardBeginningDate()));
if (ObjectUtils.isNotNull(awardAccount.getAccount().getFinancialIcrSeriesIdentifier()) && ObjectUtils.isNotNull(awardAccount.getAccount().getAcctIndirectCostRcvyTypeCd())) {
index++;
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_TYPE + " " + index, awardAccount.getAccount().getAcctIndirectCostRcvyTypeCd());
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_RATE + " " + index, awardAccount.getAccount().getFinancialIcrSeriesIdentifier());
if (ObjectUtils.isNotNull(awardAccount.getAccount().getAccountEffectiveDate())) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_PERIOD_FROM + " " + index, getDateTimeService().toDateString(awardAccount.getAccount().getAccountEffectiveDate()));
}
if (ObjectUtils.isNotNull(awardAccount.getAccount().getAccountExpirationDate())) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_PERIOD_TO + " " + index, getDateTimeService().toDateString(awardAccount.getAccount().getAccountExpirationDate()));
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_BASE + " " + index, contractsGrantsBillingUtilityService.formatForCurrency(award.getAwardTotalAmount()));
Map<String, Object> key = new HashMap<String, Object>();
key.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
key.put(KFSPropertyConstants.FINANCIAL_ICR_SERIES_IDENTIFIER, awardAccount.getAccount().getFinancialIcrSeriesIdentifier());
key.put(KFSPropertyConstants.ACTIVE, true);
key.put(KFSPropertyConstants.TRANSACTION_DEBIT_INDICATOR, KFSConstants.GL_DEBIT_CODE);
List<IndirectCostRecoveryRateDetail> icrDetail = (List<IndirectCostRecoveryRateDetail>) businessObjectService.findMatchingOrderBy(IndirectCostRecoveryRateDetail.class, key, KFSPropertyConstants.AWARD_INDR_COST_RCVY_ENTRY_NBR, false);
if (CollectionUtils.isNotEmpty(icrDetail)) {
KualiDecimal rate = new KualiDecimal(icrDetail.get(0).getAwardIndrCostRcvyRatePct());
if (ObjectUtils.isNotNull(rate)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_AMOUNT + " " + index, contractsGrantsBillingUtilityService.formatForCurrency(award.getAwardTotalAmount().multiply(rate)));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_FEDERAL + " " + index, contractsGrantsBillingUtilityService.formatForCurrency(award.getAwardTotalAmount().multiply(rate)));
amountSum = amountSum.add(award.getAwardTotalAmount().multiply(rate));
}
}
baseSum = baseSum.add(award.getAwardTotalAmount());
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_BASE_SUM, contractsGrantsBillingUtilityService.formatForCurrency(baseSum));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_AMOUNT_SUM, contractsGrantsBillingUtilityService.formatForCurrency(amountSum));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INDIRECT_EXPENSE_FEDERAL_SUM, contractsGrantsBillingUtilityService.formatForCurrency(amountSum));
}
final SystemInformation sysInfo = retrieveSystemInformationForAward(award, year);
if (ObjectUtils.isNotNull(sysInfo)) {
final String address = concatenateAddressFromSystemInformation(sysInfo);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.RECIPIENT_ORGANIZATION, address);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ZWEI, sysInfo.getUniversityFederalEmployerIdentificationNumber());
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_AGENCY, award.getAgency().getFullName());
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_GRANT_NUMBER, award.getAwardDocumentNumber());
if(CollectionUtils.isNotEmpty(award.getActiveAwardAccounts())){
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.RECIPIENT_ACCOUNT_NUMBER, award.getActiveAwardAccounts().get(0).getAccountNumber());
}
if (ObjectUtils.isNotNull(award.getAwardBeginningDate())) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.GRANT_PERIOD_FROM, getDateTimeService().toDateString(award.getAwardBeginningDate()));
}
if (ObjectUtils.isNotNull(award.getAwardClosingDate())) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.GRANT_PERIOD_TO, getDateTimeService().toDateString(award.getAwardClosingDate()));
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_RECEIPTS, contractsGrantsBillingUtilityService.formatForCurrency(this.getCashReceipts(award)));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TOTAL_FEDERAL_FUNDS_AUTHORIZED, contractsGrantsBillingUtilityService.formatForCurrency(award.getAwardTotalAmount()));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.REPORTING_PERIOD_END_DATE, getReportingPeriodEndDate(reportingPeriod, year));
if (ObjectUtils.isNotNull(cashDisbursement)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_DISBURSEMENTS, contractsGrantsBillingUtilityService.formatForCurrency(cashDisbursement));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_ON_HAND, contractsGrantsBillingUtilityService.formatForCurrency(getCashReceipts(award).subtract(cashDisbursement)));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_SHARE_OF_EXPENDITURES, contractsGrantsBillingUtilityService.formatForCurrency(cashDisbursement));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TOTAL_FEDERAL_SHARE, contractsGrantsBillingUtilityService.formatForCurrency(cashDisbursement));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.UNOBLIGATED_BALANCE_OF_FEDERAL_FUNDS, contractsGrantsBillingUtilityService.formatForCurrency(award.getAwardTotalAmount().subtract(cashDisbursement)));
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_SHARE_OF_UNLIQUIDATED_OBLIGATION, contractsGrantsBillingUtilityService.formatForCurrency(KualiDecimal.ZERO));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TOTAL_FEDERAL_INCOME_EARNED, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INCOME_EXPENDED_DEDUCATION_ALTERNATIVE, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.INCOME_EXPENDED_ADDITION_ALTERNATIVE, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.UNEXPECTED_PROGRAM_INCOME, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.NAME, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TELEPHONE, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.EMAIL_ADDRESS, KFSConstants.EMPTY_STRING);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.DATE_REPORT_SUBMITTED, getDateTimeService().toDateString(getDateTimeService().getCurrentDate()));
if (ArConstants.QUARTER1.equals(reportingPeriod) || ArConstants.QUARTER2.equals(reportingPeriod) || ArConstants.QUARTER3.equals(reportingPeriod) || ArConstants.QUARTER4.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.QUARTERLY, KFSConstants.OptionLabels.YES);
}
if (ArConstants.SEMI_ANNUAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.SEMI_ANNUAL, KFSConstants.OptionLabels.YES);
}
if (ArConstants.ANNUAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ANNUAL, KFSConstants.OptionLabels.YES);
}
if (ArConstants.FINAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FINAL, KFSConstants.OptionLabels.YES);
}
String accountingBasis = parameterService.getParameterValueAsString(ArConstants.AR_NAMESPACE_CODE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, ArConstants.BASIS_OF_ACCOUNTING);
if (ArConstants.BASIS_OF_ACCOUNTING_CASH.equals(accountingBasis)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH, KFSConstants.OptionLabels.YES);
}
if (ArConstants.BASIS_OF_ACCOUNTING_ACCRUAL.equals(accountingBasis)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ACCRUAL, KFSConstants.OptionLabels.YES);
}
}
/**
* Concatenates the address from an AR System Information object into a single String
* @param sysInfo the System Information business object to concatenate the address of
* @return the concatenated address
*/
protected String concatenateAddressFromSystemInformation(final SystemInformation sysInfo) {
String address = sysInfo.getOrganizationRemitToAddressName();
if(!StringUtils.isBlank(sysInfo.getOrganizationRemitToLine1StreetAddress())) {
address += ", " + sysInfo.getOrganizationRemitToLine1StreetAddress();
}
if(!StringUtils.isBlank(sysInfo.getOrganizationRemitToLine2StreetAddress())) {
address += ", " + sysInfo.getOrganizationRemitToLine2StreetAddress();
}
if(!StringUtils.isBlank(sysInfo.getOrganizationRemitToCityName())) {
address += ", " + sysInfo.getOrganizationRemitToCityName();
}
if(!StringUtils.isBlank(sysInfo.getOrganizationRemitToStateCode())) {
address += " " + sysInfo.getOrganizationRemitToStateCode();
}
if(!StringUtils.isBlank(sysInfo.getOrganizationRemitToZipCode())) {
address += "-" + sysInfo.getOrganizationRemitToZipCode();
}
return address;
}
/**
* Retrieves an AR System Information object for an award
* @param award the award to retrieve an associated System Information for
* @param year the year of the System Information object to retrieve
* @return the System Information object, or null if nothing is found
*/
protected SystemInformation retrieveSystemInformationForAward(ContractsAndGrantsBillingAward award, String year) {
Map primaryKeys = new HashMap<String, Object>();
primaryKeys.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
primaryKeys.put(KFSPropertyConstants.PROCESSING_CHART_OF_ACCT_CD, award.getPrimaryAwardOrganization().getChartOfAccountsCode());
primaryKeys.put(KFSPropertyConstants.PROCESSING_ORGANIZATION_CODE, award.getPrimaryAwardOrganization().getOrganizationCode());
SystemInformation sysInfo = businessObjectService.findByPrimaryKey(SystemInformation.class, primaryKeys);
return sysInfo;
}
/**
* This method is used to populate the replacement list to replace values from pdf template to actual values for Federal Form
* 425A
*
* @param awards
* @param reportingPeriod
* @param year
* @param agency
* @return total amount
*/
protected List<KualiDecimal> populateListByAgency(List<ContractsAndGrantsBillingAward> awards, String reportingPeriod, String year, ContractsAndGrantsBillingAgency agency) {
Map<String, String> replacementList = new HashMap<String, String>();
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.REPORTING_PERIOD_END_DATE, getReportingPeriodEndDate(reportingPeriod, year));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_AGENCY, agency.getFullName());
final SystemOptions systemOption = optionsService.getCurrentYearOptions();
Map primaryKeys = new HashMap<String, Object>();
primaryKeys.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
if (CollectionUtils.isNotEmpty(awards)){
primaryKeys.put(KFSPropertyConstants.PROCESSING_CHART_OF_ACCT_CD, awards.get(0).getPrimaryAwardOrganization().getChartOfAccountsCode());
primaryKeys.put(KFSPropertyConstants.PROCESSING_ORGANIZATION_CODE, awards.get(0).getPrimaryAwardOrganization().getOrganizationCode());
}
SystemInformation sysInfo = businessObjectService.findByPrimaryKey(SystemInformation.class, primaryKeys);
if (ObjectUtils.isNotNull(sysInfo)) {
String address = concatenateAddressFromSystemInformation(sysInfo);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.RECIPIENT_ORGANIZATION, address);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ZWEI, sysInfo.getUniversityFederalEmployerIdentificationNumber());
}
if (ArConstants.QUARTER1.equals(reportingPeriod) || ArConstants.QUARTER2.equals(reportingPeriod) || ArConstants.QUARTER3.equals(reportingPeriod) || ArConstants.QUARTER4.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.QUARTERLY, KFSConstants.OptionLabels.YES);
}
if (ArConstants.SEMI_ANNUAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.SEMI_ANNUAL, KFSConstants.OptionLabels.YES);
}
if (ArConstants.ANNUAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ANNUAL, KFSConstants.OptionLabels.YES);
}
if (ArConstants.FINAL.equals(reportingPeriod)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FINAL, KFSConstants.OptionLabels.YES);
}
String accountingBasis = parameterService.getParameterValueAsString(ArConstants.AR_NAMESPACE_CODE, KRADConstants.DetailTypes.ALL_DETAIL_TYPE, ArConstants.BASIS_OF_ACCOUNTING);
if (ArConstants.BASIS_OF_ACCOUNTING_CASH.equals(accountingBasis)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH, KFSConstants.OptionLabels.YES);
}
if (ArConstants.BASIS_OF_ACCOUNTING_ACCRUAL.equals(accountingBasis)) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.ACCRUAL,KFSConstants.OptionLabels.YES);
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.DATE_REPORT_SUBMITTED, getDateTimeService().toDateString(new Date(new java.util.Date().getTime())));
KualiDecimal totalCashControl = KualiDecimal.ZERO;
KualiDecimal totalCashDisbursement = KualiDecimal.ZERO;
for (int i = 0; i < 30; i++) {
if (i < awards.size()) {
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_GRANT_NUMBER + " " + (i + 1), awards.get(i).getAwardDocumentNumber());
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.RECIPIENT_ACCOUNT_NUMBER + " " + (i + 1), awards.get(i).getActiveAwardAccounts().get(0).getAccountNumber());
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.FEDERAL_CASH_DISBURSEMENT + " " + (i + 1), contractsGrantsBillingUtilityService.formatForCurrency(getCashReceipts(awards.get(i))));
totalCashControl = totalCashControl.add(this.getCashReceipts(awards.get(i)));
for (ContractsAndGrantsBillingAwardAccount awardAccount : awards.get(i).getActiveAwardAccounts()) {
totalCashDisbursement = totalCashDisbursement.add(contractsGrantsInvoiceDocumentService.getBudgetAndActualsForAwardAccount(awardAccount, systemOption.getActualFinancialBalanceTypeCd(), awards.get(i).getAwardBeginningDate()));
}
}
}
ArrayList<KualiDecimal> list = new ArrayList<KualiDecimal>();
list.add(totalCashControl);
list.add(totalCashDisbursement);
return list;
}
/**
* This method returns the last day of the given reporting period.
*
* @param reportingPeriod
* @param year
* @return
*/
protected String getReportingPeriodEndDate(String reportingPeriod, String year) {
Integer yearAsInt = Integer.parseInt(year);
java.util.Date endDate = null;
if (ArConstants.QUARTER1.equals(reportingPeriod)) {
endDate = ArConstants.BillingQuarterLastDays.FIRST_QUARTER.getDateForYear(yearAsInt);
}
else if (ArConstants.QUARTER2.equals(reportingPeriod) || ArConstants.SEMI_ANNUAL.equals(reportingPeriod)) {
endDate = ArConstants.BillingQuarterLastDays.SECOND_QUARTER.getDateForYear(yearAsInt);
}
else if (ArConstants.QUARTER3.equals(reportingPeriod)) {
endDate = ArConstants.BillingQuarterLastDays.THIRD_QUARTER.getDateForYear(yearAsInt);
}
else {
endDate = ArConstants.BillingQuarterLastDays.FOURTH_QUARTER.getDateForYear(yearAsInt);
}
return getDateTimeService().toDateString(endDate);
}
/**
* Use iText <code>{@link PdfStamper}</code> to stamp information into field values on a PDF Form Template.
*
* @param award The award the values will be pulled from.
* @param reportingPeriod
* @param year
* @param returnStream The output stream the federal form will be written to.
*/
protected void stampPdfFormValues425(ContractsAndGrantsBillingAward award, String reportingPeriod, String year, OutputStream returnStream, Map<String, String> replacementList) {
String reportTemplateName = ArConstants.FF_425_TEMPLATE_NM + KFSConstants.ReportGeneration.PDF_FILE_EXTENSION;
try {
String federalReportTemplatePath = configService.getPropertyValueAsString(KFSConstants.EXTERNALIZABLE_HELP_URL_KEY);
populateListByAward(award, reportingPeriod, year, replacementList);
//final byte[] pdfBytes = renameFieldsIn(federalReportTemplatePath + reportTemplateName, replacementList);
URL template = new URL(federalReportTemplatePath + reportTemplateName);
final byte[] pdfBytes = PdfFormFillerUtil.populateTemplate(template.openStream(), replacementList);
returnStream.write(pdfBytes);
}
catch (IOException | DocumentException ex) {
throw new RuntimeException("Troubles stamping the old 425!", ex);
}
}
/**
* Use iText <code>{@link PdfStamper}</code> to stamp information into field values on a PDF Form Template.
*
* @param agency The award the values will be pulled from.
* @param reportingPeriod
* @param year
* @param returnStream The output stream the federal form will be written to.
*/
protected void stampPdfFormValues425A(ContractsAndGrantsBillingAgency agency, String reportingPeriod, String year, OutputStream returnStream, Map<String, String> replacementList) {
String federalReportTemplatePath = configService.getPropertyValueAsString(KFSConstants.EXTERNALIZABLE_HELP_URL_KEY);
try {
final String federal425ATemplateUrl = federalReportTemplatePath + ArConstants.FF_425A_TEMPLATE_NM + KFSConstants.ReportGeneration.PDF_FILE_EXTENSION;
final String federal425TemplateUrl = federalReportTemplatePath + ArConstants.FF_425_TEMPLATE_NM + KFSConstants.ReportGeneration.PDF_FILE_EXTENSION;
Map<String, Object> fieldValues = new HashMap<>();
fieldValues.put(KFSPropertyConstants.AGENCY_NUMBER, agency.getAgencyNumber());
fieldValues.put(KFSPropertyConstants.ACTIVE, Boolean.TRUE);
List<ContractsAndGrantsBillingAward> awards = kualiModuleService.getResponsibleModuleService(ContractsAndGrantsBillingAward.class).getExternalizableBusinessObjectsList(ContractsAndGrantsBillingAward.class, fieldValues);
Integer pageNumber = 1, totalPages;
totalPages = (awards.size() / ArConstants.Federal425APdf.NUMBER_OF_SUMMARIES_PER_PAGE) + 1;
PdfCopyFields copy = new PdfCopyFields(returnStream);
// generate replacement list for FF425
populateListByAgency(awards, reportingPeriod, year, agency);
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TOTAL_PAGES, org.apache.commons.lang.ObjectUtils.toString(totalPages + 1));
KualiDecimal sumCashControl = KualiDecimal.ZERO;
KualiDecimal sumCumExp = KualiDecimal.ZERO;
while (pageNumber <= totalPages) {
List<ContractsAndGrantsBillingAward> awardsList = new ArrayList<ContractsAndGrantsBillingAward>();
for (int i = ((pageNumber - 1) * ArConstants.Federal425APdf.NUMBER_OF_SUMMARIES_PER_PAGE); i < (pageNumber * ArConstants.Federal425APdf.NUMBER_OF_SUMMARIES_PER_PAGE); i++) {
if (i < awards.size()) {
awardsList.add(awards.get(i));
}
}
// generate replacement list for FF425
List<KualiDecimal> list = populateListByAgency(awardsList, reportingPeriod, year, agency);
if (CollectionUtils.isNotEmpty(list)){
sumCashControl = sumCashControl.add(list.get(0));
if (list.size() > 1){
sumCumExp = sumCumExp.add(list.get(1));
}
}
// populate form with document values
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.PAGE_NUMBER, org.apache.commons.lang.ObjectUtils.toString(pageNumber + 1));
if (pageNumber == totalPages){
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.TOTAL, contractsGrantsBillingUtilityService.formatForCurrency(sumCashControl));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_RECEIPTS, contractsGrantsBillingUtilityService.formatForCurrency(sumCashControl));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_DISBURSEMENTS, contractsGrantsBillingUtilityService.formatForCurrency(sumCumExp));
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.CASH_ON_HAND, contractsGrantsBillingUtilityService.formatForCurrency(sumCashControl.subtract(sumCumExp)));
}
// add a document
copy.addDocument(new PdfReader(renameFieldsIn(federal425ATemplateUrl, replacementList)));
pageNumber++;
}
contractsGrantsBillingUtilityService.putValueOrEmptyString(replacementList, ArPropertyConstants.FederalFormReportFields.PAGE_NUMBER, "1");
// add the FF425 form.
copy.addDocument(new PdfReader(renameFieldsIn(federal425TemplateUrl, replacementList)));
// Close the PdfCopyFields object
copy.close();
}
catch (DocumentException | IOException ex) {
throw new RuntimeException("Tried to stamp the 425A, but couldn't do it. Just...just couldn't do it.", ex);
}
}
/**
*
* @param template the path to the original form
* @param list the replacement list
* @return
* @throws IOException
* @throws DocumentException
*/
protected byte[] renameFieldsIn(String template, Map<String, String> list) throws IOException, DocumentException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Create the stamper
PdfStamper stamper = new PdfStamper(new PdfReader(template), baos);
// Get the fields
AcroFields fields = stamper.getAcroFields();
// Loop over the fields
for (String field : list.keySet()) {
fields.setField(field, list.get(field));
}
// close the stamper
stamper.close();
return baos.toByteArray();
}
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#generateListOfInvoicesPdfToPrint(java.util.Collection)
*/
@Override
public byte[] combineInvoicePdfs(Collection<ContractsGrantsInvoiceDocument> list) throws DocumentException, IOException {
Date runDate = new Date(new java.util.Date().getTime());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
generateCombinedPdfForInvoices(list, baos);
return baos.toByteArray();
}
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#generateListOfInvoicesEnvelopesPdfToPrint(java.util.Collection)
*/
@Override
public byte[] combineInvoicePdfEnvelopes(Collection<ContractsGrantsInvoiceDocument> list) throws DocumentException, IOException {
Date runDate = new Date(new java.util.Date().getTime());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
generateCombinedPdfForEnvelopes(list, baos);
return baos.toByteArray();
}
/**
* Generates the pdf file for printing the invoices.
*
* @param list
* @param outputStream
* @throws DocumentException
* @throws IOException
*/
protected void generateCombinedPdfForInvoices(Collection<ContractsGrantsInvoiceDocument> list, OutputStream outputStream) throws DocumentException, IOException {
PdfCopyFields copy = new PdfCopyFields(outputStream);
boolean pageAdded = false;
for (ContractsGrantsInvoiceDocument invoice : list) {
// add a document
List<InvoiceAddressDetail> invoiceAddressDetails = invoice.getInvoiceAddressDetails();
for (InvoiceAddressDetail invoiceAddressDetail : invoiceAddressDetails) {
if (ArConstants.InvoiceTransmissionMethod.MAIL.equals(invoiceAddressDetail.getInvoiceTransmissionMethodCode())) {
Note note = noteService.getNoteByNoteId(invoiceAddressDetail.getNoteId());
Integer numberOfCopiesToPrint = invoiceAddressDetail.getCustomerAddress().getCustomerCopiesToPrint();
if (ObjectUtils.isNull(numberOfCopiesToPrint)) {
numberOfCopiesToPrint = 1;
}
if (!ObjectUtils.isNull(note)) {
for (int i = 0; i < numberOfCopiesToPrint; i++) {
if (!pageAdded) {
copy.open();
}
pageAdded = true;
copy.addDocument(new PdfReader(note.getAttachment().getAttachmentContents()));
}
}
invoiceAddressDetail.setInitialTransmissionDate(new Date(new java.util.Date().getTime()));
}
}
documentService.updateDocument(invoice);
}
if (pageAdded) {
copy.close();
}
}
/**
* Generates the pdf file for printing the envelopes.
*
* @param list
* @param outputStream
* @throws DocumentException
* @throws IOException
*/
protected void generateCombinedPdfForEnvelopes(Collection<ContractsGrantsInvoiceDocument> list, OutputStream outputStream) throws DocumentException, IOException {
Document document = new Document(new Rectangle(ArConstants.InvoiceEnvelopePdf.LENGTH, ArConstants.InvoiceEnvelopePdf.WIDTH));
PdfWriter.getInstance(document, outputStream);
boolean pageAdded = false;
for (ContractsGrantsInvoiceDocument invoice : list) {
// add a document
for (InvoiceAddressDetail invoiceAddressDetail : invoice.getInvoiceAddressDetails()) {
if (ArConstants.InvoiceTransmissionMethod.MAIL.equals(invoiceAddressDetail.getInvoiceTransmissionMethodCode())) {
CustomerAddress address = invoiceAddressDetail.getCustomerAddress();
Integer numberOfEnvelopesToPrint = address.getCustomerEnvelopesToPrintQuantity();
if (ObjectUtils.isNull(numberOfEnvelopesToPrint)) {
numberOfEnvelopesToPrint = 1;
}
for (int i = 0; i < numberOfEnvelopesToPrint; i++) {
// if a page has not already been added then open the document.
if (!pageAdded) {
document.open();
}
pageAdded = true;
document.newPage();
// adding the sent From address
Organization org = invoice.getInvoiceGeneralDetail().getAward().getPrimaryAwardOrganization().getOrganization();
Paragraph sentBy = generateAddressParagraph(org.getOrganizationName(), org.getOrganizationLine1Address(), org.getOrganizationLine2Address(), org.getOrganizationCityName(), org.getOrganizationStateCode(), org.getOrganizationZipCode(), ArConstants.PdfReportFonts.ENVELOPE_SMALL_FONT);
sentBy.setIndentationLeft(ArConstants.InvoiceEnvelopePdf.INDENTATION_LEFT);
sentBy.setAlignment(Element.ALIGN_LEFT);
// adding the send To address
String string;
Paragraph sendTo = generateAddressParagraph(address.getCustomerAddressName(), address.getCustomerLine1StreetAddress(), address.getCustomerLine2StreetAddress(), address.getCustomerCityName(), address.getCustomerStateCode(), address.getCustomerZipCode(), ArConstants.PdfReportFonts.ENVELOPE_TITLE_FONT);
sendTo.setAlignment(Element.ALIGN_CENTER);
sendTo.add(new Paragraph(KFSConstants.BLANK_SPACE));
document.add(sentBy);
document.add(sendTo);
}
}
}
}
if (pageAdded) {
document.close();
}
}
/**
* Generates a PDF paragraph for a given Address
* @param name the name that this envelope is being sent to
* @param line1Address the first line of the address
* @param line2Address the second line of the address
* @param cityName the name of the city to send this to
* @param stateCode the code of the state or presumably province to send this to
* @param postalCode the postal code/zip code to send the enveleope to
* @param font the font to write in
* @return a PDF Paragraph for the address
*/
protected Paragraph generateAddressParagraph(String name, String line1Address, String line2Address, String cityName, String stateCode, String postalCode, Font font) {
Paragraph addressParagraph = new Paragraph();
addressParagraph.add(new Paragraph(name, font));
if (!StringUtils.isBlank(line1Address)) {
addressParagraph.add(new Paragraph(line1Address, font));
}
if (!StringUtils.isBlank(line2Address)) {
addressParagraph.add(new Paragraph(line2Address, font));
}
String string = "";
if (!StringUtils.isBlank(cityName)) {
string += cityName;
}
if (!StringUtils.isBlank(stateCode)) {
string += ", " + stateCode;
}
if (!StringUtils.isBlank(postalCode)) {
string += "-" + postalCode;
}
if (!StringUtils.isBlank(string)) {
addressParagraph.add(new Paragraph(string, font));
}
return addressParagraph;
}
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#generateCSVToExport(org.kuali.kfs.module.ar.document.ContractsGrantsLOCReviewDocument)
*/
@Override
public byte[] convertLetterOfCreditReviewToCSV(ContractsGrantsLetterOfCreditReviewDocument LOCDocument) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(baos));
try {
csvWriter.writeNext(new String[] {getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.PROPOSAL_NUMBER),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.AWARD_DOCUMENT_NUMBER),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_DESCRIPTION),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, KFSPropertyConstants.ACCOUNT_EXPIRATION_DATE),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AWARD_BUDGET_AMOUNT),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.CLAIM_ON_CASH_BALANCE),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.AMOUNT_TO_DRAW),
getDataDictionaryService().getAttributeLabel(ContractsGrantsLetterOfCreditReviewDetail.class, ArPropertyConstants.FUNDS_NOT_DRAWN)});
if (CollectionUtils.isNotEmpty(LOCDocument.getHeaderReviewDetails()) && CollectionUtils.isNotEmpty(LOCDocument.getAccountReviewDetails())) {
for (ContractsGrantsLetterOfCreditReviewDetail item : LOCDocument.getHeaderReviewDetails()) {
String proposalNumber = org.apache.commons.lang.ObjectUtils.toString(item.getProposalNumber());
String awardDocumentNumber = org.apache.commons.lang.ObjectUtils.toString(item.getAwardDocumentNumber());
for (ContractsGrantsLetterOfCreditReviewDetail newItem : LOCDocument.getAccountReviewDetails()) {
final String accountExpirationDate = ObjectUtils.isNull(newItem.getAccountExpirationDate()) ?
KFSConstants.EMPTY_STRING :
getDateTimeService().toDateString(newItem.getAccountExpirationDate());
if (org.apache.commons.lang.ObjectUtils.equals(item.getProposalNumber(), newItem.getProposalNumber())) {
csvWriter.writeNext(new String[] { proposalNumber,
awardDocumentNumber,
newItem.getAccountDescription(),
newItem.getChartOfAccountsCode(),
newItem.getAccountNumber(),
accountExpirationDate,
contractsGrantsBillingUtilityService.formatForCurrency(newItem.getAwardBudgetAmount()),
contractsGrantsBillingUtilityService.formatForCurrency(newItem.getClaimOnCashBalance()),
contractsGrantsBillingUtilityService.formatForCurrency(newItem.getAmountToDraw()),
contractsGrantsBillingUtilityService.formatForCurrency(newItem.getFundsNotDrawn()) });
}
}
}
}
}
finally {
if (csvWriter != null) {
try {
csvWriter.close();
}
catch (IOException ex) {
csvWriter = null;
throw new RuntimeException("problem during ContractsGrantsInvoiceReportServiceImpl.generateCSVToExport()", ex);
}
}
}
return baos.toByteArray();
}
/**
* @see org.kuali.kfs.module.ar.report.service.ContractsGrantsInvoiceReportService#getPopulatedContractsGrantsInvoiceLookupResults(java.util.Collection)
*/
@Override
public Collection<ContractsGrantsInvoiceLookupResult> getPopulatedContractsGrantsInvoiceLookupResults(Collection<ContractsAndGrantsBillingAward> awards) {
Collection<ContractsGrantsInvoiceLookupResult> populatedContractsGrantsInvoiceLookupResults = new ArrayList<ContractsGrantsInvoiceLookupResult>();
if (awards.size() == 0) {
return populatedContractsGrantsInvoiceLookupResults;
}
Iterator iter = getAwardByAgency(awards).entrySet().iterator();
ContractsGrantsInvoiceLookupResult contractsGrantsInvoiceLookupResult = null;
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
List<ContractsAndGrantsBillingAward> list = (List<ContractsAndGrantsBillingAward>) entry.getValue();
// Get data from first award for agency data
if (CollectionUtils.isNotEmpty(list)){
ContractsAndGrantsBillingAgency agency = list.get(0).getAgency();
contractsGrantsInvoiceLookupResult = new ContractsGrantsInvoiceLookupResult();
if (ObjectUtils.isNotNull(agency)){
contractsGrantsInvoiceLookupResult.setAgencyNumber(agency.getAgencyNumber());
contractsGrantsInvoiceLookupResult.setAgencyReportingName(agency.getReportingName());
contractsGrantsInvoiceLookupResult.setAgencyFullName(agency.getFullName());
contractsGrantsInvoiceLookupResult.setCustomerNumber(agency.getCustomerNumber());
}
contractsGrantsInvoiceLookupResult.setAwards(list);
populatedContractsGrantsInvoiceLookupResults.add(contractsGrantsInvoiceLookupResult);
}
}
return populatedContractsGrantsInvoiceLookupResults;
}
/**
* This helper method returns a map of a list of awards by agency
* @param awards
* @return a Map of the given CGB Awards, keyed by the agency number
*/
protected Map<String, List<ContractsAndGrantsBillingAward>> getAwardByAgency(Collection<ContractsAndGrantsBillingAward> awards) {
// use a map to sort awards by agency
Map<String, List<ContractsAndGrantsBillingAward>> awardsByAgency = new HashMap<>();
for (ContractsAndGrantsBillingAward award : awards) {// To display awards only if their Billing frequency is not LOC Billing
if (!StringUtils.isBlank(award.getBillingFrequencyCode()) && !StringUtils.equalsIgnoreCase(award.getBillingFrequencyCode(), ArConstants.LOC_BILLING_SCHEDULE_CODE)) {
String agencyNumber = award.getAgencyNumber();
if (awardsByAgency.containsKey(agencyNumber)) {
awardsByAgency.get(agencyNumber).add(award);
}
else {
List<ContractsAndGrantsBillingAward> awardsByAgencyNumber = new ArrayList<ContractsAndGrantsBillingAward>();
awardsByAgencyNumber.add(award);
awardsByAgency.put(agencyNumber, awardsByAgencyNumber);
}
}
}
return awardsByAgency;
}
public PersonService getPersonService() {
return personService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
/**
* Gets the businessObjectService attribute.
*
* @return Returns the businessObjectService.
*/
public BusinessObjectService getBusinessObjectService() {
return businessObjectService;
}
/**
* Sets the businessObjectService attribute value.
*
* @param businessObjectService The businessObjectService to set.
*/
public void setBusinessObjectService(BusinessObjectService businessObjectService) {
this.businessObjectService = businessObjectService;
}
public ParameterService getParameterService() {
return parameterService;
}
public void setParameterService(ParameterService parameterService) {
this.parameterService = parameterService;
}
public void setConfigService(ConfigurationService configService) {
this.configService = configService;
}
/**
* Sets the kualiModuleService attribute value.
*
* @param kualiModuleService The kualiModuleService to set.
*/
@NonTransactional
public void setKualiModuleService(KualiModuleService kualiModuleService) {
this.kualiModuleService = kualiModuleService;
}
/**
* @return the documentService
*/
public DocumentService getDocumentService() {
return documentService;
}
/**
* @param documentService the documentService to set
*/
public void setDocumentService(DocumentService documentService) {
this.documentService = documentService;
}
public NoteService getNoteService() {
return noteService;
}
public void setNoteService(NoteService noteService) {
this.noteService = noteService;
}
public ReportInfo getReportInfo() {
return reportInfo;
}
public void setReportInfo(ReportInfo reportInfo) {
this.reportInfo = reportInfo;
}
public ReportGenerationService getReportGenerationService() {
return reportGenerationService;
}
public void setReportGenerationService(ReportGenerationService reportGenerationService) {
this.reportGenerationService = reportGenerationService;
}
public ContractsGrantsInvoiceDocumentService getContractsGrantsInvoiceDocumentService() {
return contractsGrantsInvoiceDocumentService;
}
public void setContractsGrantsInvoiceDocumentService(ContractsGrantsInvoiceDocumentService contractsGrantsInvoiceDocumentService) {
this.contractsGrantsInvoiceDocumentService = contractsGrantsInvoiceDocumentService;
}
public DateTimeService getDateTimeService() {
return dateTimeService;
}
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
public DataDictionaryService getDataDictionaryService() {
return dataDictionaryService;
}
public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
this.dataDictionaryService = dataDictionaryService;
}
public ContractsGrantsBillingUtilityService getContractsGrantsBillingUtilityService() {
return contractsGrantsBillingUtilityService;
}
public void setContractsGrantsBillingUtilityService(ContractsGrantsBillingUtilityService contractsGrantsBillingUtilityService) {
this.contractsGrantsBillingUtilityService = contractsGrantsBillingUtilityService;
}
public OptionsService getOptionsService() {
return optionsService;
}
public void setOptionsService(OptionsService optionsService) {
this.optionsService = optionsService;
}
}