/// <summary>
        /// Binds the contribution statements.
        /// </summary>
        private void BindContributionStatements()
        {
            var numberOfYears = GetAttributeValue(AttributeKey.MaxYearsToDisplay).AsInteger();

            var rockContext = new RockContext();
            var financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);
            var personAliasIds = new PersonAliasService(rockContext).Queryable().Where(a => a.Person.GivingId == Person.GivingId).Select(a => a.Id).ToList();

            // get the transactions for the person or all the members in the person's giving group (Family)
            var qry = financialTransactionDetailService.Queryable().AsNoTracking().Where(t =>
                                                                                         t.Transaction.AuthorizedPersonAliasId.HasValue &&
                                                                                         personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value) &&
                                                                                         t.Transaction.TransactionDateTime.HasValue);

            if (string.IsNullOrWhiteSpace(GetAttributeValue(AttributeKey.Accounts)))
            {
                qry = qry.Where(t => t.Account.IsTaxDeductible);
            }
            else
            {
                var accountGuids = GetAttributeValue(AttributeKey.Accounts).Split(',').Select(Guid.Parse).ToList();
                qry = qry.Where(t => accountGuids.Contains(t.Account.Guid));
            }

            var yearQry = qry.GroupBy(t => t.Transaction.TransactionDateTime.Value.Year)
                          .Select(g => g.Key)
                          .OrderByDescending(y => y);

            var statementYears = yearQry.Take(numberOfYears).ToList();

            rptContributionStatementsYYYY.DataSource = statementYears;
            rptContributionStatementsYYYY.DataBind();

            pnlStatement.Visible = statementYears.Any();
        }
Пример #2
0
        /// <summary>
        /// Assigns the entity to transaction detail.
        /// </summary>
        /// <param name="entityId">The entity identifier.</param>
        /// <param name="financialTransactionDetailId">The financial transaction detail identifier.</param>
        private void AssignEntityToTransactionDetail(int?entityId, int?financialTransactionDetailId)
        {
            if (financialTransactionDetailId.HasValue)
            {
                var rockContext = new RockContext();
                var financialTransactionDetail = new FinancialTransactionDetailService(rockContext).Get(financialTransactionDetailId.Value);
                financialTransactionDetail.EntityTypeId = _transactionEntityType.Id;
                financialTransactionDetail.EntityId     = entityId;

                DefinedValueCache blockTransactionType = null;
                Guid?blockTransactionTypeGuid          = this.GetAttributeValue("TransactionTypeGuid").AsGuidOrNull();
                if (blockTransactionTypeGuid.HasValue)
                {
                    blockTransactionType = DefinedValueCache.Read(blockTransactionTypeGuid.Value);
                }

                if (blockTransactionType != null && blockTransactionType.Id != financialTransactionDetail.Transaction.TransactionTypeValueId)
                {
                    financialTransactionDetail.Transaction.TransactionTypeValueId = blockTransactionType.Id;
                    var lTransactionType = phTableRows.ControlsOfTypeRecursive <LiteralControl>().Where(a => a.ID == "lTransactionType_" + financialTransactionDetail.Id.ToString()).FirstOrDefault();
                    if (lTransactionType != null)
                    {
                        lTransactionType.Text = string.Format("<td>{0}</td>", DefinedValueCache.Read(financialTransactionDetail.Transaction.TransactionTypeValueId));
                    }
                }

                rockContext.SaveChanges();

                var btnSaveEntity = phTableRows.ControlsOfTypeRecursive <LinkButton>().Where(a => a.ID == "btnSaveEntity_" + financialTransactionDetail.Id.ToString()).FirstOrDefault();
                if (btnSaveEntity != null)
                {
                    btnSaveEntity.ToolTip = "Last Modified at " + financialTransactionDetail.ModifiedDateTime.ToString();
                }
            }
        }
Пример #3
0
        private IEnumerable <Rock.Chart.IChartData> GetChartData()
        {
            var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(drpSlidingDateRange.DelimitedValues);

            var currenceTypeIds = new List <int>();

            cblCurrencyTypes.SelectedValues.ForEach(i => currenceTypeIds.Add(i.AsInteger()));

            var sourceIds = new List <int>();

            cblTransactionSource.SelectedValues.ForEach(i => sourceIds.Add(i.AsInteger()));

            var accountIds = new List <int>();

            foreach (var cblAccounts in phAccounts.Controls.OfType <RockCheckBoxList>())
            {
                accountIds.AddRange(cblAccounts.SelectedValuesAsInt);
            }

            var chartData = new FinancialTransactionDetailService(_rockContext).GetChartData(
                hfGroupBy.Value.ConvertToEnumOrNull <ChartGroupBy>() ?? ChartGroupBy.Week,
                hfGraphBy.Value.ConvertToEnumOrNull <TransactionGraphBy>() ?? TransactionGraphBy.Total,
                dateRange.Start,
                dateRange.End,
                nreAmount.LowerValue,
                nreAmount.UpperValue,
                currenceTypeIds,
                sourceIds,
                accountIds,
                dvpDataView.SelectedValueAsInt());

            return(chartData);
        }
        /// <summary>
        /// Assigns the entity to transaction detail.
        /// </summary>
        /// <param name="entityId">The entity identifier.</param>
        /// <param name="financialTransactionDetailId">The financial transaction detail identifier.</param>
        private void AssignEntityToTransactionDetail(int?entityId, int?financialTransactionDetailId)
        {
            if (financialTransactionDetailId.HasValue)
            {
                var financialTransactionDetailLookup = _financialTransactionDetailList.FirstOrDefault(a => a.Id == financialTransactionDetailId);

                // An un-match operation is only allowed if the entity type is already our target entity type.
                if (financialTransactionDetailLookup.EntityTypeId != _transactionEntityType.Id && !entityId.HasValue)
                {
                    return;
                }

                if (financialTransactionDetailLookup.EntityTypeId != _transactionEntityType.Id ||
                    financialTransactionDetailLookup.EntityId != entityId ||
                    _blockTransactionTypeId.HasValue && _blockTransactionTypeId != financialTransactionDetailLookup.Transaction.TransactionTypeValueId)
                {
                    var rockContext = new RockContext();
                    var financialTransactionDetail = new FinancialTransactionDetailService(rockContext).Get(financialTransactionDetailId.Value);
                    financialTransactionDetail.EntityTypeId = _transactionEntityType.Id;
                    financialTransactionDetail.EntityId     = entityId;

                    if (_blockTransactionTypeId.HasValue && _blockTransactionTypeId != financialTransactionDetail.Transaction.TransactionTypeValueId)
                    {
                        financialTransactionDetail.Transaction.TransactionTypeValueId = _blockTransactionTypeId.Value;
                        var lTransactionType = phTableRows.ControlsOfTypeRecursive <LiteralControl>().Where(a => a.ID == "lTransactionType_" + financialTransactionDetail.Id.ToString()).FirstOrDefault();
                        if (lTransactionType != null)
                        {
                            lTransactionType.Text = string.Format("<td>{0}</td>", DefinedValueCache.Get(financialTransactionDetail.Transaction.TransactionTypeValueId));
                        }
                    }

                    rockContext.SaveChanges();
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindGroupMembersGrid()
        {
            var rockContext = new RockContext();

            int groupId           = hfGroupId.Value.AsInteger();
            var groupMembersQuery = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == groupId);
            var group             = new GroupService(rockContext).Get(groupId);

            group.LoadAttributes(rockContext);
            var defaultIndividualFundRaisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();

            groupMembersQuery = groupMembersQuery.Sort(gGroupMembers.SortProperty ?? new SortProperty {
                Property = "Person.LastName, Person.NickName"
            });

            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();

            var groupMemberList = groupMembersQuery.ToList().Select(a =>
            {
                var groupMember = a;
                groupMember.LoadAttributes(rockContext);

                var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                        .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                               d.EntityId == groupMember.Id)
                                        .Sum(d => (decimal?)d.Amount) ?? 0.00M;

                var individualFundraisingGoal          = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                bool disablePublicContributionRequests = groupMember.GetAttributeValue("DisablePublicContributionRequests").AsBoolean();
                if (!individualFundraisingGoal.HasValue)
                {
                    individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                }

                var fundingRemaining = individualFundraisingGoal - contributionTotal;
                if (disablePublicContributionRequests)
                {
                    fundingRemaining = null;
                }
                else if (fundingRemaining < 0)
                {
                    fundingRemaining = 0.00M;
                }

                return(new
                {
                    groupMember.Id,
                    PersonId = groupMember.PersonId,
                    DateTimeAdded = groupMember.DateTimeAdded,
                    groupMember.Person.FullName,
                    groupMember.Person.Gender,
                    FundingRemaining = fundingRemaining,
                    GroupRoleName = a.GroupRole.Name
                });
            }).ToList();

            gGroupMembers.DataSource = groupMemberList;
            gGroupMembers.DataBind();
        }
        private void DisplayResults()
        {
            RockContext rockContext = new RockContext();

            var statementYear = PageParameter(PageParameterKey.StatementYear).AsIntegerOrNull() ?? RockDateTime.Now.Year;

            FinancialTransactionDetailService financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);

            Person targetPerson = CurrentPerson;

            var personGuid = PageParameter(PageParameterKey.PersonGuid).AsGuidOrNull();

            if (personGuid.HasValue)
            {
                // if "AllowPersonQueryString is False", only use the PersonGuid if it is a Guid of one of the current person's businesses
                var isCurrentPersonsBusiness = targetPerson != null && targetPerson.GetBusinesses().Any(b => b.Guid == personGuid.Value);
                if (GetAttributeValue(AttributeKey.AllowPersonQueryString).AsBoolean() || isCurrentPersonsBusiness)
                {
                    var person = new PersonService(rockContext).Get(personGuid.Value);
                    if (person != null)
                    {
                        targetPerson = person;
                    }
                }
            }

            FinancialStatementGeneratorOptions financialStatementGeneratorOptions = new FinancialStatementGeneratorOptions();
            var startDate = new DateTime(statementYear, 1, 1);

            financialStatementGeneratorOptions.StartDate    = startDate;
            financialStatementGeneratorOptions.EndDate      = startDate.AddYears(1);
            financialStatementGeneratorOptions.RenderMedium = "Html";

            var financialStatementTemplateGuid = this.GetAttributeValue(AttributeKey.FinancialStatementTemplate).AsGuidOrNull() ?? Rock.SystemGuid.FinancialStatementTemplate.ROCK_DEFAULT.AsGuid();

            financialStatementGeneratorOptions.FinancialStatementTemplateId = new FinancialStatementTemplateService(rockContext).GetId(financialStatementTemplateGuid);

            FinancialStatementGeneratorRecipient financialStatementGeneratorRecipient = new FinancialStatementGeneratorRecipient();

            if (targetPerson.GivingGroupId.HasValue)
            {
                financialStatementGeneratorRecipient.GroupId = targetPerson.GivingGroupId.Value;
            }
            else
            {
                financialStatementGeneratorRecipient.GroupId  = targetPerson.PrimaryFamilyId ?? 0;
                financialStatementGeneratorRecipient.PersonId = targetPerson.Id;
            }

            FinancialStatementGeneratorRecipientRequest financialStatementGeneratorRecipientRequest = new FinancialStatementGeneratorRecipientRequest(financialStatementGeneratorOptions)
            {
                FinancialStatementGeneratorRecipient = financialStatementGeneratorRecipient
            };

            var result = FinancialStatementGeneratorHelper.GetStatementGeneratorRecipientResult(financialStatementGeneratorRecipientRequest, this.CurrentPerson);

            Response.Write(result.Html);
            Response.End();
        }
Пример #7
0
        private void DisplayResults()
        {
            var numberOfYears = GetAttributeValue("MaxYearsToDisplay").AsInteger();

            RockContext rockContext = new RockContext();

            FinancialTransactionDetailService financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);

            List <int> personAliasIds;

            // fetch all the possible PersonAliasIds that have this GivingID to help optimize the SQL
            if (TargetPerson != null)
            {
                personAliasIds = new PersonAliasService(rockContext).Queryable().Where(a => a.Person.GivingId == TargetPerson.GivingId).Select(a => a.Id).ToList();
            }
            else
            {
                personAliasIds = new List <int>();
            }

            // get the transactions for the person or all the members in the person's giving group (Family)
            var qry = financialTransactionDetailService.Queryable().AsNoTracking().Where(t =>
                                                                                         t.Transaction.AuthorizedPersonAliasId.HasValue &&
                                                                                         personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value) &&
                                                                                         t.Transaction.TransactionDateTime.HasValue);

            if (string.IsNullOrWhiteSpace(GetAttributeValue("Accounts")))
            {
                qry = qry.Where(t => t.Account.IsTaxDeductible);
            }
            else
            {
                var accountGuids = GetAttributeValue("Accounts").Split(',').Select(Guid.Parse).ToList();
                qry = qry.Where(t => accountGuids.Contains(t.Account.Guid));
            }

            var yearQry = qry.GroupBy(t => t.Transaction.TransactionDateTime.Value.Year)
                          .Select(g => new { Year = g.Key })
                          .OrderByDescending(y => y.Year);

            var statementYears = yearQry.Take(numberOfYears).ToList();

            var mergeFields = new Dictionary <string, object>();

            mergeFields.Add("DetailPage", LinkedPageRoute("DetailPage"));
            mergeFields.Add("StatementYears", statementYears);

            if (TargetPerson != null)
            {
                mergeFields.Add("PersonGuid", TargetPerson.Guid);
            }

            var template = GetAttributeValue("LavaTemplate");

            lResults.Text = template.ResolveMergeFields(mergeFields);

            // don't show anything if the person doesn't have any transactions
            lResults.Visible = statementYears.Any();
        }
        protected void ShowDetail()
        {
            var rockContext = new RockContext();
            var isExported  = false;

            _financialBatch = new FinancialBatchService(rockContext).Get(_batchId);
            DateTime?dateExported = null;

            decimal variance = 0;

            if (_financialBatch != null)
            {
                var     financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);
                var     qryTransactionDetails             = financialTransactionDetailService.Queryable().Where(a => a.Transaction.BatchId == _financialBatch.Id);
                decimal txnTotal = qryTransactionDetails.Select(a => ( decimal? )a.Amount).Sum() ?? 0;
                variance = txnTotal - _financialBatch.ControlAmount;

                _financialBatch.LoadAttributes();

                dateExported = ( DateTime? )_financialBatch.AttributeValues["rocks.kfs.FinancialEdge.DateExported"].ValueAsType;

                if (dateExported != null && dateExported > DateTime.MinValue)
                {
                    isExported = true;
                }
            }

            if (ValidSettings() && !isExported)
            {
                btnExportToFinancialEdge.Text    = GetAttributeValue("ButtonText");
                btnExportToFinancialEdge.Visible = true;
                if (variance == 0)
                {
                    btnExportToFinancialEdge.Enabled = true;
                }
                else
                {
                    btnExportToFinancialEdge.Enabled = false;
                }
            }
            else if (isExported)
            {
                litDateExported.Text    = string.Format("<div class=\"small\">Exported: {0}</div>", dateExported.ToRelativeDateString());
                litDateExported.Visible = true;

                if (UserCanEdit)
                {
                    btnRemoveDate.Visible = true;
                }
            }
        }
Пример #9
0
 /// <summary>
 /// Binds the transaction detail grid.
 /// </summary>
 /// <param name="transaction">The transaction.</param>
 private void BindTransactionDetailGrid(FinancialTransaction transaction)
 {
     // Load the TransactionDetails grid here if this transaction already exists.
     if (transaction.Id != 0)
     {
         var financialTransactionDetails = new FinancialTransactionDetailService(new RockContext()).Queryable().Where(trans => trans.TransactionId == transaction.Id).ToList();
         gTransactionDetails.DataSource = financialTransactionDetails;
         gTransactionDetails.DataBind();
         pnlTransactionDetails.Visible = true;
     }
     else
     {
         pnlTransactionDetails.Visible = false;
     }
 }
Пример #10
0
 /// <summary>
 /// Handles the RowSelected event of the gTransactionDetails control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param>
 protected void gTransactionDetails_RowSelected(object sender, Rock.Web.UI.Controls.RowEventArgs e)
 {
     if (!readOnly)
     {
         var rockContext = new RockContext();
         LoadRelatedImages(new FinancialTransactionService(rockContext).Get(hfIdTransValue.ValueAsInt()).Id);
         var transactionDetailsId = (int)e.RowKeyValue;
         hfIdValue.Value = transactionDetailsId.ToString();
         var ftd = new FinancialTransactionDetailService(rockContext).Get(transactionDetailsId);
         ddlTransactionAccount.SelectedValue = ftd.AccountId.ToString();
         tbTransactionAmount.Text            = ftd.Amount.ToString();
         tbTransactionSummary.Text           = ftd.Summary;
         mdDetails.Show();
     }
 }
        /// <summary>
        /// Handles the Click event of the lbDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void lbDelete_Click(object sender, EventArgs e)
        {
            var lbDelete = sender as LinkButton;

            if (lbDelete != null)
            {
                int?financialTransactionDetailId = lbDelete.ID.Replace("lbDelete_", string.Empty).AsInteger();
                var rockContext = new RockContext();
                var financialTransactionDetail = new FinancialTransactionDetailService(rockContext).Get(financialTransactionDetailId.Value);
                financialTransactionDetail.EntityTypeId = null;
                financialTransactionDetail.EntityId     = null;
                rockContext.SaveChanges();

                BindHtmlGrid();
                LoadRegistrationDropDowns();
            }
        }
        public static void ClassInitialize(TestContext testContext)
        {
            _rockContext              = new RockContext();
            _accountService           = new FinancialAccountService(_rockContext);
            _batchService             = new FinancialBatchService(_rockContext);
            _transactionService       = new FinancialTransactionService(_rockContext);
            _paymentService           = new FinancialPaymentDetailService(_rockContext);
            _achievementTypeService   = new AchievementTypeService(_rockContext);
            _definedValueService      = new DefinedValueService(_rockContext);
            _definedTypeService       = new DefinedTypeService(_rockContext);
            _transactionDetailService = new FinancialTransactionDetailService(_rockContext);

            DeleteTestData();
            PopulateDefinedValues();
            CreateFinancialTransactionData();
            CreateAchievementTypeData();
        }
Пример #13
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override System.Linq.Expressions.Expression GetExpression(Type entityType, Data.IService serviceInstance, System.Linq.Expressions.ParameterExpression parameterExpression, string selection)
        {
            string[] selectionValues = selection.Split('|');
            if (selectionValues.Length >= 1)
            {
                var accountGuids = selectionValues[0].Split(',').Select(a => a.AsGuid()).ToList();
                var accountIds   = new FinancialAccountService((RockContext)serviceInstance.Context).GetByGuids(accountGuids).Select(a => a.Id).ToList();

                var qry = new FinancialTransactionDetailService((RockContext)serviceInstance.Context).Queryable()
                          .Where(p => accountIds.Contains(p.AccountId));

                Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.FinancialTransactionDetail>(qry, parameterExpression, "p");

                return(extractedFilterExpression);
            }

            return(null);
        }
        /// <summary>
        /// Handles the Click event of the btnNext control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnNext_Click(object sender, EventArgs e)
        {
            var groupMemberId = ddlParticipant.SelectedValue.AsIntegerOrNull();

            if (groupMemberId.HasValue)
            {
                var rockContext = new RockContext();
                var groupMember = new GroupMemberService(rockContext).Get(groupMemberId.Value);
                if (groupMember != null)
                {
                    var queryParams = new Dictionary <string, string>();
                    queryParams.Add("GroupMemberId", groupMemberId.ToString());

                    groupMember.LoadAttributes(rockContext);
                    groupMember.Group.LoadAttributes(rockContext);
                    var financialAccount = new FinancialAccountService(rockContext).Get(groupMember.Group.GetAttributeValue("FinancialAccount").AsGuid());
                    if (financialAccount != null)
                    {
                        queryParams.Add("AccountIds", financialAccount.Id.ToString());
                    }

                    if (groupMember.Group.GetAttributeValue("CapFundraisingAmount").AsBoolean())
                    {
                        var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();

                        var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                                .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                                       d.EntityId == groupMemberId)
                                                .Sum(a => (decimal?)a.Amount) ?? 0.00M;

                        var individualFundraisingGoal = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                        if (!individualFundraisingGoal.HasValue)
                        {
                            individualFundraisingGoal = groupMember.Group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                        }

                        var amountLeft = individualFundraisingGoal - contributionTotal;
                        queryParams.Add("AmountLimit", amountLeft.ToString());
                    }

                    NavigateToLinkedPage("TransactionEntryPage", queryParams);
                }
            }
        }
        private void DisplayResults()
        {
            var numberOfYears = GetAttributeValue("MaxYearsToDisplay").AsInteger();

            RockContext rockContext = new RockContext();

            FinancialTransactionDetailService financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);

            var qry = financialTransactionDetailService.Queryable().AsNoTracking()
                      .Where(t => t.Transaction.AuthorizedPersonAlias.Person.GivingId == TargetPerson.GivingId);

            if (string.IsNullOrWhiteSpace(GetAttributeValue("Accounts")))
            {
                qry = qry.Where(t => t.Account.IsTaxDeductible);
            }
            else
            {
                var accountGuids = GetAttributeValue("Accounts").Split(',').Select(Guid.Parse).ToList();
                qry = qry.Where(t => accountGuids.Contains(t.Account.Guid));
            }

            var yearQry = qry.GroupBy(t => t.Transaction.TransactionDateTime.Value.Year)
                          .Select(g => new { Year = g.Key })
                          .OrderByDescending(y => y.Year);

            var mergeFields = new Dictionary <string, object>();

            mergeFields.Add("DetailPage", LinkedPageRoute("DetailPage"));
            mergeFields.Add("StatementYears", yearQry.Take(numberOfYears));
            mergeFields.Add("PersonGuid", TargetPerson.Guid);

            var template = GetAttributeValue("LavaTemplate");

            lResults.Text = template.ResolveMergeFields(mergeFields);

            // show debug info
            if (GetAttributeValue("EnableDebug").AsBoolean() && IsUserAuthorized(Authorization.EDIT))
            {
                lDebug.Visible = true;
                lDebug.Text    = mergeFields.lavaDebugInfo();
            }
        }
Пример #16
0
        /// <summary>
        /// Handles the SaveClick event of the mdDetails control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void mdDetails_SaveClick(object sender, EventArgs e)
        {
            var rockContext = new RockContext();

            if (!string.IsNullOrWhiteSpace(tbTransactionAmount.Text))
            {
                var ftdService = new FinancialTransactionDetailService(rockContext);
                FinancialTransactionDetail ftd = null;
                var transactionDetailId        = int.Parse(hfIdValue.Value);
                if (transactionDetailId > 0)
                {
                    ftd = ftdService.Get(transactionDetailId);
                }
                else
                {
                    ftd = new FinancialTransactionDetail {
                        Id = 0
                    };
                }

                ftd.TransactionId = hfIdTransValue.ValueAsInt();
                ftd.AccountId     = int.Parse(ddlTransactionAccount.SelectedValue);
                ftd.Amount        = decimal.Parse(tbTransactionAmount.Text);
                ftd.Summary       = tbTransactionSummary.Text;

                if (transactionDetailId == 0)
                {
                    ftdService.Add(ftd);
                }

                rockContext.SaveChanges();
            }

            mdDetails.Hide();
            FinancialTransaction transaction = new FinancialTransaction();

            transaction = new FinancialTransactionService(rockContext).Get(hfIdTransValue.ValueAsInt());
            BindTransactionDetailGrid(transaction);
            LoadRelatedImages(transaction.Id);
        }
        /// <summary>
        /// Handles the Delete event of the gTransactionEntities control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs"/> instance containing the event data.</param>
        protected void gTransactionEntities_Delete(object sender, RowEventArgs e)
        {
            var rockContext = new RockContext();
            var service     = new FinancialTransactionDetailService(rockContext);
            var detail      = service.Get(e.RowKeyId);

            if (detail == null)
            {
                return;
            }
            else
            {
                var changes  = new History.HistoryChangeList();
                var typeName = detail.EntityType.FriendlyName;
                var name     = GetEntityName(detail.EntityTypeId, detail.EntityId, rockContext);

                History.EvaluateChange(changes, "Entity Type Id", detail.EntityTypeId, null);
                History.EvaluateChange(changes, "Entity Id", detail.EntityId, null);

                detail.EntityTypeId = null;
                detail.EntityId     = null;

                changes.AddCustom("Removed", "Removed", string.Format("Removed transaction detail association to {0} {1}", typeName, name));

                HistoryService.SaveChanges(
                    rockContext,
                    typeof(FinancialTransaction),
                    Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(),
                    detail.TransactionId,
                    changes
                    );

                rockContext.SaveChanges();
            }

            BindGrid();
        }
Пример #18
0
        /// <summary>
        /// Handles the Delete event of the gTransactionDetails control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param>
        protected void gTransactionDetails_Delete(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            var rockContext = new RockContext();
            var ftdService  = new FinancialTransactionDetailService(rockContext);
            var ftd         = ftdService.Get(e.RowKeyId);

            if (ftd != null)
            {
                string errorMessage;
                if (!ftdService.CanDelete(ftd, out errorMessage))
                {
                    maGridWarning.Show(errorMessage, Rock.Web.UI.Controls.ModalAlertType.Information);
                    return;
                }

                ftdService.Delete(ftd);
                rockContext.SaveChanges();
            }

            FinancialTransaction transaction = new FinancialTransaction();

            transaction = new FinancialTransactionService(rockContext).Get(hfIdTransValue.ValueAsInt());
            BindTransactionDetailGrid(transaction);
        }
        /// <summary>
        /// Handles the SelectedIndexChanged event of the ddlRegistration control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void ddlRegistration_SelectedIndexChanged(object sender, EventArgs e)
        {
            var ddlRegistration = sender as RockDropDownList;

            if (ddlRegistration != null && ddlRegistration.SelectedValue.AsIntegerOrNull().HasValue)
            {
                int?financialTransactionDetailId = ddlRegistration.ID.Replace("ddlRegistration_", string.Empty).AsInteger();
                var rockContext = new RockContext();
                var financialTransactionDetail = new FinancialTransactionDetailService(rockContext).Get(financialTransactionDetailId.Value);
                var registrationEntityTypeId   = EntityTypeCache.GetId <Registration>();
                financialTransactionDetail.EntityTypeId = registrationEntityTypeId;
                financialTransactionDetail.EntityId     = ddlRegistration.SelectedValue.AsInteger();

                var transactionType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_EVENT_REGISTRATION);
                if (financialTransactionDetail.Transaction.TransactionTypeValueId != transactionType.Id)
                {
                    financialTransactionDetail.Transaction.TransactionTypeValueId = transactionType.Id;
                }

                rockContext.SaveChanges();
                BindHtmlGrid();
                LoadRegistrationDropDowns();
            }
        }
Пример #20
0
        /// <summary>
        /// Binds the attendees grid.
        /// </summary>
        private void BindGiversGrid()
        {
            // Get all the selected criteria values
            var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(drpSlidingDateRange.DelimitedValues);
            var start     = dateRange.Start;
            var end       = dateRange.End;

            var minAmount = nreAmount.LowerValue;
            var maxAmount = nreAmount.UpperValue;

            var currencyTypeIds = new List <int>();

            cblCurrencyTypes.SelectedValues.ForEach(i => currencyTypeIds.Add(i.AsInteger()));

            var sourceTypeIds = new List <int>();

            cblTransactionSource.SelectedValues.ForEach(i => sourceTypeIds.Add(i.AsInteger()));

            var accountIds = new List <int>();

            foreach (var cblAccounts in phAccounts.Controls.OfType <RockCheckBoxList>())
            {
                accountIds.AddRange(cblAccounts.SelectedValuesAsInt);
            }

            var dataViewId = dvpDataView.SelectedValueAsInt();

            GiversViewBy viewBy = GiversViewBy.Giver;

            if (!HideViewByOption)
            {
                viewBy = hfViewBy.Value.ConvertToEnumOrNull <GiversViewBy>() ?? GiversViewBy.Giver;
            }

            // Clear all the existing grid columns
            var selectField    = new SelectField();
            var oldSelectField = gGiversGifts.ColumnsOfType <SelectField>().FirstOrDefault();

            if (oldSelectField != null)
            {
                selectField.SelectedKeys.AddRange(oldSelectField.SelectedKeys);
            }

            gGiversGifts.Columns.Clear();

            // Add a column for selecting rows
            gGiversGifts.Columns.Add(selectField);

            // Add a column for the person's name
            gGiversGifts.Columns.Add(
                new RockBoundField
            {
                DataField      = "PersonName",
                HeaderText     = "Person",
                SortExpression = "LastName,NickName"
            });

            // add a column for email (but is only included on excel export)
            gGiversGifts.Columns.Add(
                new RockBoundField
            {
                DataField           = "Email",
                HeaderText          = "Email",
                SortExpression      = "Email",
                Visible             = false,
                ExcelExportBehavior = ExcelExportBehavior.AlwaysInclude
            });

            // Add a column for total amount
            gGiversGifts.Columns.Add(
                new CurrencyField
            {
                DataField      = "TotalAmount",
                HeaderText     = "Total",
                SortExpression = "TotalAmount"
            });


            // Add columns for the selected account totals
            if (accountIds.Any())
            {
                var accounts = new FinancialAccountService(_rockContext)
                               .Queryable().AsNoTracking()
                               .Where(a => accountIds.Contains(a.Id))
                               .ToList();

                foreach (int accountId in accountIds)
                {
                    var account = accounts.FirstOrDefault(a => a.Id == accountId);
                    if (account != null)
                    {
                        gGiversGifts.Columns.Add(
                            new CurrencyField
                        {
                            DataField      = account.Id.ToString(),
                            HeaderText     = account.Name,
                            SortExpression = account.Id.ToString()
                        });
                    }
                }
            }

            // Add a column for the number of gifts
            var numberGiftsField = new RockBoundField
            {
                DataField        = "NumberGifts",
                HeaderText       = "Number of Gifts",
                SortExpression   = "NumberGifts",
                DataFormatString = "{0:N0}",
            };

            numberGiftsField.ItemStyle.HorizontalAlign = HorizontalAlign.Right;
            gGiversGifts.Columns.Add(numberGiftsField);

            // Add a column to indicate if this is a first time giver
            gGiversGifts.Columns.Add(
                new BoolField
            {
                DataField      = "IsFirstEverGift",
                HeaderText     = "Is First Gift",
                SortExpression = "IsFirstEverGift"
            });

            // Add a column for the first gift date ( that matches criteria )
            gGiversGifts.Columns.Add(
                new DateField
            {
                DataField      = "FirstGift",
                HeaderText     = "First Gift",
                SortExpression = "FirstGift"
            });

            // Add a column for the first-ever gift date ( to any tax-deductible account )
            gGiversGifts.Columns.Add(
                new DateField
            {
                DataField      = "FirstEverGift",
                HeaderText     = "First Gift Ever",
                SortExpression = "FirstEverGift"
            });


            var transactionDetailService = new FinancialTransactionDetailService(_rockContext);
            var personService            = new PersonService(_rockContext);

            // If dataview was selected get the person id's returned by the dataview
            var dataViewPersonIds = new List <int>();

            if (dataViewId.HasValue)
            {
                var dataView = new DataViewService(_rockContext).Get(dataViewId.Value);
                if (dataView != null)
                {
                    var errorMessages = new List <string>();
                    ParameterExpression paramExpression = personService.ParameterExpression;
                    Expression          whereExpression = dataView.GetExpression(personService, paramExpression, out errorMessages);

                    SortProperty sortProperty        = null;
                    var          dataViewPersonIdQry = personService
                                                       .Queryable().AsNoTracking()
                                                       .Where(paramExpression, whereExpression, sortProperty)
                                                       .Select(p => p.Id);
                    dataViewPersonIds = dataViewPersonIdQry.ToList();
                }
            }

            // Check to see if grid should display only people who gave a certain number of times and if so
            // set the min value
            int minCount          = 0;
            var previousPersonIds = new List <int>();

            if (radByPattern.Checked)
            {
                minCount = tbPatternXTimes.Text.AsInteger();
                var missedStart = drpPatternDateRange.LowerValue;
                var missedEnd   = drpPatternDateRange.UpperValue;
                if (missedStart.HasValue && missedEnd.HasValue)
                {
                    // Get the givingids that gave any amount during the pattern's date range. These
                    // are needed so that we know who to exclude from the result set
                    var previousGivingIds = transactionDetailService
                                            .Queryable().AsNoTracking()
                                            .Where(d =>
                                                   d.Transaction.TransactionDateTime.HasValue &&
                                                   d.Transaction.TransactionDateTime.Value >= missedStart.Value &&
                                                   d.Transaction.TransactionDateTime.Value < missedEnd.Value &&
                                                   accountIds.Contains(d.AccountId) &&
                                                   d.Amount != 0.0M)
                                            .Select(d => d.Transaction.AuthorizedPersonAlias.Person.GivingId);

                    // Now get the person ids from the givingids
                    previousPersonIds = personService
                                        .Queryable().AsNoTracking()
                                        .Where(p => previousGivingIds.Contains(p.GivingId))
                                        .Select(p => p.Id)
                                        .ToList();
                }
            }

            // Call the stored procedure to get all the giving data that matches the selected criteria.
            // The stored procedure returns two tables. First is a list of all matching transaction summary
            // information and the second table is each giving leader's first-ever gift date to a tax-deductible account
            DataSet ds = FinancialTransactionDetailService.GetGivingAnalytics(start, end, minAmount, maxAmount,
                                                                              accountIds, currencyTypeIds, sourceTypeIds, dataViewId, viewBy);

            // Get the results table
            DataTable dtResults = ds.Tables[0];

            // Get the first-ever gift dates and load them into a dictionary for faster matching
            DataTable dtFirstEver   = ds.Tables[1];
            var       firstEverVals = new Dictionary <int, DateTime>();

            foreach (DataRow row in ds.Tables[1].Rows)
            {
                if (!DBNull.Value.Equals(row["FirstEverGift"]))
                {
                    firstEverVals.Add((int)row["PersonId"], (DateTime)row["FirstEverGift"]);
                }
            }

            // Add columns to the result set for the first-ever data
            dtResults.Columns.Add(new DataColumn("IsFirstEverGift", typeof(bool)));
            dtResults.Columns.Add(new DataColumn("FirstEverGift", typeof(DateTime)));

            foreach (DataRow row in dtResults.Rows)
            {
                bool rowValid = true;

                // Get the person id
                int personId = (int)row["Id"];

                if (radByPattern.Checked)
                {
                    // If pattern was specified check minimum gifts and other date range
                    int numberGifts = (int)row["NumberGifts"];
                    if (numberGifts < minCount)
                    {
                        rowValid = false;
                    }
                    else
                    {
                        // If this giving leader gave during the pattern date, remove the row since we
                        // only want those who did not
                        if (previousPersonIds.Contains(personId))
                        {
                            rowValid = false;
                        }
                    }
                }

                if (dataViewId.HasValue)
                {
                    // If a dataview filter was specified, and this row is not part of dataview,
                    // remove it
                    if (!dataViewPersonIds.Contains(personId))
                    {
                        rowValid = false;

                        // Remove person id from list so that list can be used later to optionally
                        // add rows for remaining people who were in the dataview, but not in the
                        // result set
                        dataViewPersonIds.Remove(personId);
                    }
                }

                if (rowValid)
                {
                    // Set the first ever information for each row
                    bool     isFirstEverGift = false;
                    DateTime firstGift       = (DateTime)row["FirstGift"];
                    if (firstEverVals.ContainsKey(personId))
                    {
                        DateTime firstEverGift = firstEverVals[personId];
                        isFirstEverGift = firstEverGift.Equals(firstGift);

                        row["FirstEverGift"] = firstEverGift;
                    }

                    // If only first time givers should be included, remove any that are not
                    if (radFirstTime.Checked && !isFirstEverGift)
                    {
                        rowValid = false;
                    }
                    else
                    {
                        row["IsFirstEverGift"] = isFirstEverGift;
                    }
                }

                if (!rowValid)
                {
                    row.Delete();
                }
            }

            // if dataview was selected and it includes people not in the result set,
            if (dataViewId.HasValue && rblDataViewAction.SelectedValue == "All" && dataViewPersonIds.Any())
            {
                // Query for the names of each of these people
                foreach (var person in personService
                         .Queryable().AsNoTracking()
                         .Select(p => new {
                    p.Id,
                    p.Guid,
                    p.NickName,
                    p.LastName,
                    p.Email
                }))
                {
                    // Check for a first ever gift date
                    var firstEverGiftDate = firstEverVals
                                            .Where(f => f.Key == person.Id)
                                            .Select(f => f.Value)
                                            .FirstOrDefault();

                    DataRow row = dtResults.NewRow();
                    row["Id"]              = person.Id;
                    row["Guid"]            = person.Guid;
                    row["NickName"]        = person.NickName;
                    row["LastName"]        = person.LastName;
                    row["PersonName"]      = person.NickName + " " + person.LastName;
                    row["Email"]           = person.Email;
                    row["IsFirstEverGift"] = false;
                    row["FirstEverGift"]   = firstEverGiftDate;
                    dtResults.Rows.Add(row);
                }
            }

            // Update the changes (deletes) in the datatable
            dtResults.AcceptChanges();

            // Calculate Total
            if (viewBy == GiversViewBy.Giver)
            {
                pnlTotal.Visible = true;
                object amountTotalObj = dtResults.Compute("Sum(TotalAmount)", null);
                if (amountTotalObj != null)
                {
                    decimal amountTotal = amountTotalObj.ToString().AsDecimal();
                    lTotal.Text = amountTotal.FormatAsCurrency();
                }
                else
                {
                    lTotal.Text = string.Empty;
                }
            }
            else
            {
                pnlTotal.Visible = false;
            }

            // Sort the results
            System.Data.DataView dv = dtResults.DefaultView;
            if (gGiversGifts.SortProperty != null)
            {
                try
                {
                    var sortProperties = new List <string>();
                    foreach (string prop in gGiversGifts.SortProperty.Property.SplitDelimitedValues(false))
                    {
                        sortProperties.Add(string.Format("[{0}] {1}", prop, gGiversGifts.SortProperty.DirectionString));
                    }
                    dv.Sort = sortProperties.AsDelimited(", ");
                }
                catch
                {
                    dv.Sort = "[LastName] ASC, [NickName] ASC";
                }
            }
            else
            {
                dv.Sort = "[LastName] ASC, [NickName] ASC";
            }

            gGiversGifts.DataSource = dv;
            gGiversGifts.DataBind();
        }
Пример #21
0
        private void BuildDynamicControls()
        {
            // Get all the accounts grouped by campus
            if (_campusAccounts == null)
            {
                using (var rockContext = new RockContext())
                {
                    _campusAccounts = new Dictionary <int, Dictionary <int, string> >();

                    Guid contributionGuid       = Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid();
                    var  contributionAccountIds = new FinancialTransactionDetailService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(d =>
                                                         d.Transaction != null &&
                                                         d.Transaction.TransactionTypeValue != null &&
                                                         d.Transaction.TransactionTypeValue.Guid.Equals(contributionGuid))
                                                  .Select(d => d.AccountId)
                                                  .Distinct()
                                                  .ToList();

                    foreach (var campusAccounts in new FinancialAccountService(rockContext)
                             .Queryable().AsNoTracking()
                             .Where(a =>
                                    a.IsActive &&
                                    contributionAccountIds.Contains(a.Id))
                             .GroupBy(a => a.CampusId ?? 0)
                             .Select(c => new
                    {
                        CampusId = c.Key,
                        Accounts = c.OrderBy(a => a.Name).Select(a => new { a.Id, a.Name }).ToList()
                    }))
                    {
                        _campusAccounts.Add(campusAccounts.CampusId, new Dictionary <int, string>());
                        foreach (var account in campusAccounts.Accounts)
                        {
                            _campusAccounts[campusAccounts.CampusId].Add(account.Id, account.Name);
                        }
                    }
                }
            }

            phAccounts.Controls.Clear();

            foreach (var campusId in _campusAccounts)
            {
                var cbList = new RockCheckBoxList();
                cbList.ID = "cblAccounts" + campusId.Key.ToString();

                if (campusId.Key > 0)
                {
                    var campus = CampusCache.Read(campusId.Key);
                    cbList.Label = campus != null ? campus.Name + " Accounts" : "Campus " + campusId.Key.ToString();
                }
                else
                {
                    cbList.Label = "Accounts";
                }

                cbList.RepeatDirection = RepeatDirection.Vertical;
                cbList.DataValueField  = "Key";
                cbList.DataTextField   = "Value";
                cbList.DataSource      = campusId.Value;
                cbList.DataBind();

                phAccounts.Controls.Add(cbList);
            }
        }
Пример #22
0
        /// <summary>
        /// Shows the financial batch summary.
        /// </summary>
        /// <param name="batch">The financial batch.</param>
        private void ShowReadonlyDetails(FinancialBatch batch)
        {
            SetEditMode(false);

            if (batch != null)
            {
                hfBatchId.SetValue(batch.Id);

                SetHeadingInfo(batch, batch.Name);

                string campusName = string.Empty;
                if (batch.CampusId.HasValue)
                {
                    var campus = CampusCache.Read(batch.CampusId.Value);
                    if (campus != null)
                    {
                        campusName = campus.ToString();
                    }
                }

                var rockContext = new RockContext();
                var financialTransactionService = new FinancialTransactionService(rockContext);
                var batchTransactions           = financialTransactionService.Queryable().Where(a => a.BatchId.HasValue && a.BatchId.Value == batch.Id);

                var     financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);
                var     qryTransactionDetails             = financialTransactionDetailService.Queryable().Where(a => a.Transaction.BatchId == batch.Id);
                decimal txnTotal = qryTransactionDetails.Select(a => (decimal?)a.Amount).Sum() ?? 0;

                decimal variance     = txnTotal - batch.ControlAmount;
                string  amountFormat = string.Format(
                    "{0} / {1} / " + (variance == 0.0M ? "{2}" : "<span class='label label-danger'>{2}</span>"),
                    txnTotal.FormatAsCurrency(),
                    batch.ControlAmount.FormatAsCurrency(),
                    variance.FormatAsCurrency());

                lDetails.Text = new DescriptionList()
                                .Add("Date Range", new DateRange(batch.BatchStartDateTime, batch.BatchEndDateTime).ToString("g"))
                                .Add("Transaction / Control / Variance", amountFormat)
                                .Add("Accounting Code", batch.AccountingSystemCode)
                                .Add("Notes", batch.Note)
                                .Html;

                batch.LoadAttributes();
                var attributes = batch.Attributes.Select(a => a.Value).OrderBy(a => a.Order).ThenBy(a => a.Name).ToList();

                var attributeCategories = Helper.GetAttributeCategories(attributes);

                Rock.Attribute.Helper.AddDisplayControls(batch, attributeCategories, phReadonlyAttributes, null, false);

                // Account Summary
                gAccounts.DataSource = qryTransactionDetails
                                       .GroupBy(d => new
                {
                    AccountId   = d.AccountId,
                    AccountName = d.Account.Name
                })
                                       .Select(s => new
                {
                    Id     = s.Key.AccountId,
                    Name   = s.Key.AccountName,
                    Amount = s.Sum(a => (decimal?)a.Amount) ?? 0.0M
                })
                                       .OrderBy(s => s.Name)
                                       .ToList();

                gAccounts.DataBind();

                // Currency Summary
                gCurrencyTypes.DataSource = batchTransactions
                                            .GroupBy(c => new
                {
                    CurrencyTypeValueId = c.FinancialPaymentDetailId.HasValue ? c.FinancialPaymentDetail.CurrencyTypeValueId : 0,
                })
                                            .Select(s => new
                {
                    CurrencyTypeValueId = s.Key.CurrencyTypeValueId,
                    Amount = s.Sum(a => (decimal?)a.TransactionDetails.Sum(t => t.Amount)) ?? 0.0M
                })
                                            .ToList()
                                            .Select(s => new
                {
                    Id     = s.CurrencyTypeValueId,
                    Name   = DefinedValueCache.GetName(s.CurrencyTypeValueId),
                    Amount = s.Amount
                }).OrderBy(a => a.Name).ToList();

                gCurrencyTypes.DataBind();
            }
        }
Пример #23
0
        /// <summary>
        /// Shows the view.
        /// </summary>
        /// <param name="groupId">The group identifier.</param>
        protected void ShowView(int groupId)
        {
            pnlView.Visible = true;
            hfGroupId.Value = groupId.ToString();
            var rockContext = new RockContext();

            var group = new GroupService(rockContext).Get(groupId);

            if (group == null)
            {
                pnlView.Visible = false;
                return;
            }

            group.LoadAttributes(rockContext);
            var opportunityType = DefinedValueCache.Get(group.GetAttributeValue("OpportunityType").AsGuid());

            if (this.GetAttributeValue("SetPageTitletoOpportunityTitle").AsBoolean())
            {
                RockPage.Title        = group.GetAttributeValue("OpportunityTitle");
                RockPage.BrowserTitle = group.GetAttributeValue("OpportunityTitle");
                RockPage.Header.Title = group.GetAttributeValue("OpportunityTitle");
            }

            var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions {
                GetLegacyGlobalMergeFields = false
            });

            mergeFields.Add("Block", this.BlockCache);
            mergeFields.Add("Group", group);

            // Left Sidebar
            var photoGuid = group.GetAttributeValue("OpportunityPhoto").AsGuidOrNull();

            imgOpportunityPhoto.Visible  = photoGuid.HasValue;
            imgOpportunityPhoto.ImageUrl = string.Format("~/GetImage.ashx?Guid={0}", photoGuid);

            var groupMembers = group.Members.ToList();

            foreach (var gm in groupMembers)
            {
                gm.LoadAttributes(rockContext);
            }

            // only show the 'Donate to a Participant' button if there are participants that are taking contribution requests
            btnDonateToParticipant.Visible = groupMembers.Where(a => !a.GetAttributeValue("DisablePublicContributionRequests").AsBoolean()).Any();
            if (!string.IsNullOrWhiteSpace(opportunityType.GetAttributeValue("core_DonateButtonText")))
            {
                btnDonateToParticipant.Text = opportunityType.GetAttributeValue("core_DonateButtonText");
            }

            RegistrationInstance registrationInstance = null;
            var registrationInstanceId = group.GetAttributeValue("RegistrationInstance").AsIntegerOrNull();

            if (registrationInstanceId.HasValue)
            {
                registrationInstance = new RegistrationInstanceService(rockContext).Get(registrationInstanceId.Value);
            }

            mergeFields.Add("RegistrationPage", LinkedPageRoute("RegistrationPage"));

            if (registrationInstance != null)
            {
                mergeFields.Add("RegistrationInstance", registrationInstance);
                mergeFields.Add("RegistrationInstanceLinkages", registrationInstance.Linkages);

                // populate merge fields for Registration Counts
                var maxRegistrantCount       = 0;
                var currentRegistrationCount = 0;

                if (registrationInstance.MaxAttendees != 0)
                {
                    maxRegistrantCount = registrationInstance.MaxAttendees;
                }

                currentRegistrationCount = new RegistrationRegistrantService(rockContext).Queryable().AsNoTracking()
                                           .Where(r =>
                                                  r.Registration.RegistrationInstanceId == registrationInstance.Id &&
                                                  r.OnWaitList == false)
                                           .Count();

                mergeFields.Add("CurrentRegistrationCount", currentRegistrationCount);
                if (maxRegistrantCount != 0)
                {
                    mergeFields.Add("MaxRegistrantCount", maxRegistrantCount);
                    mergeFields.Add("RegistrationSpotsAvailable", maxRegistrantCount - currentRegistrationCount);
                }
            }

            string sidebarLavaTemplate = this.GetAttributeValue("SidebarLavaTemplate");

            lSidebarHtml.Text = sidebarLavaTemplate.ResolveMergeFields(mergeFields);

            SetActiveTab("Details");

            // Top Main
            string summaryLavaTemplate = this.GetAttributeValue("SummaryLavaTemplate");

            lMainTopContentHtml.Text = summaryLavaTemplate.ResolveMergeFields(mergeFields);

            // only show the leader toolbox link of the currentperson has a leader role in the group
            btnLeaderToolbox.Visible = group.Members.Any(a => a.PersonId == this.CurrentPersonId && a.GroupRole.IsLeader);

            //// Participant Actions
            // only show if the current person is a group member
            var groupMember = group.Members.FirstOrDefault(a => a.PersonId == this.CurrentPersonId);

            if (groupMember != null)
            {
                hfGroupMemberId.Value         = groupMember.Id.ToString();
                pnlParticipantActions.Visible = true;
            }
            else
            {
                hfGroupMemberId.Value         = null;
                pnlParticipantActions.Visible = false;
            }

            mergeFields.Add("GroupMember", groupMember);

            // Progress
            if (groupMember != null && pnlParticipantActions.Visible)
            {
                var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();

                var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                        .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                               d.EntityId == groupMember.Id)
                                        .Sum(a => (decimal?)a.Amount) ?? 0.00M;

                var individualFundraisingGoal = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                if (!individualFundraisingGoal.HasValue)
                {
                    individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                }

                var amountLeft = individualFundraisingGoal - contributionTotal;
                var percentMet = individualFundraisingGoal > 0 ? contributionTotal * 100 / individualFundraisingGoal : 100;

                mergeFields.Add("AmountLeft", amountLeft);
                mergeFields.Add("PercentMet", percentMet);

                var queryParams = new Dictionary <string, string>();
                queryParams.Add("GroupId", hfGroupId.Value);
                queryParams.Add("GroupMemberId", hfGroupMemberId.Value);
                mergeFields.Add("MakeDonationUrl", LinkedPageUrl("DonationPage", queryParams));
                mergeFields.Add("ParticipantPageUrl", LinkedPageUrl("ParticipantPage", queryParams));

                string makeDonationButtonText = null;
                if (groupMember.PersonId == this.CurrentPersonId)
                {
                    makeDonationButtonText = "Make Payment";
                }
                else
                {
                    makeDonationButtonText = string.Format("Contribute to {0} {1}", RockFilters.Possessive(groupMember.Person.NickName), opportunityType);
                }

                mergeFields.Add("MakeDonationButtonText", makeDonationButtonText);

                var participantLavaTemplate = this.GetAttributeValue("ParticipantLavaTemplate");
                lParticipantActionsHtml.Text = participantLavaTemplate.ResolveMergeFields(mergeFields);
            }

            // Tab:Details
            lDetailsHtml.Text  = group.GetAttributeValue("OpportunityDetails");
            btnDetailsTab.Text = string.Format("{0} Details", opportunityType);

            // Tab:Updates
            liUpdatesTab.Visible = false;
            var updatesContentChannelGuid = group.GetAttributeValue("UpdateContentChannel").AsGuidOrNull();

            if (updatesContentChannelGuid.HasValue)
            {
                var contentChannel = new ContentChannelService(rockContext).Get(updatesContentChannelGuid.Value);
                if (contentChannel != null)
                {
                    liUpdatesTab.Visible = true;
                    string updatesLavaTemplate = this.GetAttributeValue("UpdatesLavaTemplate");
                    var    contentChannelItems = new ContentChannelItemService(rockContext).Queryable().Where(a => a.ContentChannelId == contentChannel.Id).AsNoTracking().ToList();

                    mergeFields.Add("ContentChannelItems", contentChannelItems);
                    lUpdatesContentItemsHtml.Text = updatesLavaTemplate.ResolveMergeFields(mergeFields);

                    btnUpdatesTab.Text = string.Format("{0} Updates ({1})", opportunityType, contentChannelItems.Count());
                }
            }

            // Tab:Comments
            var noteType = NoteTypeCache.Get(this.GetAttributeValue("NoteType").AsGuid());

            if (noteType != null)
            {
                notesCommentsTimeline.NoteOptions.SetNoteTypes(new List <NoteTypeCache> {
                    noteType
                });
            }

            notesCommentsTimeline.NoteOptions.EntityId = groupId;

            // show the Add button on comments for any logged in person
            notesCommentsTimeline.AddAllowed = true;

            var enableCommenting = group.GetAttributeValue("EnableCommenting").AsBoolean();

            btnCommentsTab.Text = string.Format("Comments ({0})", notesCommentsTimeline.NoteCount);

            if (CurrentPerson == null)
            {
                notesCommentsTimeline.Visible = enableCommenting && (notesCommentsTimeline.NoteCount > 0);
                lNoLoginNoCommentsYet.Visible = notesCommentsTimeline.NoteCount == 0;
                liCommentsTab.Visible         = enableCommenting;
                btnLoginToComment.Visible     = enableCommenting;
            }
            else
            {
                lNoLoginNoCommentsYet.Visible = false;
                notesCommentsTimeline.Visible = enableCommenting;
                liCommentsTab.Visible         = enableCommenting;
                btnLoginToComment.Visible     = false;
            }

            // if btnDetailsTab is the only visible tab, hide the tab since there is nothing else to tab to
            if (!liCommentsTab.Visible && !liUpdatesTab.Visible)
            {
                tlTabList.Visible = false;
            }
        }
Пример #24
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);
        }
        private void DisplayResults()
        {
            RockContext rockContext = new RockContext();

            var statementYear = RockDateTime.Now.Year;

            if (Request["StatementYear"] != null)
            {
                Int32.TryParse(Request["StatementYear"].ToString(), out statementYear);
            }

            FinancialTransactionDetailService financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);

            Person targetPerson = CurrentPerson;

            List <Guid> excludedCurrencyTypes = new List <Guid>();

            if (!string.IsNullOrWhiteSpace(GetAttributeValue("ExcludedCurrencyTypes")))
            {
                excludedCurrencyTypes = GetAttributeValue("ExcludedCurrencyTypes").Split(',').Select(Guid.Parse).ToList();
            }

            if (GetAttributeValue("AllowPersonQuerystring").AsBoolean())
            {
                if (!string.IsNullOrWhiteSpace(Request["PersonGuid"]))
                {
                    Guid?personGuid = Request["PersonGuid"].AsGuidOrNull();

                    if (personGuid.HasValue)
                    {
                        var person = new PersonService(rockContext).Get(personGuid.Value);
                        if (person != null)
                        {
                            targetPerson = person;
                        }
                    }
                }
            }

            // fetch all the possible PersonAliasIds that have this GivingID to help optimize the SQL
            var personAliasIds = new PersonAliasService(rockContext).Queryable().Where(a => a.Person.GivingId == targetPerson.GivingId).Select(a => a.Id).ToList();

            // get the transactions for the person or all the members in the person's giving group (Family)
            var qry = financialTransactionDetailService.Queryable().AsNoTracking()
                      .Where(t => t.Transaction.AuthorizedPersonAliasId.HasValue && personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value));

            qry = qry.Where(t => t.Transaction.TransactionDateTime.Value.Year == statementYear);

            if (string.IsNullOrWhiteSpace(GetAttributeValue("Accounts")))
            {
                qry = qry.Where(t => t.Account.IsTaxDeductible);
            }
            else
            {
                var accountGuids = GetAttributeValue("Accounts").Split(',').Select(Guid.Parse).ToList();
                qry = qry.Where(t => accountGuids.Contains(t.Account.Guid));
            }

            if (excludedCurrencyTypes.Count > 0)
            {
                qry = qry.Where(t => !excludedCurrencyTypes.Contains(t.Transaction.FinancialPaymentDetail.CurrencyTypeValue.Guid));
            }

            qry = qry.OrderByDescending(t => t.Transaction.TransactionDateTime);

            var mergeFields = new Dictionary <string, object>();

            mergeFields.Add("StatementStartDate", "1/1/" + statementYear.ToString());
            if (statementYear == RockDateTime.Now.Year)
            {
                mergeFields.Add("StatementEndDate", RockDateTime.Now);
            }
            else
            {
                mergeFields.Add("StatementEndDate", "12/31/" + statementYear.ToString());
            }

            var familyGroupTypeId = GroupTypeCache.Read(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY).Id;
            var groupMemberQry    = new GroupMemberService(rockContext).Queryable().Where(m => m.Group.GroupTypeId == familyGroupTypeId);

            // get giving group members in order by family role (adult -> child) and then gender (male -> female)
            var givingGroup = new PersonService(rockContext).Queryable().AsNoTracking()
                              .Where(p => p.GivingId == targetPerson.GivingId)
                              .GroupJoin(
                groupMemberQry,
                p => p.Id,
                m => m.PersonId,
                (p, m) => new { p, m })
                              .SelectMany(x => x.m.DefaultIfEmpty(), (y, z) => new { Person = y.p, GroupMember = z })
                              .Select(p => new { FirstName = p.Person.NickName, LastName = p.Person.LastName, FamilyRoleOrder = p.GroupMember.GroupRole.Order, Gender = p.Person.Gender, PersonId = p.Person.Id })
                              .DistinctBy(p => p.PersonId)
                              .OrderBy(p => p.FamilyRoleOrder).ThenBy(p => p.Gender)
                              .ToList();

            string salutation = string.Empty;

            if (givingGroup.GroupBy(g => g.LastName).Count() == 1)
            {
                salutation = string.Join(", ", givingGroup.Select(g => g.FirstName)) + " " + givingGroup.FirstOrDefault().LastName;
                if (salutation.Contains(","))
                {
                    salutation = salutation.ReplaceLastOccurrence(",", " &");
                }
            }
            else
            {
                salutation = string.Join(", ", givingGroup.Select(g => g.FirstName + " " + g.LastName));
                if (salutation.Contains(","))
                {
                    salutation = salutation.ReplaceLastOccurrence(",", " &");
                }
            }
            mergeFields.Add("Salutation", salutation);

            var homeAddress = targetPerson.GetHomeLocation();

            if (homeAddress != null)
            {
                mergeFields.Add("StreetAddress1", homeAddress.Street1);
                mergeFields.Add("StreetAddress2", homeAddress.Street2);
                mergeFields.Add("City", homeAddress.City);
                mergeFields.Add("State", homeAddress.State);
                mergeFields.Add("PostalCode", homeAddress.PostalCode);
                mergeFields.Add("Country", homeAddress.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);
            }

            mergeFields.Add("TransactionDetails", qry.ToList());

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

            // pledge information
            var pledges = new FinancialPledgeService(rockContext).Queryable().AsNoTracking()
                          .Where(p => p.PersonAliasId.HasValue && personAliasIds.Contains(p.PersonAliasId.Value))
                          .GroupBy(p => p.Account)
                          .Select(g => new PledgeSummary
            {
                AccountId       = g.Key.Id,
                AccountName     = g.Key.Name,
                AmountPledged   = g.Sum(p => p.TotalAmount),
                PledgeStartDate = g.Min(p => p.StartDate),
                PledgeEndDate   = g.Max(p => p.EndDate)
            })
                          .ToList();

            // add detailed pledge information
            foreach (var pledge in pledges)
            {
                var adjustedPedgeEndDate = pledge.PledgeEndDate.Value.Date.AddDays(1);
                pledge.AmountGiven = new FinancialTransactionDetailService(rockContext).Queryable()
                                     .Where(t =>
                                            t.AccountId == pledge.AccountId &&
                                            t.Transaction.AuthorizedPersonAliasId.HasValue && personAliasIds.Contains(t.Transaction.AuthorizedPersonAliasId.Value) &&
                                            t.Transaction.TransactionDateTime >= pledge.PledgeStartDate &&
                                            t.Transaction.TransactionDateTime < adjustedPedgeEndDate)
                                     .Sum(t => ( decimal? )t.Amount) ?? 0;

                pledge.AmountRemaining = (pledge.AmountGiven > pledge.AmountPledged) ? 0 : (pledge.AmountPledged - pledge.AmountGiven);

                if (pledge.AmountPledged > 0)
                {
                    var test = (double)pledge.AmountGiven / (double)pledge.AmountPledged;
                    pledge.PercentComplete = (int)((pledge.AmountGiven * 100) / pledge.AmountPledged);
                }
            }

            mergeFields.Add("Pledges", pledges);

            var template = GetAttributeValue("LavaTemplate");

            lResults.Text = template.ResolveMergeFields(mergeFields);

            // show debug info
            if (GetAttributeValue("EnableDebug").AsBoolean() && IsUserAuthorized(Authorization.EDIT))
            {
                lDebug.Visible = true;
                lDebug.Text    = mergeFields.lavaDebugInfo();
            }
        }
Пример #26
0
        protected void ShowDetail(bool setSelectControlValues = true)
        {
            var rockContext  = new RockContext();
            var isExported   = false;
            var debugEnabled = GetAttributeValue(AttributeKey.EnableDebug).AsBoolean();
            var exportMode   = GetAttributeValue(AttributeKey.ExportMode);

            _financialBatch = new FinancialBatchService(rockContext).Get(_batchId);
            DateTime?dateExported = null;

            _variance = 0;

            if (_financialBatch != null)
            {
                var     financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);
                var     qryTransactionDetails             = financialTransactionDetailService.Queryable().Where(a => a.Transaction.BatchId == _financialBatch.Id);
                decimal txnTotal = qryTransactionDetails.Select(a => ( decimal? )a.Amount).Sum() ?? 0;
                _variance = txnTotal - _financialBatch.ControlAmount;

                _financialBatch.LoadAttributes();

                dateExported = ( DateTime? )_financialBatch.GetAttributeValueAsType("rocks.kfs.Intacct.DateExported");

                if (dateExported != null && dateExported > DateTime.MinValue)
                {
                    isExported = true;
                }

                if (debugEnabled)
                {
                    var debugLava = Session["IntacctDebugLava"].ToStringSafe();
                    if (!string.IsNullOrWhiteSpace(debugLava))
                    {
                        lDebug.Visible = true;
                        lDebug.Text   += debugLava;
                        Session["IntacctDebugLava"] = string.Empty;
                    }
                }
            }

            if (ValidSettings() && !isExported)
            {
                btnExportToIntacct.Text    = GetAttributeValue(AttributeKey.ButtonText);
                btnExportToIntacct.Visible = true;
                if (exportMode == "JournalEntry")
                {
                    pnlOtherReceipt.Visible = false;
                }
                else
                {
                    SetupOtherReceipts(setSelectControlValues);
                }
                SetExportButtonVisibility();
            }
            else if (isExported)
            {
                litDateExported.Text       = string.Format("<div class=\"small\">Exported: {0}</div>", dateExported.ToRelativeDateString());
                litDateExported.Visible    = true;
                pnlExportedDetails.Visible = true;

                if (UserCanEdit)
                {
                    btnRemoveDate.Visible = true;
                }
            }
        }
        /// <summary>
        /// Binds the group members progress repeater.
        /// </summary>
        protected void BindGroupMembersProgressGrid(Group group, GroupMember gMember, RockContext rockContext)
        {
            IQueryable <GroupMember> groupMembersQuery;

            if (gMember != null)
            {
                groupMembersQuery = new GroupMemberService(rockContext).Queryable().Where(a => a.Id == gMember.Id);

                pnlHeader.Visible = false;
            }
            else
            {
                groupMembersQuery = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == group.Id);
            }

            group.LoadAttributes(rockContext);
            var defaultIndividualFundRaisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();

            groupMembersQuery = groupMembersQuery.Sort(new SortProperty {
                Property = "Person.LastName, Person.NickName"
            });

            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();

            var groupMemberList = groupMembersQuery.ToList().Select(a =>
            {
                var groupMember = a;
                groupMember.LoadAttributes(rockContext);

                var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                        .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                               d.EntityId == groupMember.Id)
                                        .Sum(d => (decimal?)d.Amount) ?? 0;

                var individualFundraisingGoal          = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                bool disablePublicContributionRequests = groupMember.GetAttributeValue("DisablePublicContributionRequests").AsBoolean();
                if (!individualFundraisingGoal.HasValue)
                {
                    individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
                }

                decimal percentageAchieved = 0;
                if (individualFundraisingGoal != null)
                {
                    percentageAchieved = individualFundraisingGoal == 0 ? 0 : contributionTotal / (0.01M * individualFundraisingGoal.Value);
                }

                var progressBarWidth = percentageAchieved;

                if (percentageAchieved >= 100)
                {
                    progressBarWidth = 100;
                }


                if (!individualFundraisingGoal.HasValue)
                {
                    individualFundraisingGoal = 0;
                }

                return(new
                {
                    FullName = groupMember.Person.FullName,
                    IndividualFundraisingGoal = (individualFundraisingGoal ?? 0.00M).ToString("0.##"),
                    ContributionTotal = contributionTotal.ToString("0.##"),
                    Percentage = percentageAchieved.ToString("0.##"),
                    CssClass = GetProgressCssClass(percentageAchieved),
                    ProgressBarWidth = progressBarWidth
                });
            }).ToList();

            this.GroupIndividualFundraisingGoal = groupMemberList.Sum(a => decimal.Parse(a.IndividualFundraisingGoal));
            this.GroupContributionTotal         = groupMemberList.Sum(a => decimal.Parse(a.ContributionTotal));
            this.PercentComplete  = decimal.Round(this.GroupContributionTotal == 0 ? 0 : this.GroupContributionTotal / (this.GroupIndividualFundraisingGoal * 0.01M), 2);
            this.ProgressCssClass = GetProgressCssClass(this.PercentComplete);

            rptFundingProgress.DataSource = groupMemberList;
            rptFundingProgress.DataBind();
        }
Пример #28
0
        /// <summary>
        /// Shows the view.
        /// </summary>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="groupMemberId">The group member identifier.</param>
        protected void ShowView(int groupId, int groupMemberId)
        {
            pnlView.Visible            = true;
            pnlMain.Visible            = true;
            pnlEditPreferences.Visible = false;
            hfGroupId.Value            = groupId.ToString();
            hfGroupMemberId.Value      = groupMemberId.ToString();
            var rockContext = new RockContext();

            var group = new GroupService(rockContext).Get(groupId);

            if (group == null)
            {
                pnlView.Visible = false;
                return;
            }

            var groupMember = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == groupId && a.Id == groupMemberId).FirstOrDefault();

            if (groupMember == null)
            {
                pnlView.Visible = false;
                return;
            }

            group.LoadAttributes(rockContext);

            // set page title to the trip name
            RockPage.Title        = group.GetAttributeValue("OpportunityTitle");
            RockPage.BrowserTitle = group.GetAttributeValue("OpportunityTitle");
            RockPage.Header.Title = group.GetAttributeValue("OpportunityTitle");

            var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new CommonMergeFieldsOptions {
                GetLegacyGlobalMergeFields = false
            });

            mergeFields.Add("Group", group);

            groupMember.LoadAttributes(rockContext);
            mergeFields.Add("GroupMember", groupMember);

            // Left Top Sidebar
            var photoGuid = group.GetAttributeValue("OpportunityPhoto");

            imgOpportunityPhoto.ImageUrl = string.Format("~/GetImage.ashx?Guid={0}", photoGuid);

            // Top Main
            string profileLavaTemplate = this.GetAttributeValue("ProfileLavaTemplate");

            if (groupMember.PersonId == this.CurrentPersonId)
            {
                // show a warning about missing Photo or Intro if the current person is viewing their own profile
                var warningItems = new List <string>();
                if (!groupMember.Person.PhotoId.HasValue)
                {
                    warningItems.Add("photo");
                }
                if (groupMember.GetAttributeValue("PersonalOpportunityIntroduction").IsNullOrWhiteSpace())
                {
                    warningItems.Add("personal opportunity introduction");
                }

                nbProfileWarning.Text    = "<stong>Tip!</strong> Edit your profile to add a " + warningItems.AsDelimited(", ", " and ") + ".";
                nbProfileWarning.Visible = warningItems.Any();
            }
            else
            {
                nbProfileWarning.Visible = false;
            }

            btnEditProfile.Visible = groupMember.PersonId == this.CurrentPersonId;

            lMainTopContentHtml.Text = profileLavaTemplate.ResolveMergeFields(mergeFields);

            bool disablePublicContributionRequests = groupMember.GetAttributeValue("DisablePublicContributionRequests").AsBoolean();

            // only show Contribution stuff if the current person is the participant and contribution requests haven't been disabled
            bool showContributions = !disablePublicContributionRequests && (groupMember.PersonId == this.CurrentPersonId);

            btnContributionsTab.Visible = showContributions;

            // Progress
            var entityTypeIdGroupMember = EntityTypeCache.GetId <Rock.Model.GroupMember>();

            var contributionTotal = new FinancialTransactionDetailService(rockContext).Queryable()
                                    .Where(d => d.EntityTypeId == entityTypeIdGroupMember &&
                                           d.EntityId == groupMemberId)
                                    .Sum(a => (decimal?)a.Amount) ?? 0.00M;

            var individualFundraisingGoal = groupMember.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();

            if (!individualFundraisingGoal.HasValue)
            {
                individualFundraisingGoal = group.GetAttributeValue("IndividualFundraisingGoal").AsDecimalOrNull();
            }

            var amountLeft = individualFundraisingGoal - contributionTotal;
            var percentMet = individualFundraisingGoal > 0 ? contributionTotal * 100 / individualFundraisingGoal : 100;

            mergeFields.Add("AmountLeft", amountLeft);
            mergeFields.Add("PercentMet", percentMet);

            var queryParams = new Dictionary <string, string>();

            queryParams.Add("GroupId", hfGroupId.Value);
            queryParams.Add("GroupMemberId", hfGroupMemberId.Value);
            mergeFields.Add("MakeDonationUrl", LinkedPageUrl("DonationPage", queryParams));

            var opportunityType = DefinedValueCache.Get(group.GetAttributeValue("OpportunityType").AsGuid());

            string makeDonationButtonText = null;

            if (groupMember.PersonId == this.CurrentPersonId)
            {
                makeDonationButtonText = "Make Payment";
            }
            else
            {
                makeDonationButtonText = string.Format("Contribute to {0} {1}", RockFilters.Possessive(groupMember.Person.NickName), opportunityType);
            }

            mergeFields.Add("MakeDonationButtonText", makeDonationButtonText);

            var progressLavaTemplate = this.GetAttributeValue("ProgressLavaTemplate");

            lProgressHtml.Text = progressLavaTemplate.ResolveMergeFields(mergeFields);

            // set text on the return button
            btnMainPage.Text = opportunityType.Value + " Page";

            // Tab:Updates
            btnUpdatesTab.Visible = false;
            bool showContentChannelUpdates = false;
            var  updatesContentChannelGuid = group.GetAttributeValue("UpdateContentChannel").AsGuidOrNull();

            if (updatesContentChannelGuid.HasValue)
            {
                var contentChannel = new ContentChannelService(rockContext).Get(updatesContentChannelGuid.Value);
                if (contentChannel != null)
                {
                    showContentChannelUpdates = true;

                    // only show the UpdatesTab if there is another Tab option
                    btnUpdatesTab.Visible = btnContributionsTab.Visible;

                    string updatesLavaTemplate = this.GetAttributeValue("UpdatesLavaTemplate");
                    var    contentChannelItems = new ContentChannelItemService(rockContext).Queryable().Where(a => a.ContentChannelId == contentChannel.Id).AsNoTracking().ToList();

                    mergeFields.Add("ContentChannelItems", contentChannelItems);
                    lUpdatesContentItemsHtml.Text = updatesLavaTemplate.ResolveMergeFields(mergeFields);
                    btnUpdatesTab.Text            = string.Format("{0} Updates ({1})", opportunityType, contentChannelItems.Count());
                }
            }

            if (showContentChannelUpdates)
            {
                SetActiveTab("Updates");
            }
            else if (showContributions)
            {
                SetActiveTab("Contributions");
            }
            else
            {
                SetActiveTab("");
            }

            // Tab: Contributions
            BindContributionsGrid();

            // Tab:Comments
            var noteType = NoteTypeCache.Get(this.GetAttributeValue("NoteType").AsGuid());

            if (noteType != null)
            {
                notesCommentsTimeline.NoteOptions.SetNoteTypes(new List <NoteTypeCache> {
                    noteType
                });
            }

            notesCommentsTimeline.NoteOptions.EntityId = groupMember.Id;

            // show the Add button on comments for any logged in person
            notesCommentsTimeline.AddAllowed = true;

            var enableCommenting = group.GetAttributeValue("EnableCommenting").AsBoolean();

            if (CurrentPerson == null)
            {
                notesCommentsTimeline.Visible = enableCommenting && (notesCommentsTimeline.NoteCount > 0);
                lNoLoginNoCommentsYet.Visible = notesCommentsTimeline.NoteCount == 0;
                pnlComments.Visible           = enableCommenting;
                btnLoginToComment.Visible     = enableCommenting;
            }
            else
            {
                lNoLoginNoCommentsYet.Visible = false;
                notesCommentsTimeline.Visible = enableCommenting;
                pnlComments.Visible           = enableCommenting;
                btnLoginToComment.Visible     = false;
            }

            // if btnContributionsTab is the only visible tab, hide the tab since there is nothing else to tab to
            if (!btnUpdatesTab.Visible && btnContributionsTab.Visible)
            {
                SetActiveTab("Contributions");
                btnContributionsTab.Visible = false;
            }
        }
Пример #29
0
        protected void ShowDetail()
        {
            var rockContext  = new RockContext();
            var isExported   = false;
            var debugEnabled = GetAttributeValue("EnableDebug").AsBoolean();

            _financialBatch = new FinancialBatchService(rockContext).Get(_batchId);
            DateTime?dateExported = null;

            decimal variance = 0;

            if (_financialBatch != null)
            {
                var     financialTransactionDetailService = new FinancialTransactionDetailService(rockContext);
                var     qryTransactionDetails             = financialTransactionDetailService.Queryable().Where(a => a.Transaction.BatchId == _financialBatch.Id);
                decimal txnTotal = qryTransactionDetails.Select(a => ( decimal? )a.Amount).Sum() ?? 0;
                variance = txnTotal - _financialBatch.ControlAmount;

                _financialBatch.LoadAttributes();

                dateExported = ( DateTime? )_financialBatch.AttributeValues["rocks.kfs.ShelbyFinancials.DateExported"].ValueAsType;

                if (dateExported != null && dateExported > DateTime.MinValue)
                {
                    isExported = true;
                }
            }

            if (!isExported)
            {
                btnExportToShelbyFinancials.Text    = GetAttributeValue("ButtonText");
                btnExportToShelbyFinancials.Visible = true;
                ddlJournalType.Visible     = true;
                tbAccountingPeriod.Visible = true;
                if (variance == 0)
                {
                    btnExportToShelbyFinancials.Enabled = true;
                }
                else
                {
                    btnExportToShelbyFinancials.Enabled = false;
                }
            }
            else
            {
                pnlExportedDetails.Visible = true;

                litDateExported.Text    = string.Format("<div class=\"small\">Exported: {0}</div>", dateExported.ToRelativeDateString());
                litDateExported.Visible = true;

                if (UserCanEdit)
                {
                    btnRemoveDate.Visible = true;
                }
            }

            if (debugEnabled)
            {
                var debugLava = Session["ShelbyFinancialsDebugLava"].ToStringSafe();
                if (!string.IsNullOrWhiteSpace(debugLava))
                {
                    lDebug.Visible = true;
                    lDebug.Text   += debugLava;
                    Session["ShelbyFinancialsDebugLava"] = string.Empty;
                }
            }
        }
        /// <summary>
        /// Creates the table controls.
        /// </summary>
        /// <param name="batchId">The batch identifier.</param>
        /// <param name="dataViewId">The data view identifier.</param>
        private void BindHtmlGrid(int?batchId, int?dataViewId)
        {
            _financialTransactionDetailList = null;
            RockContext rockContext = new RockContext();

            nbSaveSuccess.Visible = false;
            btnSave.Visible       = false;

            List <DataControlField> tableColumns = new List <DataControlField>();

            tableColumns.Add(new RockLiteralField {
                ID = "lPerson", HeaderText = "Person"
            });
            tableColumns.Add(new RockLiteralField {
                ID = "lAmount", HeaderText = "Amount"
            });
            tableColumns.Add(new RockLiteralField {
                ID = "lAccount", HeaderText = "Account"
            });
            tableColumns.Add(new RockLiteralField {
                ID = "lTransactionType", HeaderText = "Transaction Type"
            });

            string entityColumnHeading = this.GetAttributeValue("EntityColumnHeading");

            if (string.IsNullOrEmpty(entityColumnHeading))
            {
                if (_transactionEntityType != null)
                {
                    entityColumnHeading = _entityTypeQualifiedName;
                }
            }

            tableColumns.Add(new RockLiteralField {
                ID = "lEntityColumn", HeaderText = entityColumnHeading
            });

            var additionalColumns = this.GetAttributeValue(CustomGridColumnsConfig.AttributeKey).FromJsonOrNull <CustomGridColumnsConfig>();

            if (additionalColumns != null)
            {
                foreach (var columnConfig in additionalColumns.ColumnsConfig)
                {
                    int insertPosition;
                    if (columnConfig.PositionOffsetType == CustomGridColumnsConfig.ColumnConfig.OffsetType.LastColumn)
                    {
                        insertPosition = tableColumns.Count - columnConfig.PositionOffset;
                    }
                    else
                    {
                        insertPosition = columnConfig.PositionOffset;
                    }

                    var column = columnConfig.GetGridColumn();
                    tableColumns.Insert(insertPosition, column);
                    insertPosition++;
                }
            }

            StringBuilder headers = new StringBuilder();

            foreach (var tableColumn in tableColumns)
            {
                if (tableColumn.HeaderStyle.CssClass.IsNotNullOrWhiteSpace())
                {
                    headers.AppendFormat("<th class='{0}'>{1}</th>", tableColumn.HeaderStyle.CssClass, tableColumn.HeaderText);
                }
                else
                {
                    headers.AppendFormat("<th>{0}</th>", tableColumn.HeaderText);
                }
            }

            lHeaderHtml.Text = headers.ToString();

            int?transactionId = this.PageParameter("TransactionId").AsIntegerOrNull();

            if (batchId.HasValue || dataViewId.HasValue || transactionId.HasValue)
            {
                var financialTransactionDetailQuery = new FinancialTransactionDetailService(rockContext).Queryable()
                                                      .Include(a => a.Transaction)
                                                      .Include(a => a.Transaction.AuthorizedPersonAlias.Person);
                if (batchId.HasValue)
                {
                    financialTransactionDetailQuery = financialTransactionDetailQuery.Where(a => a.Transaction.BatchId == batchId.Value);
                }

                if (dataViewId.HasValue && dataViewId > 0)
                {
                    var           dataView = new DataViewService(rockContext).Get(dataViewId.Value);
                    List <string> errorMessages;
                    var           transactionDetailIdsQry = dataView.GetQuery(null, rockContext, null, out errorMessages).Select(a => a.Id);
                    financialTransactionDetailQuery = financialTransactionDetailQuery.Where(a => transactionDetailIdsQry.Contains(a.Id));
                }

                if (transactionId.HasValue)
                {
                    financialTransactionDetailQuery = financialTransactionDetailQuery.Where(a => transactionId == a.TransactionId);
                }

                int maxResults = this.GetAttributeValue("MaxNumberofResults").AsIntegerOrNull() ?? 1000;
                _financialTransactionDetailList = financialTransactionDetailQuery.OrderByDescending(a => a.Transaction.TransactionDateTime).Take(maxResults).ToList();
                phTableRows.Controls.Clear();
                btnSave.Visible = _financialTransactionDetailList.Any();
                string appRoot   = this.ResolveRockUrl("~/");
                string themeRoot = this.ResolveRockUrl("~~/");

                foreach (var financialTransactionDetail in _financialTransactionDetailList)
                {
                    var tr = new HtmlGenericContainer("tr");
                    foreach (var tableColumn in tableColumns)
                    {
                        var literalControl = new LiteralControl();
                        if (tableColumn is RockLiteralField)
                        {
                            tr.Controls.Add(literalControl);
                            var literalTableColumn = tableColumn as RockLiteralField;
                            if (literalTableColumn.ID == "lPerson")
                            {
                                literalControl.Text = string.Format("<td>{0}</td>", financialTransactionDetail.Transaction.AuthorizedPersonAlias);
                            }
                            else if (literalTableColumn.ID == "lAmount")
                            {
                                literalControl.Text = string.Format("<td>{0}</td>", financialTransactionDetail.Amount.FormatAsCurrency());
                            }
                            else if (literalTableColumn.ID == "lAccount")
                            {
                                literalControl.Text = string.Format("<td>{0}</td>", financialTransactionDetail.Account.ToString());
                            }
                            else if (literalTableColumn.ID == "lTransactionType")
                            {
                                literalControl.ID   = "lTransactionType_" + financialTransactionDetail.Id.ToString();
                                literalControl.Text = string.Format("<td>{0}</td>", financialTransactionDetail.Transaction.TransactionTypeValue);
                            }
                            else if (literalTableColumn.ID == "lEntityColumn")
                            {
                                var tdEntityControls = new HtmlGenericContainer("td")
                                {
                                    ID = "pnlEntityControls_" + financialTransactionDetail.Id.ToString()
                                };
                                tr.Controls.Add(tdEntityControls);

                                if (_transactionEntityType != null)
                                {
                                    if (_transactionEntityType.Id == EntityTypeCache.GetId <GroupMember>())
                                    {
                                        var ddlGroup = new RockDropDownList {
                                            ID = "ddlGroup_" + financialTransactionDetail.Id.ToString(), EnhanceForLongLists = true
                                        };
                                        ddlGroup.Label                 = "Group";
                                        ddlGroup.AutoPostBack          = true;
                                        ddlGroup.SelectedIndexChanged += ddlGroup_SelectedIndexChanged;
                                        tdEntityControls.Controls.Add(ddlGroup);
                                        var ddlGroupMember = new RockDropDownList {
                                            ID = "ddlGroupMember_" + financialTransactionDetail.Id.ToString(), Visible = false, EnhanceForLongLists = true
                                        };
                                        ddlGroupMember.Label = "Group Member";
                                        tdEntityControls.Controls.Add(ddlGroupMember);
                                    }
                                    else if (_transactionEntityType.Id == EntityTypeCache.GetId <Group>())
                                    {
                                        var ddlGroup = new RockDropDownList {
                                            ID = "ddlGroup_" + financialTransactionDetail.Id.ToString(), EnhanceForLongLists = true
                                        };
                                        ddlGroup.AutoPostBack = false;
                                        tdEntityControls.Controls.Add(ddlGroup);
                                    }
                                    else if (_transactionEntityType.Id == EntityTypeCache.GetId <DefinedValue>())
                                    {
                                        var ddlDefinedValue = new DefinedValuePicker {
                                            ID = "ddlDefinedValue_" + financialTransactionDetail.Id.ToString(), EnhanceForLongLists = true
                                        };
                                        tdEntityControls.Controls.Add(ddlDefinedValue);
                                    }
                                    else if (_transactionEntityType.SingleValueFieldType != null)
                                    {
                                        var entityPicker = _transactionEntityType.SingleValueFieldType.Field.EditControl(new Dictionary <string, Rock.Field.ConfigurationValue>(), "entityPicker_" + financialTransactionDetail.Id.ToString());
                                        tdEntityControls.Controls.Add(entityPicker);
                                    }
                                }
                            }
                        }
                        else if (tableColumn is LavaField)
                        {
                            tr.Controls.Add(literalControl);
                            var lavaField = tableColumn as LavaField;

                            Dictionary <string, object> mergeValues = new Dictionary <string, object>();
                            mergeValues.Add("Row", financialTransactionDetail);

                            string lavaOutput = lavaField.LavaTemplate.ResolveMergeFields(mergeValues);

                            // Resolve any dynamic url references
                            lavaOutput = lavaOutput.Replace("~~/", themeRoot).Replace("~/", appRoot);

                            if (lavaField.ItemStyle.CssClass.IsNotNullOrWhiteSpace())
                            {
                                literalControl.Text = string.Format("<td class='{0}'>{1}</td>", lavaField.ItemStyle.CssClass, lavaOutput);
                            }
                            else
                            {
                                literalControl.Text = string.Format("<td>{0}</td>", lavaOutput);
                            }
                        }
                    }

                    phTableRows.Controls.Add(tr);

                    pnlTransactions.Visible = true;
                }
            }
            else
            {
                pnlTransactions.Visible = false;
            }
        }