示例#1
0
        /// <summary>
        /// Gets the financial transaction query.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="usePersonFilters">if set to <c>true</c> [use person filters].</param>
        /// <returns></returns>
        private IQueryable <FinancialTransaction> GetFinancialTransactionQuery(StatementGeneratorOptions options, RockContext rockContext, bool usePersonFilters)
        {
            var financialTransactionService = new FinancialTransactionService(rockContext);
            var financialTransactionQry     = financialTransactionService.Queryable();

            // filter to specified date range
            financialTransactionQry = financialTransactionQry.Where(a => a.TransactionDateTime >= options.StartDate);

            if (options.EndDate.HasValue)
            {
                financialTransactionQry = financialTransactionQry.Where(a => a.TransactionDateTime < options.EndDate.Value);
            }

            // default to Contributions if nothing specified
            var transactionTypeContribution = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid());

            if (options.TransactionTypeIds == null || !options.TransactionTypeIds.Any())
            {
                options.TransactionTypeIds = new List <int>();
                if (transactionTypeContribution != null)
                {
                    options.TransactionTypeIds.Add(transactionTypeContribution.Id);
                }
            }

            if (options.TransactionTypeIds.Count() == 1)
            {
                int selectedTransactionTypeId = options.TransactionTypeIds[0];
                financialTransactionQry = financialTransactionQry.Where(a => a.TransactionTypeValueId == selectedTransactionTypeId);
            }
            else
            {
                financialTransactionQry = financialTransactionQry.Where(a => options.TransactionTypeIds.Contains(a.TransactionTypeValueId));
            }

            // Filter to specified AccountIds (if specified)
            if (options.TransactionAccountIds == null)
            {
                // if TransactionAccountIds wasn't supplied, don't filter on AccountId
            }
            else
            {
                // narrow it down to recipients that have transactions involving any of the AccountIds
                var selectedAccountIds = options.TransactionAccountIds;
                financialTransactionQry = financialTransactionQry.Where(a => a.TransactionDetails.Any(x => selectedAccountIds.Contains(x.AccountId)));
            }

            if (usePersonFilters)
            {
                if (options.PersonId.HasValue)
                {
                    // If PersonId is specified, then this statement is for a specific person, so don't do any other filtering
                    string personGivingId = new PersonService(rockContext).Queryable().Where(a => a.Id == options.PersonId.Value).Select(a => a.GivingId).FirstOrDefault();
                    if (personGivingId != null)
                    {
                        financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAlias.Person.GivingId == personGivingId);
                    }
                    else
                    {
                        // shouldn't happen, but just in case person doesn't exist
                        financialTransactionQry = financialTransactionQry.Where(a => false);
                    }
                }
                else
                {
                    // unless we are using a DataView for filtering, filter based on the IncludeBusiness and ExcludeInActiveIndividuals options
                    if (!options.DataViewId.HasValue)
                    {
                        if (!options.IncludeBusinesses)
                        {
                            int recordTypeValueIdPerson = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                            financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAlias.Person.RecordTypeValueId == recordTypeValueIdPerson);
                        }

                        if (options.ExcludeInActiveIndividuals)
                        {
                            int recordStatusValueIdActive = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id;
                            financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAlias.Person.RecordStatusValueId == recordStatusValueIdActive);
                        }
                    }

                    // Only include Non-Deceased People even if we are including inactive individuals
                    financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAlias.Person.IsDeceased == false);
                }
            }

            return(financialTransactionQry);
        }
示例#2
0
        /// <summary>
        /// Gets the financial pledge query.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="usePersonFilters">if set to <c>true</c> [use person filters].</param>
        /// <returns></returns>
        private IQueryable <FinancialPledge> GetFinancialPledgeQuery(StatementGeneratorOptions options, RockContext rockContext, bool usePersonFilters)
        {
            // pledge information
            var pledgeQry = new FinancialPledgeService(rockContext).Queryable();

            // only include pledges that started *before* the enddate of the statement ( we don't want pledges that start AFTER the statement end date )
            if (options.EndDate.HasValue)
            {
                pledgeQry = pledgeQry.Where(p => p.StartDate <= options.EndDate.Value);
            }

            // also only include pledges that ended *after* the statement start date ( we don't want pledges that ended BEFORE the statement start date )
            pledgeQry = pledgeQry.Where(p => p.EndDate >= options.StartDate.Value);

            // Filter to specified AccountIds (if specified)
            if (options.PledgesAccountIds == null || !options.PledgesAccountIds.Any())
            {
                // if no PledgeAccountIds where specified, don't include any pledges
                pledgeQry = pledgeQry.Where(a => false);
            }
            else
            {
                // NOTE: Only get the Pledges that were specifically pledged to the selected accounts
                // If the PledgesIncludeChildAccounts = true, we'll include transactions to those child accounts as part of the pledge (but only one level deep)
                var selectedAccountIds = options.PledgesAccountIds;
                pledgeQry = pledgeQry.Where(a => a.AccountId.HasValue && selectedAccountIds.Contains(a.AccountId.Value));
            }

            if (usePersonFilters)
            {
                if (options.PersonId.HasValue)
                {
                    // If PersonId is specified, then this statement is for a specific person, so don't do any other filtering
                    string personGivingId = new PersonService(rockContext).Queryable().Where(a => a.Id == options.PersonId.Value).Select(a => a.GivingId).FirstOrDefault();
                    if (personGivingId != null)
                    {
                        pledgeQry = pledgeQry.Where(a => a.PersonAlias.Person.GivingId == personGivingId);
                    }
                    else
                    {
                        // shouldn't happen, but just in case person doesn't exist
                        pledgeQry = pledgeQry.Where(a => false);
                    }
                }
                else
                {
                    // unless we are using a DataView for filtering, filter based on the IncludeBusiness and ExcludeInActiveIndividuals options
                    if (!options.DataViewId.HasValue)
                    {
                        if (!options.IncludeBusinesses)
                        {
                            int recordTypeValueIdPerson = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                            pledgeQry = pledgeQry.Where(a => a.PersonAlias.Person.RecordTypeValueId == recordTypeValueIdPerson);
                        }

                        if (options.ExcludeInActiveIndividuals)
                        {
                            int recordStatusValueIdActive = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id;
                            pledgeQry = pledgeQry.Where(a => a.PersonAlias.Person.RecordStatusValueId == recordStatusValueIdActive);
                        }

                        // Only include Non-Deceased People even if we are including inactive individuals
                        pledgeQry = pledgeQry.Where(a => a.PersonAlias.Person.IsDeceased == false);
                    }
                }
            }

            return(pledgeQry);
        }
示例#3
0
        public List <StatementGeneratorRecipient> GetStatementGeneratorRecipients([FromBody] StatementGeneratorOptions options)
        {
            if (options == null)
            {
                throw new Exception("StatementGenerationOption options must be specified");
            }

            using (var rockContext = new RockContext())
            {
                var financialTransactionQry = GetFinancialTransactionQuery(options, rockContext, true);
                var financialPledgeQry      = GetFinancialPledgeQuery(options, rockContext, true);

                // Get distinct Giving Groups for Persons that have a specific GivingGroupId and have transactions that match the filter
                // These are Persons that give as part of a Group.For example, Husband and Wife
                var qryGivingGroupIdsThatHaveTransactions = financialTransactionQry.Select(a => a.AuthorizedPersonAlias.Person.GivingGroupId).Where(a => a.HasValue)
                                                            .Select(a => new
                {
                    PersonId = ( int? )null,
                    GroupId  = a.Value
                }).Distinct();

                var qryGivingGroupIdsThatHavePledges = financialPledgeQry.Select(a => a.PersonAlias.Person.GivingGroupId).Where(a => a.HasValue)
                                                       .Select(a => new
                {
                    PersonId = ( int? )null,
                    GroupId  = a.Value
                }).Distinct();

                // Get Persons and their GroupId(s) that do not have GivingGroupId and have transactions that match the filter.
                // These are the persons that give as individuals vs as part of a group. We need the Groups (families they belong to) in order
                // to determine which address(es) the statements need to be mailed to
                var groupTypeIdFamily = GroupTypeCache.GetFamilyGroupType().Id;
                var groupMembersQry   = new GroupMemberService(rockContext).Queryable().Where(m => m.Group.GroupTypeId == groupTypeIdFamily);

                var qryIndividualGiversThatHaveTransactions = financialTransactionQry
                                                              .Where(a => !a.AuthorizedPersonAlias.Person.GivingGroupId.HasValue)
                                                              .Select(a => a.AuthorizedPersonAlias.PersonId).Distinct()
                                                              .Join(groupMembersQry, p => p, m => m.PersonId, (p, m) => new { PersonId = ( int? )p, GroupId = m.GroupId });

                var qryIndividualGiversThatHavePledges = financialPledgeQry
                                                         .Where(a => !a.PersonAlias.Person.GivingGroupId.HasValue)
                                                         .Select(a => a.PersonAlias.PersonId).Distinct()
                                                         .Join(groupMembersQry, p => p, m => m.PersonId, (p, m) => new { PersonId = ( int? )p, GroupId = m.GroupId });

                var unionQry = qryGivingGroupIdsThatHaveTransactions.Union(qryIndividualGiversThatHaveTransactions);

                if (options.PledgesAccountIds.Any())
                {
                    unionQry = unionQry.Union(qryGivingGroupIdsThatHavePledges).Union(qryIndividualGiversThatHavePledges);
                }

                /*  Limit to Mailing Address and sort by ZipCode */
                IQueryable <GroupLocation> groupLocationsQry = GetGroupLocationQuery(rockContext);

                // Do an outer join on location so we can include people that don't have an address (if options.IncludeIndividualsWithNoAddress) //
                var unionJoinLocationQry = from pg in unionQry
                                           join l in groupLocationsQry on pg.GroupId equals l.GroupId into u
                                           from l in u.DefaultIfEmpty()
                                           select new
                {
                    pg.PersonId,
                    pg.GroupId,
                    LocationGuid = ( Guid? )l.Location.Guid,
                    l.Location.PostalCode
                };

                // Require that LocationId has a value unless this is for a specific person, a dataview, or the IncludeIndividualsWithNoAddress option is enabled
                if (options.PersonId == null && options.DataViewId == null && !options.IncludeIndividualsWithNoAddress)
                {
                    unionJoinLocationQry = unionJoinLocationQry.Where(a => a.LocationGuid.HasValue);
                }

                if (options.OrderBy == OrderBy.PostalCode)
                {
                    unionJoinLocationQry = unionJoinLocationQry.OrderBy(a => a.PostalCode);
                }
                else if (options.OrderBy == OrderBy.LastName)
                {
                    // get a query to look up LastName for recipients that give as a group
                    var qryLastNameAsGroup = new PersonService(rockContext).Queryable(false, true)
                                             .Where(a => a.GivingLeaderId == a.Id && a.GivingGroupId.HasValue)
                                             .Select(a => new
                    {
                        a.GivingGroupId,
                        a.LastName,
                        a.FirstName
                    });

                    // get a query to look up LastName for recipients that give as individuals
                    var qryLastNameAsIndividual = new PersonService(rockContext).Queryable(false, true);

                    unionJoinLocationQry = unionJoinLocationQry.Select(a => new
                    {
                        a.PersonId,
                        a.GroupId,
                        a.LocationGuid,
                        a.PostalCode,
                        GivingLeader = a.PersonId.HasValue ?
                                       qryLastNameAsIndividual.Where(p => p.Id == a.PersonId).Select(x => new { x.LastName, x.FirstName }).FirstOrDefault()
                            : qryLastNameAsGroup.Where(gl => gl.GivingGroupId == a.GroupId).Select(x => new { x.LastName, x.FirstName }).FirstOrDefault()
                    }).OrderBy(a => a.GivingLeader.LastName).ThenBy(a => a.GivingLeader.FirstName)
                                           .Select(a => new
                    {
                        a.PersonId,
                        a.GroupId,
                        a.LocationGuid,
                        a.PostalCode
                    });
                }

                var givingIdsQry = unionJoinLocationQry.Select(a => new { a.PersonId, a.GroupId, a.LocationGuid });

                var recipientList = givingIdsQry.ToList().Select(a => new StatementGeneratorRecipient {
                    GroupId = a.GroupId, PersonId = a.PersonId, LocationGuid = a.LocationGuid
                }).ToList();

                if (options.DataViewId.HasValue)
                {
                    var dataView = new DataViewService(new RockContext()).Get(options.DataViewId.Value);
                    if (dataView != null)
                    {
                        List <string> errorMessages = new List <string>();
                        var           personList    = dataView.GetQuery(null, null, out errorMessages).OfType <Rock.Model.Person>().Select(a => new { a.Id, a.GivingGroupId }).ToList();
                        HashSet <int> personIds     = new HashSet <int>(personList.Select(a => a.Id));
                        HashSet <int> groupsIds     = new HashSet <int>(personList.Where(a => a.GivingGroupId.HasValue).Select(a => a.GivingGroupId.Value).Distinct());

                        foreach (var recipient in recipientList.ToList())
                        {
                            if (recipient.PersonId.HasValue)
                            {
                                if (!personIds.Contains(recipient.PersonId.Value))
                                {
                                    recipientList.Remove(recipient);
                                }
                            }
                            else
                            {
                                if (!groupsIds.Contains(recipient.GroupId))
                                {
                                    recipientList.Remove(recipient);
                                }
                            }
                        }
                    }
                }

                return(recipientList);
            }
        }
示例#4
0
        public StatementGeneratorRecipientResult GetStatementGeneratorRecipientResult(int groupId, int?personId, Guid?locationGuid, [FromBody] StatementGeneratorOptions options)
        {
            if (options == null)
            {
                throw new Exception("StatementGenerationOption options must be specified");
            }

            if (options.LayoutDefinedValueGuid == null)
            {
                throw new Exception("LayoutDefinedValueGuid option must be specified");
            }

            var result = new StatementGeneratorRecipientResult();

            result.GroupId  = groupId;
            result.PersonId = personId;

            using (var rockContext = new RockContext())
            {
                var financialTransactionQry = this.GetFinancialTransactionQuery(options, rockContext, false);
                var financialPledgeQry      = GetFinancialPledgeQuery(options, rockContext, false);

                var    personList = new List <Person>();
                Person person     = null;
                if (personId.HasValue)
                {
                    person = new PersonService(rockContext).Queryable().Include(a => a.Aliases).Where(a => a.Id == personId.Value).FirstOrDefault();
                    personList.Add(person);
                }
                else
                {
                    // get transactions for all the persons in the specified group that have specified that group as their GivingGroup
                    GroupMemberService groupMemberService = new GroupMemberService(rockContext);
                    personList = groupMemberService.GetByGroupId(groupId).Where(a => a.Person.GivingGroupId == groupId).Select(s => s.Person).Include(a => a.Aliases).ToList();
                    person     = personList.FirstOrDefault();
                }

                if (options.ExcludeOptedOutIndividuals == true && !options.DataViewId.HasValue)
                {
                    int?doNotSendGivingStatementAttributeId = AttributeCache.Get(Rock.StatementGenerator.SystemGuid.Attribute.PERSON_DO_NOT_SEND_GIVING_STATEMENT.AsGuid())?.Id;
                    if (doNotSendGivingStatementAttributeId.HasValue)
                    {
                        var personIds         = personList.Select(a => a.Id).ToList();
                        var optedOutPersonQry = new AttributeValueService(rockContext).Queryable().Where(a => a.AttributeId == doNotSendGivingStatementAttributeId);
                        if (personIds.Count == 1)
                        {
                            int entityPersonId = personIds[0];
                            optedOutPersonQry = optedOutPersonQry.Where(a => a.EntityId == entityPersonId);
                        }
                        else
                        {
                            optedOutPersonQry = optedOutPersonQry.Where(a => personIds.Contains(a.EntityId.Value));
                        }

                        var optedOutPersonIds = optedOutPersonQry
                                                .Select(a => new
                        {
                            PersonId = a.EntityId.Value,
                            a.Value
                        }).ToList().Where(a => a.Value.AsBoolean() == true).Select(a => a.PersonId).ToList();

                        if (optedOutPersonIds.Any())
                        {
                            bool givingLeaderOptedOut = personList.Any(a => optedOutPersonIds.Contains(a.Id) && a.GivingLeaderId == a.Id);

                            var remaingPersonIds = personList.Where(a => !optedOutPersonIds.Contains(a.Id)).ToList();

                            if (givingLeaderOptedOut || !remaingPersonIds.Any())
                            {
                                // If the giving leader opted out, or if there aren't any people in the giving statement that haven't opted out, return NULL and OptedOut = true
                                result.OptedOut = true;
                                result.Html     = null;
                                return(result);
                            }
                        }
                    }
                }

                var personAliasIds = personList.SelectMany(a => a.Aliases.Select(x => x.Id)).ToList();
                if (personAliasIds.Count == 1)
                {
                    var personAliasId = personAliasIds[0];
                    financialTransactionQry = financialTransactionQry.Where(a => a.AuthorizedPersonAliasId.Value == personAliasId);
                }
                else
                {
                    financialTransactionQry = financialTransactionQry.Where(a => personAliasIds.Contains(a.AuthorizedPersonAliasId.Value));
                }

                var financialTransactionsList = financialTransactionQry
                                                .Include(a => a.FinancialPaymentDetail)
                                                .Include(a => a.FinancialPaymentDetail.CurrencyTypeValue)
                                                .Include(a => a.TransactionDetails)
                                                .Include(a => a.TransactionDetails.Select(x => x.Account))
                                                .OrderBy(a => a.TransactionDateTime).ToList();

                foreach (var financialTransaction in financialTransactionsList)
                {
                    if (options.TransactionAccountIds != null)
                    {
                        // remove any Accounts that were not included (in case there was a mix of included and not included accounts in the transaction)
                        financialTransaction.TransactionDetails = financialTransaction.TransactionDetails.Where(a => options.TransactionAccountIds.Contains(a.AccountId)).ToList();
                    }

                    financialTransaction.TransactionDetails = financialTransaction.TransactionDetails.OrderBy(a => a.Account.Order).ThenBy(a => a.Account.Name).ToList();
                }

                var lavaTemplateValue      = DefinedValueCache.Get(options.LayoutDefinedValueGuid.Value);
                var lavaTemplateLava       = lavaTemplateValue.GetAttributeValue("LavaTemplate");
                var lavaTemplateFooterLava = lavaTemplateValue.GetAttributeValue("FooterHtml");

                var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, null, new Lava.CommonMergeFieldsOptions {
                    GetLegacyGlobalMergeFields = false, GetDeviceFamily = false, GetOSFamily = false, GetPageContext = false, GetPageParameters = false, GetCampuses = true, GetCurrentPerson = true
                });
                mergeFields.Add("LavaTemplate", lavaTemplateValue);

                mergeFields.Add("PersonList", personList);
                mergeFields.Add("StatementStartDate", options.StartDate);
                var humanFriendlyEndDate = options.EndDate.HasValue ? options.EndDate.Value.AddDays(-1) : RockDateTime.Now.Date;
                mergeFields.Add("StatementEndDate", humanFriendlyEndDate);

                var familyTitle = Rock.Data.RockUdfHelper.ufnCrm_GetFamilyTitle(rockContext, personId, groupId, null, false, !options.ExcludeInActiveIndividuals);

                mergeFields.Add("Salutation", familyTitle);

                Location mailingAddress;

                if (locationGuid.HasValue)
                {
                    // get the location that was specified for the recipient
                    mailingAddress = new LocationService(rockContext).Get(locationGuid.Value);
                }
                else
                {
                    // for backwards compatibility, get the first address
                    IQueryable <GroupLocation> groupLocationsQry = GetGroupLocationQuery(rockContext);
                    mailingAddress = groupLocationsQry.Where(a => a.GroupId == groupId).Select(a => a.Location).FirstOrDefault();
                }

                mergeFields.Add("MailingAddress", mailingAddress);

                if (mailingAddress != null)
                {
                    mergeFields.Add("StreetAddress1", mailingAddress.Street1);
                    mergeFields.Add("StreetAddress2", mailingAddress.Street2);
                    mergeFields.Add("City", mailingAddress.City);
                    mergeFields.Add("State", mailingAddress.State);
                    mergeFields.Add("PostalCode", mailingAddress.PostalCode);
                    mergeFields.Add("Country", mailingAddress.Country);
                }
                else
                {
                    mergeFields.Add("StreetAddress1", string.Empty);
                    mergeFields.Add("StreetAddress2", string.Empty);
                    mergeFields.Add("City", string.Empty);
                    mergeFields.Add("State", string.Empty);
                    mergeFields.Add("PostalCode", string.Empty);
                    mergeFields.Add("Country", string.Empty);
                }

                var transactionDetailListAll = financialTransactionsList.SelectMany(a => a.TransactionDetails).ToList();

                if (options.HideRefundedTransactions && transactionDetailListAll.Any(a => a.Amount < 0))
                {
                    var allRefunds = transactionDetailListAll.SelectMany(a => a.Transaction.Refunds).ToList();
                    foreach (var refund in allRefunds)
                    {
                        foreach (var refundedOriginalTransactionDetail in refund.OriginalTransaction.TransactionDetails)
                        {
                            // remove the refund's original TransactionDetails from the results
                            if (transactionDetailListAll.Contains(refundedOriginalTransactionDetail))
                            {
                                transactionDetailListAll.Remove(refundedOriginalTransactionDetail);
                                foreach (var refundDetailId in refund.FinancialTransaction.TransactionDetails.Select(a => a.Id))
                                {
                                    // remove the refund's transaction from the results
                                    var refundDetail = transactionDetailListAll.FirstOrDefault(a => a.Id == refundDetailId);
                                    if (refundDetail != null)
                                    {
                                        transactionDetailListAll.Remove(refundDetail);
                                    }
                                }
                            }
                        }
                    }
                }

                if (options.HideCorrectedTransactions && transactionDetailListAll.Any(a => a.Amount < 0))
                {
                    // Hide transactions that are corrected on the same date. Transactions that have a matching negative dollar amount on the same date and same account will not be shown.

                    // get a list of dates that have at least one negative transaction
                    var transactionsByDateList = transactionDetailListAll.GroupBy(a => a.Transaction.TransactionDateTime.Value.Date).Select(a => new
                    {
                        Date = a.Key,
                        TransactionDetails = a.ToList()
                    })
                                                 .Where(a => a.TransactionDetails.Any(x => x.Amount < 0))
                                                 .ToList();


                    foreach (var transactionsByDate in transactionsByDateList)
                    {
                        foreach (var negativeTransaction in transactionsByDate.TransactionDetails.Where(a => a.Amount < 0))
                        {
                            // find the first transaction that has an amount that matches the negative amount (on the same day and same account)
                            // and make sure the matching transaction doesn't already have a refund associated with it
                            var correctedTransactionDetail = transactionsByDate.TransactionDetails
                                                             .Where(a => (a.Amount == (-negativeTransaction.Amount) && a.AccountId == negativeTransaction.AccountId) && !a.Transaction.Refunds.Any())
                                                             .FirstOrDefault();
                            if (correctedTransactionDetail != null)
                            {
                                // if the transaction was corrected, remove it, and also remove the associated correction (the negative one) transaction
                                transactionDetailListAll.Remove(correctedTransactionDetail);
                                transactionDetailListAll.Remove(negativeTransaction);
                            }
                        }
                    }
                }

                List <FinancialTransactionDetail> transactionDetailListCash    = transactionDetailListAll;
                List <FinancialTransactionDetail> transactionDetailListNonCash = new List <FinancialTransactionDetail>();

                if (options.CurrencyTypeIdsCash != null)
                {
                    // NOTE: if there isn't a FinancialPaymentDetail record, assume it is Cash
                    transactionDetailListCash = transactionDetailListCash.Where(a =>
                                                                                (a.Transaction.FinancialPaymentDetailId == null) ||
                                                                                (a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue && options.CurrencyTypeIdsCash.Contains(a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value))).ToList();
                }

                if (options.CurrencyTypeIdsNonCash != null)
                {
                    transactionDetailListNonCash = transactionDetailListAll.Where(a =>
                                                                                  a.Transaction.FinancialPaymentDetailId.HasValue &&
                                                                                  a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue &&
                                                                                  options.CurrencyTypeIdsNonCash.Contains(a.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value)).ToList();
                }

                // Add Merge Fields for Transactions for custom Statements that might want to organize the output by Transaction instead of TransactionDetail
                var transactionListCash    = transactionDetailListCash.GroupBy(a => a.Transaction).Select(a => a.Key).ToList();
                var transactionListNonCash = transactionDetailListNonCash.GroupBy(a => a.Transaction).Select(a => a.Key).ToList();
                mergeFields.Add("Transactions", transactionListCash);
                mergeFields.Add("TransactionsNonCash", transactionListNonCash);

                // Add the standard TransactionDetails and TransactionDetailsNonCash that the default Rock templates use
                mergeFields.Add("TransactionDetails", transactionDetailListCash);
                mergeFields.Add("TransactionDetailsNonCash", transactionDetailListNonCash);

                mergeFields.Add("TotalContributionAmount", transactionDetailListCash.Sum(a => a.Amount));
                mergeFields.Add("TotalContributionCount", transactionDetailListCash.Count());

                mergeFields.Add("TotalContributionAmountNonCash", transactionDetailListNonCash.Sum(a => a.Amount));
                mergeFields.Add("TotalContributionCountNonCash", transactionDetailListNonCash.Count());

                mergeFields.Add("AccountSummary", transactionDetailListCash.GroupBy(t => t.Account.Name).Select(s => new { AccountName = s.Key, Total = s.Sum(a => a.Amount), Order = s.Max(a => a.Account.Order) }).OrderBy(s => s.Order));
                mergeFields.Add("AccountSummaryNonCash", transactionDetailListNonCash.GroupBy(t => t.Account.Name).Select(s => new { AccountName = s.Key, Total = s.Sum(a => a.Amount), Order = s.Max(a => a.Account.Order) }).OrderBy(s => s.Order));

                if (options.PledgesAccountIds.Any())
                {
                    var pledgeList = financialPledgeQry
                                     .Where(p => p.PersonAliasId.HasValue && personAliasIds.Contains(p.PersonAliasId.Value))
                                     .Include(a => a.Account)
                                     .OrderBy(a => a.Account.Order)
                                     .ThenBy(a => a.Account.PublicName)
                                     .ToList();

                    var pledgeSummaryByPledgeList = pledgeList
                                                    .Select(p => new
                    {
                        p.Account,
                        Pledge = p
                    })
                                                    .ToList();

                    //// Pledges but organized by Account (in case more than one pledge goes to the same account)
                    //// NOTE: In the case of multiple pledges to the same account (just in case they accidently or intentionally had multiple pledges to the same account)
                    ////  -- Date Range
                    ////    -- StartDate: Earliest StartDate of all the pledges for that account
                    ////    -- EndDate: Lastest EndDate of all the pledges for that account
                    ////  -- Amount Pledged: Sum of all Pledges to that account
                    ////  -- Amount Given:
                    ////    --  The sum of transaction amounts to that account between
                    ////      -- Start Date: Earliest Start Date of all the pledges to that account
                    ////      -- End Date: Whatever is earlier (Statement End Date or Pledges' End Date)
                    var pledgeSummaryList = pledgeSummaryByPledgeList.GroupBy(a => a.Account).Select(a => new PledgeSummary
                    {
                        Account    = a.Key,
                        PledgeList = a.Select(x => x.Pledge).ToList()
                    }).ToList();

                    // add detailed pledge information
                    if (pledgeSummaryList.Any())
                    {
                        int statementPledgeYear = options.StartDate.Value.Year;

                        List <int> pledgeCurrencyTypeIds = null;
                        if (options.CurrencyTypeIdsCash != null)
                        {
                            pledgeCurrencyTypeIds = options.CurrencyTypeIdsCash;
                            if (options.PledgesIncludeNonCashGifts && options.CurrencyTypeIdsNonCash != null)
                            {
                                pledgeCurrencyTypeIds = options.CurrencyTypeIdsCash.Union(options.CurrencyTypeIdsNonCash).ToList();
                            }
                        }

                        foreach (var pledgeSummary in pledgeSummaryList)
                        {
                            DateTime adjustedPledgeEndDate = pledgeSummary.PledgeEndDate.Value.Date;
                            if (pledgeSummary.PledgeEndDate.Value.Date < DateTime.MaxValue.Date)
                            {
                                adjustedPledgeEndDate = pledgeSummary.PledgeEndDate.Value.Date.AddDays(1);
                            }

                            if (options.EndDate.HasValue)
                            {
                                if (adjustedPledgeEndDate > options.EndDate.Value)
                                {
                                    adjustedPledgeEndDate = options.EndDate.Value;
                                }
                            }

                            var pledgeFinancialTransactionDetailQry = new FinancialTransactionDetailService(rockContext).Queryable().Where(t =>
                                                                                                                                           t.Transaction.AuthorizedPersonAliasId.HasValue && personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value) &&
                                                                                                                                           t.Transaction.TransactionDateTime >= pledgeSummary.PledgeStartDate &&
                                                                                                                                           t.Transaction.TransactionDateTime < adjustedPledgeEndDate);

                            if (options.PledgesIncludeChildAccounts)
                            {
                                // If PledgesIncludeChildAccounts = true, we'll include transactions to those child accounts as part of the pledge (but only one level deep)
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t =>
                                                                                                                t.AccountId == pledgeSummary.AccountId
                                                                                                                ||
                                                                                                                (t.Account.ParentAccountId.HasValue && t.Account.ParentAccountId == pledgeSummary.AccountId)
                                                                                                                );
                            }
                            else
                            {
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t => t.AccountId == pledgeSummary.AccountId);
                            }

                            if (pledgeCurrencyTypeIds != null)
                            {
                                pledgeFinancialTransactionDetailQry = pledgeFinancialTransactionDetailQry.Where(t =>
                                                                                                                t.Transaction.FinancialPaymentDetailId.HasValue &&
                                                                                                                t.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.HasValue && pledgeCurrencyTypeIds.Contains(t.Transaction.FinancialPaymentDetail.CurrencyTypeValueId.Value));
                            }

                            pledgeSummary.AmountGiven = pledgeFinancialTransactionDetailQry.Sum(t => ( decimal? )t.Amount) ?? 0;
                        }
                    }

                    // Pledges ( organized by each Account in case an account is used by more than one pledge )
                    mergeFields.Add("Pledges", pledgeSummaryList);
                }

                mergeFields.Add("Options", options);

                var currentPerson = this.GetPerson();
                result.Html = lavaTemplateLava.ResolveMergeFields(mergeFields, currentPerson);
                if (!string.IsNullOrEmpty(lavaTemplateFooterLava))
                {
                    result.FooterHtml = lavaTemplateFooterLava.ResolveMergeFields(mergeFields, currentPerson);
                }

                result.Html = result.Html.Trim();
            }

            return(result);
        }
示例#5
0
 public StatementGeneratorRecipientResult GetStatementGeneratorRecipientResult(int groupId, Guid?locationGuid, [FromBody] StatementGeneratorOptions options)
 {
     return(GetStatementGeneratorRecipientResult(groupId, ( int? )null, locationGuid, options));
 }
示例#6
0
 public StatementGeneratorRecipientResult GetStatementGeneratorRecipientResult(int groupId, int?personId, [FromBody] StatementGeneratorOptions options)
 {
     return(GetStatementGeneratorRecipientResult(groupId, personId, ( Guid? )null, options));
 }