public Document RunReport()
{
UpdateProgress( "Connecting..." );
// Login and setup options for REST calls
RockConfig rockConfig = RockConfig.Load();
_rockRestClient = new RockRestClient( rockConfig.RockBaseUrl );
_rockRestClient.Login( rockConfig.Username, rockConfig.Password );
// shouldn't happen, but just in case the StartDate isn't set, set it to the first day of the current year
DateTime firstDayOfYear = new DateTime( DateTime.Now.Year, 1, 1 );
// note: if a specific person is specified, get them even if they don't have an address.
_contributionStatementOptionsREST = new
{
StartDate = Options.StartDate ?? firstDayOfYear,
EndDate = Options.EndDate,
AccountIds = Options.AccountIds,
IncludeIndividualsWithNoAddress = Options.PersonId.HasValue || Options.IncludeIndividualsWithNoAddress,
DataViewId = Options.DataViewId,
PersonId = Options.PersonId,
OrderByPostalCode = true
};
var organizationAddressAttribute = _rockRestClient.GetData<List<Rock.Client.Attribute>>( "api/attributes", "Key eq 'OrganizationAddress'" ).FirstOrDefault();
if ( organizationAddressAttribute != null )
{
var organizationAddressAttributeValue = _rockRestClient.GetData<List<Rock.Client.AttributeValue>>( "api/AttributeValues", string.Format( "AttributeId eq {0}", organizationAddressAttribute.Id ) ).FirstOrDefault();
Guid locationGuid = Guid.Empty;
if ( Guid.TryParse( organizationAddressAttributeValue.Value, out locationGuid ) )
{
_organizationAddressLocation = _rockRestClient.GetData<List<Rock.Client.Location>>( "api/locations", string.Format( "Guid eq guid'{0}'", locationGuid ) ).FirstOrDefault();
}
}
// If we don't have a _organizationAddressLocation, just create an empty location
_organizationAddressLocation = _organizationAddressLocation ?? new Rock.Client.Location();
// setup report layout and events
DocumentLayout report = new DocumentLayout( this.Options.LayoutFile );
//// if there is an imgLogo and the path is "logo.jpg", use the logo specified in rockconfig.
//// We have to read the layout as Xml first to figure out what the Path of the imgLogo
XmlDocument layoutXmlDoc = new XmlDocument();
layoutXmlDoc.Load( this.Options.LayoutFile );
var imageNodes = layoutXmlDoc.GetElementsByTagName( "image" );
foreach ( var imageNode in imageNodes.OfType<XmlNode>() )
{
string imagePath = imageNode.Attributes["path"].Value;
string imageId = imageNode.Attributes["id"].Value;
if ( imageId.Equals( "imgLogo" ) && imagePath.Equals( RockConfig.DefaultLogoFile, StringComparison.OrdinalIgnoreCase ) )
{
Image imgLogo = report.GetReportElementById( "imgLogo" ) as Image;
if ( imgLogo != null )
{
try
{
if ( !rockConfig.LogoFile.Equals( RockConfig.DefaultLogoFile, StringComparison.OrdinalIgnoreCase ) )
{
imgLogo.ImageData = ceTe.DynamicPDF.Imaging.ImageData.GetImage( rockConfig.LogoFile );
}
}
catch ( Exception ex )
{
throw new Exception( "Error loading Logo Image: " + rockConfig.LogoFile + "\n\n" + ex.Message );
}
}
}
}
Query query = report.GetQueryById( "OuterQuery" );
if ( query == null )
{
throw new MissingReportElementException( "Report requires a QueryElement named 'OuterQuery'" );
}
query.OpeningRecordSet += mainQuery_OpeningRecordSet;
Query orgInfoQuery = report.GetQueryById( "OrgInfoQuery" );
if ( orgInfoQuery == null )
{
throw new MissingReportElementException( "Report requires a QueryElement named 'OrgInfoQuery'" );
}
orgInfoQuery.OpeningRecordSet += orgInfoQuery_OpeningRecordSet;
_accountSummaryQuery = report.GetQueryById( "AccountSummaryQuery" );
if ( _accountSummaryQuery == null )
{
// not required. Just don't do anything if it isn't there
}
else
{
_accountSummaryQuery.OpeningRecordSet += delegate( object s, OpeningRecordSetEventArgs ee )
{
// create a recordset for the _accountSummaryQuery which is the GroupBy summary of AccountName, Amount
/*
The structure of _transactionsDataTable is
DateTime TransactionDateTime
string CurrencyTypeValueName
string Summary (main transaction summary)
DataTable Details {
int AccountId
string AccountName
string Summary (detail summary)
decimal Amount
}
*/
var detailsData = new DataTable();
detailsData.Columns.Add( "AccountId", typeof( int ) );
detailsData.Columns.Add( "AccountName" );
detailsData.Columns.Add( "Amount", typeof( decimal ) );
foreach ( var details in _transactionsDataTable.AsEnumerable().Select( a => ( a["Details"] as DataTable ) ) )
{
foreach ( var row in details.AsEnumerable() )
{
detailsData.Rows.Add( row["AccountId"], row["AccountName"], row["Amount"] );
}
}
var summaryTable = detailsData.AsEnumerable().GroupBy( g => g["AccountId"] ).Select( a => new
{
AccountName = a.Max( x => x["AccountName"].ToString() ),
Amount = a.Sum( x => decimal.Parse( x["Amount"].ToString() ) )
} ).OrderBy( o => o.AccountName );
ee.RecordSet = new EnumerableRecordSet( summaryTable );
};
}
UpdateProgress( "Getting Data..." );
// get outer query data from Rock database via REST now vs in mainQuery_OpeningRecordSet to make sure we have data
DataSet personGroupAddressDataSet = _rockRestClient.PostDataWithResult<object, DataSet>( "api/FinancialTransactions/GetContributionPersonGroupAddress", _contributionStatementOptionsREST );
_personGroupAddressDataTable = personGroupAddressDataSet.Tables[0];
RecordCount = _personGroupAddressDataTable.Rows.Count;
if ( RecordCount > 0 )
{
Document doc = report.Run();
return doc;
}
else
{
return null;
}
}