/// <summary>
 /// Refreshes the list. Public method...can be called from other blocks.
 /// </summary>
 public void RefreshList()
 {
     var contextEntity = this.ContextEntity();
     if ( contextEntity != null )
     {
         if ( contextEntity is FinancialBatch )
         {
             var batchId = PageParameter( "financialBatchId" );
             var batch = new FinancialBatchService( new RockContext() ).Get( int.Parse( batchId ) );
             _batch = batch;
             BindGrid();
         }
     }
 }
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="itemKey">The item key.</param>
        /// <param name="itemKeyValue">The item key value.</param>
        public void ShowDetail( string itemKey, int itemKeyValue )
        {
            if ( !itemKey.Equals( "financialBatchId" ) )
            {
                return;
            }

            FinancialBatch financialBatch = null;
            if ( !itemKeyValue.Equals( 0 ) )
            {
                financialBatch = new FinancialBatchService( new RockContext() ).Get( itemKeyValue );
            }
            else
            {
                financialBatch = new FinancialBatch { Id = 0 };
            }

            bool readOnly = false;
            if ( !IsUserAuthorized( Authorization.EDIT ) )
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( FinancialBatch.FriendlyTypeName );
            }

            if ( !readOnly )
            {
                lbEdit.Visible = true;
                if ( financialBatch.Id > 0 )
                {
                    ShowSummary( financialBatch );
                }
                else
                {
                    ShowEdit( financialBatch );
                }
            }
            else
            {
                lbEdit.Visible = false;
                ShowSummary( financialBatch );
            }

            lbSave.Visible = !readOnly;
        }
Пример #3
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void btnSave_Click( object sender, RoutedEventArgs e )
        {
            try
            {
                RockConfig rockConfig = RockConfig.Load();
                RockRestClient client = new RockRestClient( rockConfig.RockBaseUrl );
                client.Login( rockConfig.Username, rockConfig.Password );

                FinancialBatch financialBatch = null;
                if ( SelectedFinancialBatch == null || SelectedFinancialBatch.Id == 0)
                {
                    financialBatch = new FinancialBatch { Id = 0, Guid = Guid.NewGuid(), Status = BatchStatus.Pending, CreatedByPersonAliasId = LoggedInPerson.PrimaryAlias.Id };
                }
                else
                {
                    financialBatch = client.GetData<FinancialBatch>( string.Format( "api/FinancialBatches/{0}", SelectedFinancialBatch.Id ) );
                }

                txtBatchName.Text = txtBatchName.Text.Trim();

                financialBatch.Name = txtBatchName.Text;
                Campus selectedCampus = cbCampus.SelectedItem as Campus;
                if ( selectedCampus.Id > 0 )
                {
                    financialBatch.CampusId = selectedCampus.Id;
                }
                else
                {
                    financialBatch.CampusId = null;
                }

                financialBatch.BatchStartDateTime = dpBatchDate.SelectedDate;

                if ( !string.IsNullOrWhiteSpace( txtControlAmount.Text ) )
                {
                    financialBatch.ControlAmount = decimal.Parse( txtControlAmount.Text.Replace( "$", string.Empty ) );
                }
                else
                {
                    financialBatch.ControlAmount = 0.00M;
                }

                if ( financialBatch.Id == 0 )
                {
                    client.PostData<FinancialBatch>( "api/FinancialBatches/", financialBatch );
                }
                else
                {
                    client.PutData<FinancialBatch>( "api/FinancialBatches/", financialBatch );
                }

                if ( SelectedFinancialBatch == null || SelectedFinancialBatch.Id == 0 )
                {
                    // refetch the batch to get the Id if it was just Inserted
                    financialBatch = client.GetDataByGuid<FinancialBatch>( "api/FinancialBatches", financialBatch.Guid );

                    SelectedFinancialBatch = financialBatch;
                }

                LoadFinancialBatchesGrid();

                ShowBatch( false );
            }
            catch ( Exception ex )
            {
                MessageBox.Show( ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation );
            }
        }
Пример #4
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapBatch(CSVInstance csvData)
        {
            var newBatches        = new List <FinancialBatch>();
            var earliestBatchDate = ImportDateTime;

            var completed = 0;

            ReportProgress(0, $"Verifying batch import ({ImportedBatches.Count:N0} already exist).");
            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                var batchIdKey = row[BatchID];
                var batchId    = batchIdKey.AsType <int?>();
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch
                    {
                        CreatedByPersonAliasId = ImportPersonAliasId,
                        ForeignKey             = batchId.ToString(),
                        ForeignId            = batchId,
                        Note                 = string.Empty,
                        Status               = BatchStatus.Closed,
                        AccountingSystemCode = string.Empty
                    };

                    var name = row[BatchName] as string;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    var batchDate = ParseDateOrDefault(row[BatchDate], null);
                    if (batchDate.HasValue)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;

                        if (earliestBatchDate > batchDate)
                        {
                            earliestBatchDate = (DateTime)batchDate;
                        }
                    }

                    var amountKey = row[BatchAmount];
                    var amount    = amountKey.AsType <decimal?>();
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, $"{completed:N0} batches imported.");
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);

                        foreach (var b in newBatches)
                        {
                            if (!ImportedBatches.ContainsKey((int)b.ForeignId))
                            {
                                ImportedBatches.Add((int)b.ForeignId, b.Id);
                            }
                            else
                            {
                                LogException("Duplicate Batch", string.Format("Batch #{0} is a duplicate and will be skipped. Please check the source data.", b.ForeignId));
                            }
                        }

                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch
                {
                    CreatedDateTime        = ImportDateTime,
                    CreatedByPersonAliasId = ImportPersonAliasId,
                    Status             = BatchStatus.Closed,
                    BatchStartDateTime = earliestBatchDate,
                    Name          = $"Default Batch {ImportDateTime}",
                    ControlAmount = 0.0m,
                    ForeignKey    = "0",
                    ForeignId     = 0
                };

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, $"Finished batch import: {completed:N0} batches imported.");
            return(completed);
        }
Пример #5
0
        /// <summary>
        /// Creates the giving records for the given parameters.
        /// </summary>
        /// <param name="personGuid">The person unique identifier.</param>
        /// <param name="startingDate">The starting date.</param>
        /// <param name="endDate">The end date.</param>
        /// <param name="frequency">The frequency (onetime, weekly, monthly).</param>
        /// <param name="percentGive">The percent give.</param>
        /// <param name="growRatePercent">The grow rate percent.</param>
        /// <param name="growFrequencyWeeks">The grow frequency weeks.</param>
        /// <param name="specialGiftPercent">The special gift percent.</param>
        /// <param name="accountAmountDict">The account amount dictionary.</param>
        /// <param name="circularImageList">A circular linked list of imageUrls to use for the fake contribution checks.</param>
        /// <param name="rockContexe">A rock context.</param>
        private void CreateGiving( Guid personGuid, DateTime startingDate, DateTime endDate, Frequency frequency, int percentGive, int growRatePercent, int growFrequencyWeeks, int specialGiftPercent, Dictionary<int, decimal> accountAmountDict, LinkedList<string> circularImageList, RockContext rockContext )
        {
            int weekNumber = 0;
            DateTime monthly = startingDate;

            var currencyTypeCheck = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid() );

            var imageUrlNode = circularImageList.First ?? null;
            // foreach weekend or monthly between the starting and ending date...
            for ( DateTime date = startingDate; date <= endDate; date = frequency == Frequency.weekly ? date.AddDays( 7 ) : frequency == Frequency.monthly ? date.AddMonths( 1 ) : endDate.AddDays(1) )
            {
                weekNumber = (int)(date - startingDate).TotalDays / 7;

                // increase by growRatePercent every growFrequencyWeeks
                if ( growFrequencyWeeks != 0 && growRatePercent != 0 && weekNumber !=0 && weekNumber % growFrequencyWeeks == 0 )
                {
                    var copy = accountAmountDict.ToDictionary( entry => entry.Key, entry => entry.Value );
                    foreach ( var item in accountAmountDict )
                    {
                        decimal amount = Math.Round( ( item.Value * 0.01M ) + item.Value, 0 );
                        copy[item.Key] = amount;
                    }
                    accountAmountDict = copy;
                }

                // randomized skip/missed weeks
                int summerFactor = ( 7 <= date.Month && date.Month <= 9 ) ? summerPercentFactor : 0;
                if ( _random.Next( 0, 100 ) > percentGive - summerFactor )
                {
                    continue; // skip this week
                }

                FinancialBatch batch;
                if ( _contributionBatches.ContainsKey( date ) )
                {
                    batch = _contributionBatches[date];
                }
                else
                {
                    batch = new FinancialBatch {
                        Id = 0,
                        Guid = Guid.NewGuid(),
                        BatchStartDateTime = date,
                        BatchEndDateTime = date,
                        Status = BatchStatus.Closed,
                        ControlAmount = 0,
                        Name = string.Format( "SampleData{0}", date.ToJavascriptMilliseconds() ),
                        CreatedByPersonAliasId = CurrentPerson.PrimaryAliasId };
                    _contributionBatches.Add( date, batch );
                }

                // Set up the new transaction
                FinancialTransaction financialTransaction = new FinancialTransaction
                {
                    TransactionTypeValueId = _transactionTypeContributionId,
                    Guid = Guid.NewGuid(),
                    TransactionDateTime = date,
                    AuthorizedPersonAliasId = _peopleAliasDictionary[personGuid]
                };

                financialTransaction.FinancialPaymentDetail = new FinancialPaymentDetail();
                financialTransaction.FinancialPaymentDetail.CurrencyTypeValueId = currencyTypeCheck.Id;
                financialTransaction.FinancialPaymentDetail.Guid = Guid.NewGuid();

                // Add a transaction detail record for each account they're donating to
                foreach ( var item in accountAmountDict )
                {
                    FinancialTransactionDetail transactionDetail = new FinancialTransactionDetail {
                        AccountId = item.Key,
                        Amount = item.Value,
                        Guid = Guid.NewGuid()
                    };

                    financialTransaction.TransactionDetails.Add( transactionDetail );
                }

                // Add the image to the transaction (if any)
                if ( imageUrlNode != null )
                {
                    FinancialTransactionImage transactionImage = new FinancialTransactionImage
                    {
                        BinaryFile = SaveImage( imageUrlNode.Value, _checkImageBinaryFileType, _checkImageBinaryFileTypeSettings, rockContext ),
                        Guid = Guid.NewGuid(),
                    };
                    financialTransaction.Images.Add( transactionImage );
                    imageUrlNode = imageUrlNode.Next ?? imageUrlNode.List.First;
                }

                // Update the batch with the new control amount
                batch.ControlAmount += financialTransaction.TotalAmount;
                batch.Transactions.Add( financialTransaction );
            }
        }
Пример #6
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="batchId">The financial batch identifier.</param>
        public void ShowDetail( int batchId )
        {
            FinancialBatch batch = null;

            bool editAllowed = true;

            if ( !batchId.Equals( 0 ) )
            {
                batch = GetBatch( batchId );
                if ( batch != null )
                {
                    editAllowed = batch.IsAuthorized( Authorization.EDIT, CurrentPerson );
                    pdAuditDetails.SetEntity( batch, ResolveRockUrl( "~" ) );
                }
            }

            if ( batch == null )
            {
                batch = new FinancialBatch { Id = 0, Status = BatchStatus.Open };

                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            hfBatchId.Value = batch.Id.ToString();

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if ( !editAllowed || !IsUserAuthorized( Authorization.EDIT ) )
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( FinancialBatch.FriendlyTypeName );
            }

            if ( readOnly )
            {
                lbEdit.Visible = false;
                ShowReadonlyDetails( batch );
            }
            else
            {
                lbEdit.Visible = true;
                if ( batch.Id > 0 )
                {
                    ShowReadonlyDetails( batch );
                }
                else
                {
                    ShowEditDetails( batch );
                }
            }

            lbSave.Visible = !readOnly;
        }
Пример #7
0
        /// <summary>
        /// Shows the edit details.
        /// </summary>
        /// <param name="batch">The financial batch.</param>
        protected void ShowEditDetails( FinancialBatch batch )
        {
            if ( batch != null )
            {
                hfBatchId.Value = batch.Id.ToString();
                string title = batch.Id > 0 ?
                    ActionTitle.Edit( FinancialBatch.FriendlyTypeName ) :
                    ActionTitle.Add( FinancialBatch.FriendlyTypeName );

                SetHeadingInfo( batch, title );

                SetEditMode( true );

                tbName.Text = batch.Name;

                ddlStatus.BindToEnum<BatchStatus>();
                ddlStatus.SelectedIndex = (int)(BatchStatus)batch.Status;

                campCampus.Campuses = CampusCache.All();
                if ( batch.CampusId.HasValue )
                {
                    campCampus.SetValue( batch.CampusId.Value );
                }

                tbControlAmount.Text = batch.ControlAmount.ToString( "N2" );

                dtpStart.SelectedDateTime = batch.BatchStartDateTime;
                dtpEnd.SelectedDateTime = batch.BatchEndDateTime;

                tbAccountingCode.Text = batch.AccountingSystemCode;
                tbNote.Text = batch.Note;
            }
        }
Пример #8
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 campus = string.Empty;
                if (batch.Campus != null)
                {
                    campus = batch.Campus.ToString();
                }

                decimal txnTotal     = batch.Transactions.Sum(t => (decimal?)(t.TransactionDetails.Sum(d => (decimal?)d.Amount) ?? 0.0M)) ?? 0.0M;
                decimal variance     = txnTotal - batch.ControlAmount;
                string  amountFormat = string.Format("{0} / {1} / " + (variance == 0.0M ? "{2}" : "<span class='label label-danger'>{2}</span>"),
                                                     txnTotal.ToString("C2"), batch.ControlAmount.ToString("C2"), variance.ToString("C2"));

                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)
                                .Html;
                //Account Summary
                gAccounts.DataSource = batch.Transactions
                                       .SelectMany(t => t.TransactionDetails)
                                       .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 = batch.Transactions
                                            .Select(t => new
                {
                    CurrencyId   = t.CurrencyTypeValue != null ? t.CurrencyTypeValue.Id : 0,
                    CurrencyName = t.CurrencyTypeValue != null ? t.CurrencyTypeValue.Value : "None",
                    TotalAmount  = t.TotalAmount
                })
                                            .GroupBy(c => new
                {
                    c.CurrencyId,
                    c.CurrencyName
                })
                                            .Select(s => new
                {
                    Id     = s.Key.CurrencyId,
                    Name   = s.Key.CurrencyName,
                    Amount = s.Sum(a => (decimal?)a.TotalAmount) ?? 0.0M
                })
                                            .OrderBy(s => s.Name)
                                            .ToList();
                gCurrencyTypes.DataBind();
            }
        }
Пример #9
0
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e)
        {
            var            rockContext  = new RockContext();
            var            batchService = new FinancialBatchService(rockContext);
            FinancialBatch batch        = null;

            var changes = new List <string>();

            int batchId = hfBatchId.Value.AsInteger();

            if (batchId == 0)
            {
                batch = new FinancialBatch();
                batchService.Add(batch);
                changes.Add("Created the batch");
            }
            else
            {
                batch = batchService.Get(batchId);
            }

            if (batch != null)
            {
                if (ddlBatchName.Visible)
                {
                    History.EvaluateChange(changes, "Batch Name", batch.Name, ddlBatchName.SelectedItem.Text);
                    batch.Name = ddlBatchName.SelectedItem.Text;
                }
                else
                {
                    History.EvaluateChange(changes, "Batch Name", batch.Name, tbName.Text);
                    batch.Name = tbName.Text;
                }

                BatchStatus batchStatus = (BatchStatus)ddlStatus.SelectedIndex;

                string errorMessage;
                if (!batch.IsValidBatchStatusChange(batch.Status, batchStatus, this.CurrentPerson, out errorMessage))
                {
                    cvBatch.IsValid      = false;
                    cvBatch.ErrorMessage = errorMessage;
                    return;
                }

                History.EvaluateChange(changes, "Status", batch.Status, batchStatus);
                batch.Status = batchStatus;

                CampusCache oldCampus = null;
                if (batch.CampusId.HasValue)
                {
                    oldCampus = CampusCache.Read(batch.CampusId.Value);
                }

                CampusCache newCampus = null;
                if (campCampus.SelectedCampusId.HasValue)
                {
                    newCampus = CampusCache.Read(campCampus.SelectedCampusId.Value);
                }

                History.EvaluateChange(changes, "Campus", oldCampus != null ? oldCampus.Name : "None", newCampus != null ? newCampus.Name : "None");
                batch.CampusId = campCampus.SelectedCampusId;

                DateTime?startDateTime = dtpStart.SelectedDateTimeIsBlank ? null : dtpStart.SelectedDateTime;
                History.EvaluateChange(changes, "Start Date/Time", batch.BatchStartDateTime, startDateTime);
                batch.BatchStartDateTime = startDateTime;

                DateTime?endDateTime;
                if (dtpEnd.SelectedDateTimeIsBlank && batch.BatchStartDateTime.HasValue)
                {
                    endDateTime = batch.BatchStartDateTime.Value.AddDays(1);
                }
                else
                {
                    endDateTime = dtpEnd.SelectedDateTimeIsBlank ? null : dtpEnd.SelectedDateTime;
                }

                History.EvaluateChange(changes, "End Date/Time", batch.BatchEndDateTime, endDateTime);
                batch.BatchEndDateTime = endDateTime;

                decimal controlAmount = tbControlAmount.Text.AsDecimal();
                History.EvaluateChange(changes, "Control Amount", batch.ControlAmount.FormatAsCurrency(), controlAmount.FormatAsCurrency());
                batch.ControlAmount = controlAmount;

                History.EvaluateChange(changes, "Accounting System Code", batch.AccountingSystemCode, tbAccountingCode.Text);
                batch.AccountingSystemCode = tbAccountingCode.Text;

                History.EvaluateChange(changes, "Notes", batch.Note, tbNote.Text);
                batch.Note = tbNote.Text;

                cvBatch.IsValid = batch.IsValid;
                if (!Page.IsValid || !batch.IsValid)
                {
                    cvBatch.ErrorMessage = batch.ValidationResults.Select(a => a.ErrorMessage).ToList().AsDelimited("<br />");
                    return;
                }

                batch.LoadAttributes(rockContext);
                Rock.Attribute.Helper.GetEditValues(phAttributes, batch);

                rockContext.WrapTransaction(() =>
                {
                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            pdAuditDetails.SetEntity(batch, ResolveRockUrl("~"));
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(FinancialBatch),
                                Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                batch.Id,
                                changes);
                        }
                    }
                });

                batch.SaveAttributeValues(rockContext);

                if (batchId == 0)
                {
                    // If created a new batch, navigate to same page so that transaction list displays correctly
                    var pageReference = CurrentPageReference;
                    pageReference.Parameters.AddOrReplace("batchId", batch.Id.ToString());
                    NavigateToPage(pageReference);
                }
                else
                {
                    hfBatchId.SetValue(batch.Id);

                    // Requery the batch to support EF navigation properties
                    var savedBatch = GetBatch(batch.Id);
                    ShowReadonlyDetails(savedBatch);

                    // If there is a batch context item, update the context's properties with new values
                    var contextObjects = new Dictionary <string, object>();
                    foreach (var contextEntityType in RockPage.GetContextEntityTypes())
                    {
                        var contextEntity = RockPage.GetCurrentContext(contextEntityType);
                        if (contextEntity is FinancialBatch)
                        {
                            var contextBatch = contextEntity as FinancialBatch;
                            contextBatch.CopyPropertiesFrom(batch);
                        }
                    }

                    // Then refresh transaction list
                    RockPage.UpdateBlocks("~/Blocks/Finance/TransactionList.ascx");
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapBatch( IQueryable<Row> tableData )
        {
            var batchAttribute = AttributeCache.Read( BatchAttributeId );
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches = new List<FinancialBatch>();

            int completed = 0;
            int totalRows = tableData.Count();
            int percentage = ( totalRows - 1 ) / 100 + 1;
            ReportProgress( 0, string.Format( "Checking batch import ({0:N0} found, {1:N0} already exist).", totalRows, ImportedBatches.Count() ) );
            foreach ( var row in tableData )
            {
                int? batchId = row["BatchID"] as int?;
                if ( batchId != null && !ImportedBatches.ContainsKey( batchId ) )
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAlias.Id;
                    batch.Status = batchStatusClosed;

                    string name = row["BatchName"] as string;
                    if ( name != null )
                    {
                        name = name.Trim();
                        batch.Name = name.Left( 50 );
                        batch.CampusId = CampusList.Where( c => name.StartsWith( c.Name ) || name.StartsWith( c.ShortCode ) )
                            .Select( c => (int?)c.Id ).FirstOrDefault();
                    }

                    DateTime? batchDate = row["BatchDate"] as DateTime?;
                    if ( batchDate != null )
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime = batchDate;
                    }

                    decimal? amount = row["BatchAmount"] as decimal?;
                    if ( amount != null )
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    batch.Attributes = new Dictionary<string, AttributeCache>();
                    batch.AttributeValues = new Dictionary<string, List<AttributeValue>>();
                    batch.Attributes.Add( batchAttribute.Key, batchAttribute );
                    batch.AttributeValues.Add( batchAttribute.Key, new List<AttributeValue>() );
                    batch.AttributeValues[batchAttribute.Key].Add( new AttributeValue()
                    {
                        AttributeId = batchAttribute.Id,
                        Value = batchId.ToString(),
                        Order = 0
                    } );

                    newBatches.Add( batch );
                    completed++;
                    if ( completed % percentage < 1 )
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress( percentComplete, string.Format( "{0:N0} batches imported ({1}% complete).", completed, percentComplete ) );
                    }
                    else if ( completed % ReportingNumber < 1 )
                    {
                        RockTransactionScope.WrapTransaction( () =>
                        {
                            var batchService = new FinancialBatchService();
                            batchService.RockContext.FinancialBatches.AddRange( newBatches );
                            batchService.RockContext.SaveChanges();

                            var attributeValueService = new AttributeValueService();
                            foreach ( var newBatch in newBatches.Where( b => b.Attributes.Any() ) )
                            {
                                var attributeValue = newBatch.AttributeValues[batchAttribute.Key].FirstOrDefault();
                                if ( attributeValue != null )
                                {
                                    attributeValue.EntityId = newBatch.Id;
                                    attributeValueService.RockContext.AttributeValues.Add( attributeValue );
                                }
                            }

                            attributeValueService.RockContext.SaveChanges();
                        } );

                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if ( newBatches.Any() )
            {
                RockTransactionScope.WrapTransaction( () =>
                {
                    var batchService = new FinancialBatchService();
                    batchService.RockContext.FinancialBatches.AddRange( newBatches );
                    batchService.RockContext.SaveChanges();

                    var attributeValueService = new AttributeValueService();
                    foreach ( var newBatch in newBatches.Where( b => b.Attributes.Any() ) )
                    {
                        var attributeValue = newBatch.AttributeValues[batchAttribute.Key].FirstOrDefault();
                        if ( attributeValue != null )
                        {
                            attributeValue.EntityId = newBatch.Id;
                            attributeValueService.RockContext.AttributeValues.Add( attributeValue );
                        }
                    }

                    attributeValueService.RockContext.SaveChanges();
                } );
            }

            ReportProgress( 100, string.Format( "Finished batch import: {0:N0} batches imported.", completed ) );
        }
Пример #11
0
        /// <summary>
        /// Updates the batch UI.
        /// </summary>
        /// <param name="selectedBatch">The selected batch.</param>
        private void UpdateBatchUI( FinancialBatch selectedBatch )
        {
            if ( selectedBatch == null )
            {
                HideBatch();
                return;
            }
            else
            {
                ShowBatch( false );
            }

            RockConfig rockConfig = RockConfig.Load();
            RockRestClient client = new RockRestClient( rockConfig.RockBaseUrl );
            client.Login( rockConfig.Username, rockConfig.Password );
            SelectedFinancialBatch = selectedBatch;
            lblBatchNameReadOnly.Content = selectedBatch.Name;

            lblBatchCampusReadOnly.Content = selectedBatch.CampusId.HasValue ? client.GetData<Campus>( string.Format( "api/Campus/{0}", selectedBatch.CampusId ) ).Name : None.Text;
            lblBatchDateReadOnly.Content = selectedBatch.BatchStartDateTime.Value.ToString( "d" );
            lblBatchCreatedByReadOnly.Content = client.GetData<Person>( string.Format( "api/People/GetByPersonAliasId/{0}", selectedBatch.CreatedByPersonAliasId ) ).FullName;
            lblBatchControlAmountReadOnly.Content = selectedBatch.ControlAmount.ToString( "F" );

            txtBatchName.Text = selectedBatch.Name;
            if ( selectedBatch.CampusId.HasValue )
            {
                cbCampus.SelectedValue = selectedBatch.CampusId;
            }
            else
            {
                cbCampus.SelectedValue = 0;
            }

            dpBatchDate.SelectedDate = selectedBatch.BatchStartDateTime;
            lblCreatedBy.Content = lblBatchCreatedByReadOnly.Content as string;
            txtControlAmount.Text = selectedBatch.ControlAmount.ToString( "F" );

            List<FinancialTransaction> transactions = client.GetData<List<FinancialTransaction>>( "api/FinancialTransactions/", string.Format( "BatchId eq {0}", selectedBatch.Id ) );
            foreach ( var transaction in transactions )
            {
                transaction.CurrencyTypeValue = this.CurrencyValueList.FirstOrDefault( a => a.Id == transaction.CurrencyTypeValueId );
            }

            // include CheckNumber for checks that we scanned in this session
            var scannedCheckList = ScannedDocList.Where( a => a.IsCheck ).ToList();
            var gridList = transactions.OrderByDescending( a => a.CreatedDateTime ).Select( a => new
            {
                FinancialTransaction = a,
                CheckNumber = a.CurrencyTypeValue.Guid == Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK.AsGuid()
                    ? scannedCheckList.FirstOrDefault( s => s.TransactionId == a.Id ) != null ? scannedCheckList.FirstOrDefault( s => s.TransactionId == a.Id ).CheckNumber : "****"
                    : "-"
            } );

            grdBatchItems.DataContext = gridList;
        }
Пример #12
0
        public static FinancialTransaction Translate(IDictionary <string, object> record, List <FinancialAccount> accounts, List <FinancialBatch> batches)
        {
            if (record == null || !record.Keys.Any())
            {
                return(null);
            }

            var accountName = CsvFieldTranslators.GetString("Fund(s)", record);
            var account     = accounts.FirstOrDefault(a => a.Name == accountName);

            if (account == null)
            {
                account = new FinancialAccount
                {
                    // CampusId
                    Id   = accounts.Count + 1,
                    Name = accountName
                };

                accounts.Add(account);
            }

            // Map the properties of Person Note class to known CSV headers
            // Maybe this could be configurable to the user in the UI if the need arises
            var transactionPropertyToCsvFieldNameMap = new Dictionary <string, string> {
                { "Id", "Payment ID" },
                { "BatchId", "Batch" },
                { "AuthorizedPersonId", "Person ID" },
                { "TransactionDate", "Date" },
                //{ "TransactionType", "" }
                { "TransactionSource", "Method ID" },
                { "CurrencyType", "Method ID" },
                { "Summary", "Note" },
                { "TransactionCode", "Payment ID" },
                { "CreatedDateTime", "Date" }
                // ModifiedByPersonId
                // ModifiedDateTime
            };

            var detailPropertyToCsvFieldNameMap = new Dictionary <string, string> {
                { "Id", "Payment ID" },
                { "TransactionId", "Payment ID" },
                // AccountId
                { "Amount", "Amount" },
                { "Summary", "Note" },
                // CreatedByPersonId
                { "CreatedDateTime", "Date" }
                // ModifiedByPersonId
                // ModifiedDateTime
            };

            // Create a person note object. Using the map, read values from the CSV record and
            // set the associated properties of the person with those values
            var transaction     = new FinancialTransaction();
            var transactionType = transaction.GetType();

            foreach (var kvp in transactionPropertyToCsvFieldNameMap)
            {
                var propertyName = kvp.Key;
                var csvFieldName = kvp.Value;
                var property     = transactionType.GetProperty(propertyName);
                var value        = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, record);

                property.SetValue(transaction, value);
            }

            var detail = new FinancialTransactionDetail
            {
                AccountId = account.Id
            };
            var detailType = detail.GetType();

            transaction.FinancialTransactionDetails.Add(detail);

            foreach (var kvp in detailPropertyToCsvFieldNameMap)
            {
                var propertyName = kvp.Key;
                var csvFieldName = kvp.Value;
                var property     = detailType.GetProperty(propertyName);
                var value        = CsvFieldTranslators.GetValue(property.PropertyType, csvFieldName, record);

                property.SetValue(detail, value);
            }

            var existingBatch = batches.FirstOrDefault(b => b.Id == transaction.BatchId);

            if (existingBatch == null)
            {
                existingBatch = new FinancialBatch
                {
                    Id     = transaction.BatchId,
                    Name   = "Breeze Transactions",
                    Status = BatchStatus.Closed
                };

                batches.Add(existingBatch);
            }

            existingBatch.FinancialTransactions.Add(transaction);

            // Batch doesn't have a start date or this transaction is before the start date
            if (!existingBatch.StartDate.HasValue ||
                (transaction.TransactionDate.HasValue &&
                 transaction.TransactionDate.Value < existingBatch.StartDate.Value))
            {
                existingBatch.StartDate = transaction.TransactionDate;
            }

            // TODO store unused values, like checknumber, as attributes when slingshot supports it

            return(transaction);
        }
Пример #13
0
        public static List <GLTransaction> GetTransactionSummary(FinancialBatch financialBatch, RockContext rockContext, out List <RegistrationInstance> registrationLinks, out List <GroupMember> groupMemberLinks)
        {
            //
            // Group/Sum Transactions by Debit/Bank Account and Project since Project can come from Account or Transaction Details
            //
            var batchTransactions = new List <GLTransaction>();

            registrationLinks = new List <RegistrationInstance>();
            groupMemberLinks  = new List <GroupMember>();
            foreach (var transaction in financialBatch.Transactions)
            {
                transaction.LoadAttributes();
                var gateway = transaction.FinancialGateway;
                var gatewayDefaultFeeAccount = string.Empty;
                var processTransactionFees   = 0;
                if (gateway != null)
                {
                    gateway.LoadAttributes();
                    gatewayDefaultFeeAccount = transaction.FinancialGateway.GetAttributeValue("rocks.kfs.Intacct.DEFAULTFEEACCOUNTNO");
                    var gatewayFeeProcessing = transaction.FinancialGateway.GetAttributeValue("rocks.kfs.Intacct.FEEPROCESSING").AsIntegerOrNull();
                    if (gatewayFeeProcessing != null)
                    {
                        processTransactionFees = gatewayFeeProcessing.Value;
                    }
                }

                foreach (var transactionDetail in transaction.TransactionDetails)
                {
                    transactionDetail.LoadAttributes();
                    transactionDetail.Account.LoadAttributes();

                    var detailProject         = transactionDetail.GetAttributeValue("rocks.kfs.Intacct.PROJECTID").AsGuidOrNull();
                    var accountProject        = transactionDetail.Account.GetAttributeValue("rocks.kfs.Intacct.PROJECTID").AsGuidOrNull();
                    var transactionFeeAccount = transactionDetail.Account.GetAttributeValue("rocks.kfs.Intacct.FEEACCOUNTNO");

                    if (string.IsNullOrWhiteSpace(transactionFeeAccount))
                    {
                        transactionFeeAccount = gatewayDefaultFeeAccount;
                    }

                    var projectCode = string.Empty;
                    if (detailProject != null)
                    {
                        projectCode = DefinedValueCache.Get(( Guid )detailProject).Value;
                    }
                    else if (accountProject != null)
                    {
                        projectCode = DefinedValueCache.Get(( Guid )accountProject).Value;
                    }

                    if (transactionDetail.EntityTypeId.HasValue)
                    {
                        var registrationEntityType = EntityTypeCache.Get(typeof(Rock.Model.Registration));
                        var groupMemberEntityType  = EntityTypeCache.Get(typeof(Rock.Model.GroupMember));

                        if (transactionDetail.EntityId.HasValue && transactionDetail.EntityTypeId == registrationEntityType.Id)
                        {
                            foreach (var registration in new RegistrationService(rockContext)
                                     .Queryable().AsNoTracking()
                                     .Where(r =>
                                            r.RegistrationInstance != null &&
                                            r.RegistrationInstance.RegistrationTemplate != null &&
                                            r.Id == transactionDetail.EntityId))
                            {
                                registrationLinks.Add(registration.RegistrationInstance);
                            }
                        }
                        if (transactionDetail.EntityId.HasValue && transactionDetail.EntityTypeId == groupMemberEntityType.Id)
                        {
                            foreach (var groupMember in new GroupMemberService(rockContext)
                                     .Queryable().AsNoTracking()
                                     .Where(gm =>
                                            gm.Group != null &&
                                            gm.Id == transactionDetail.EntityId))
                            {
                                groupMemberLinks.Add(groupMember);
                            }
                        }
                    }

                    var transactionItem = new GLTransaction()
                    {
                        Payer                  = transaction.AuthorizedPersonAlias.Person.FullName,
                        Amount                 = transactionDetail.Amount,
                        FinancialAccountId     = transactionDetail.AccountId,
                        Project                = projectCode,
                        TransactionFeeAmount   = transactionDetail.FeeAmount != null && transactionDetail.FeeAmount.Value > 0 ? transactionDetail.FeeAmount.Value : 0.0M,
                        TransactionFeeAccount  = transactionFeeAccount,
                        ProcessTransactionFees = processTransactionFees
                    };

                    batchTransactions.Add(transactionItem);
                }
            }

            var batchTransactionList = batchTransactions
                                       .GroupBy(d => new { d.FinancialAccountId, d.Project, d.TransactionFeeAccount, d.ProcessTransactionFees })
                                       .Select(s => new GLTransaction
            {
                Payer = "Rock Import",
                FinancialAccountId     = s.Key.FinancialAccountId,
                Project                = s.Key.Project,
                Amount                 = s.Sum(f => ( decimal? )f.Amount) ?? 0.0M,
                TransactionFeeAmount   = s.Sum(f => ( decimal? )f.TransactionFeeAmount) ?? 0.0M,
                TransactionFeeAccount  = s.Key.TransactionFeeAccount,
                ProcessTransactionFees = s.Key.ProcessTransactionFees
            })
                                       .ToList();

            return(batchTransactionList);
        }
Пример #14
0
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            bool promptWithFilter = true;
            var  contextEntity    = this.ContextEntity();

            if (contextEntity != null)
            {
                if (contextEntity is Person)
                {
                    _person          = contextEntity as Person;
                    promptWithFilter = false;
                }
                else if (contextEntity is FinancialBatch)
                {
                    _batch = contextEntity as FinancialBatch;
                    gfTransactions.Visible = false;
                    promptWithFilter       = false;
                }
                else if (contextEntity is FinancialScheduledTransaction)
                {
                    _scheduledTxn          = contextEntity as FinancialScheduledTransaction;
                    gfTransactions.Visible = false;
                    promptWithFilter       = false;
                }
            }

            if (!Page.IsPostBack)
            {
                BindFilter();

                if (promptWithFilter && gfTransactions.Visible)
                {
                    //// NOTE: Special Case for this List Block since there could be a very large number of transactions:
                    //// If the filter is shown and we aren't filtering by anything else, don't automatically populate the grid. Wait for them to hit apply on the filter
                    gfTransactions.Show();
                }
                else
                {
                    BindGrid();
                }
            }

            if (_canEdit && _batch != null)
            {
                string script = string.Format(@"
    $('#{0}').change(function( e ){{
        var count = $(""#{1} input[id$='_cbSelect_0']:checked"").length;
        if (count == 0) {{
            eval({2});
        }}
        else
        {{
            var $ddl = $(this);
            if ($ddl.val() != '') {{
                Rock.dialogs.confirm('Are you sure you want to move the selected transactions to a new batch (the control amounts on each batch will be updated to reflect the moved transaction\'s amounts)?', function (result) {{
                    if (result) {{
                        eval({2});
                    }}
                    $ddl.val('');
                }});
            }}
        }}
    }});
", _ddlMove.ClientID, gTransactions.ClientID, Page.ClientScript.GetPostBackEventReference(this, "MoveTransactions"));
                ScriptManager.RegisterStartupScript(_ddlMove, _ddlMove.GetType(), "moveTransaction", script, true);
            }
        }
        private OtherReceipt BuildOtherReceipt(FinancialBatch financialBatch, ref string debugLava, PaymentMethod paymentMethod, string bankAccountId = null, string unDepGLAccountId = null, string DescriptionLava = "")
        {
            if (string.IsNullOrWhiteSpace(DescriptionLava))
            {
                DescriptionLava = "{{ Batch.Id }}: {{ Batch.Name }}";
            }

            var rockContext = new RockContext();

            var batchDate    = financialBatch.BatchStartDateTime == null ? RockDateTime.Now : ((System.DateTime)financialBatch.BatchStartDateTime);
            var otherReceipt = new OtherReceipt
            {
                Payer            = "Rock Batch Import",
                PaymentDate      = batchDate,
                ReceivedDate     = batchDate,
                PaymentMethod    = paymentMethod,
                BankAccountId    = bankAccountId,
                UnDepGLAccountNo = unDepGLAccountId,
                DepositDate      = batchDate,
                Description      = string.Format("Imported From Rock batch {0}: {1}", financialBatch.Id, financialBatch.Name),
                RefId            = financialBatch.Id.ToString(),
                ReceiptItems     = new List <ReceiptLineItem>()
            };
            List <RegistrationInstance> registrationLinks;
            List <GroupMember>          groupMemberLinks;
            var receiptTransactions = TransactionHelpers.GetTransactionSummary(financialBatch, rockContext, out registrationLinks, out groupMemberLinks);

            //
            // Get the Dimensions from the Account since the Transaction Details have been Grouped already
            //
            var customDimensions = TransactionHelpers.GetCustomDimensions();

            // Create Receipt Item for each entry within a grouping
            foreach (var bTran in receiptTransactions)
            {
                var account = new FinancialAccountService(rockContext).Get(bTran.FinancialAccountId);
                var customDimensionValues = new Dictionary <string, dynamic>();
                account.LoadAttributes();
                var mergeFieldObjects = new MergeFieldObjects
                {
                    Account          = account,
                    Batch            = financialBatch,
                    Registrations    = registrationLinks,
                    GroupMembers     = groupMemberLinks,
                    Summary          = bTran,
                    CustomDimensions = customDimensions
                };
                Dictionary <string, object> mergeFields = TransactionHelpers.GetMergeFieldsAndDimensions(ref debugLava, customDimensionValues, mergeFieldObjects);

                var classId      = account.GetAttributeValue("rocks.kfs.Intacct.CLASSID");
                var departmentId = account.GetAttributeValue("rocks.kfs.Intacct.DEPARTMENT");
                var locationId   = account.GetAttributeValue("rocks.kfs.Intacct.LOCATION");

                var receiptItem = new ReceiptLineItem
                {
                    GlAccountNo  = account.GetAttributeValue("rocks.kfs.Intacct.ACCOUNTNO"),
                    Amount       = bTran.ProcessTransactionFees == 1 ? bTran.Amount - bTran.TransactionFeeAmount : bTran.Amount,
                    Memo         = DescriptionLava.ResolveMergeFields(mergeFields),
                    LocationId   = locationId,
                    DepartmentId = departmentId,
                    ProjectId    = bTran.Project,
                    ClassId      = classId,
                    CustomFields = customDimensionValues
                };
                otherReceipt.ReceiptItems.Add(receiptItem);

                if (bTran.ProcessTransactionFees == 2)
                {
                    var feeLineItem = new ReceiptLineItem
                    {
                        GlAccountNo  = bTran.TransactionFeeAccount,
                        Amount       = bTran.TransactionFeeAmount * -1,
                        Memo         = "Transaction Fees",
                        LocationId   = locationId,
                        DepartmentId = departmentId,
                        ProjectId    = bTran.Project,
                        ClassId      = classId
                    };
                    otherReceipt.ReceiptItems.Add(feeLineItem);
                }
            }

            return(otherReceipt);
        }
Пример #16
0
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e)
        {
            var            rockContext  = new RockContext();
            var            batchService = new FinancialBatchService(rockContext);
            FinancialBatch batch        = null;

            var changes = new List <string>();

            int batchId = hfBatchId.Value.AsInteger();

            if (batchId == 0)
            {
                batch = new FinancialBatch();
                batchService.Add(batch);
                changes.Add("Created the batch");
            }
            else
            {
                batch = batchService.Get(batchId);
            }

            if (batch != null)
            {
                History.EvaluateChange(changes, "Batch Name", batch.Name, tbName.Text);
                batch.Name = tbName.Text;

                BatchStatus batchStatus = (BatchStatus)ddlStatus.SelectedIndex;
                History.EvaluateChange(changes, "Status", batch.Status, batchStatus);
                batch.Status = batchStatus;

                CampusCache oldCampus = null;
                if (batch.CampusId.HasValue)
                {
                    oldCampus = CampusCache.Read(batch.CampusId.Value);
                }
                CampusCache newCampus = null;
                if (campCampus.SelectedCampusId.HasValue)
                {
                    newCampus = CampusCache.Read(campCampus.SelectedCampusId.Value);
                }
                History.EvaluateChange(changes, "Campus", oldCampus != null ? oldCampus.Name : "None", newCampus != null ? newCampus.Name : "None");
                batch.CampusId = campCampus.SelectedCampusId;

                DateTime?startDateTime = dtpStart.SelectedDateTimeIsBlank ? null : dtpStart.SelectedDateTime;
                History.EvaluateChange(changes, "Start Date/Time", batch.BatchStartDateTime, startDateTime);
                batch.BatchStartDateTime = startDateTime;

                DateTime?endDateTime;
                if (dtpEnd.SelectedDateTimeIsBlank && batch.BatchStartDateTime.HasValue)
                {
                    endDateTime = batch.BatchStartDateTime.Value.AddDays(1);
                }
                else
                {
                    endDateTime = dtpEnd.SelectedDateTimeIsBlank ? null : dtpEnd.SelectedDateTime;
                }
                History.EvaluateChange(changes, "End Date/Time", batch.BatchEndDateTime, endDateTime);
                batch.BatchEndDateTime = endDateTime;

                decimal controlAmount = tbControlAmount.Text.AsDecimal();
                History.EvaluateChange(changes, "Control Amount", batch.ControlAmount.FormatAsCurrency(), controlAmount.FormatAsCurrency());
                batch.ControlAmount = controlAmount;

                History.EvaluateChange(changes, "Accounting System Code", batch.AccountingSystemCode, tbAccountingCode.Text);
                batch.AccountingSystemCode = tbAccountingCode.Text;

                History.EvaluateChange(changes, "Notes", batch.Note, tbNote.Text);
                batch.Note = tbNote.Text;

                cvBatch.IsValid = batch.IsValid;
                if (!Page.IsValid || !batch.IsValid)
                {
                    cvBatch.ErrorMessage = batch.ValidationResults.Select(a => a.ErrorMessage).ToList().AsDelimited("<br />");
                    return;
                }

                rockContext.WrapTransaction(() =>
                {
                    if (rockContext.SaveChanges() > 0)
                    {
                        if (changes.Any())
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof(FinancialBatch),
                                Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                batch.Id,
                                changes);
                        }
                    }
                });

                if (batchId == 0)
                {
                    // If created a new batch, navigate to same page so that transaction list displays correctly
                    var pageReference = CurrentPageReference;
                    pageReference.Parameters.AddOrReplace("batchId", batch.Id.ToString());
                    NavigateToPage(pageReference);
                }
                else
                {
                    hfBatchId.SetValue(batch.Id);

                    // Requery the batch to support EF navigation properties
                    var savedBatch = GetBatch(batch.Id);

                    ShowReadonlyDetails(savedBatch);
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapBatch( CSVInstance csvData )
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches = new List<FinancialBatch>();

            int completed = 0;
            ReportProgress( 0, string.Format( "Verifying batch import ({0:N0} already exist).", ImportedBatches.Count ) );
            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ( (row = csvData.Database.FirstOrDefault()) != null )
            {
                string batchIdKey = row[BatchID];
                int? batchId = batchIdKey.AsType<int?>();
                if ( batchId != null && !ImportedBatches.ContainsKey( ( int )batchId ) )
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey = batchId.ToString();
                    batch.ForeignId = batchId;
                    batch.Note = string.Empty;
                    batch.Status = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row[BatchName] as string;
                    if ( !String.IsNullOrWhiteSpace( name ) )
                    {
                        name = name.Trim();
                        batch.Name = name.Left( 50 );
                        batch.CampusId = CampusList.Where( c => name.StartsWith( c.Name ) || name.StartsWith( c.ShortCode ) )
                            .Select( c => ( int? )c.Id ).FirstOrDefault();
                    }

                    string batchDateKey = row[BatchDate];
                    DateTime? batchDate = batchDateKey.AsType<DateTime?>();
                    if ( batchDate != null )
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime = batchDate;
                    }

                    string amountKey = row[BatchAmount];
                    decimal? amount = amountKey.AsType<decimal?>();
                    if ( amount != null )
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add( batch );
                    completed++;
                    if ( completed % (ReportingNumber * 10) < 1 )
                    {
                        ReportProgress( 0, string.Format( "{0:N0} batches imported.", completed ) );
                    }
                    else if ( completed % ReportingNumber < 1 )
                    {
                        SaveFinancialBatches( newBatches );
                        newBatches.ForEach( b => ImportedBatches.Add( ( int )b.ForeignId, ( int? )b.Id ) );
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if ( !ImportedBatches.ContainsKey( 0 ) )
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name = string.Format( "Default Batch (Imported {0})", ImportDateTime );
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey = "0";
                defaultBatch.ForeignId = 0;

                newBatches.Add( defaultBatch );
            }

            if ( newBatches.Any() )
            {
                SaveFinancialBatches( newBatches );
                newBatches.ForEach( b => ImportedBatches.Add( ( int )b.ForeignId, ( int? )b.Id ) );
            }

            ReportProgress( 100, string.Format( "Finished batch import: {0:N0} batches imported.", completed ) );
            return completed;
        }
Пример #18
0
        private List <JournalEntryLine> GetGlEntries(RockContext rockContext, FinancialBatch financialBatch, string journalCode, int period, ref string debugLava, string DescriptionLava = "")
        {
            if (string.IsNullOrWhiteSpace(DescriptionLava))
            {
                DescriptionLava = "{{ Batch.Id }}: {{ Batch.Name }}";
            }
            //
            // Group/Sum Transactions by Account and Project since Project can come from Account or Transaction Details
            //
            var batchTransactions = new List <GLTransaction>();
            var registrationLinks = new List <RegistrationInstance>();
            var groupMemberLinks  = new List <GroupMember>();

            foreach (var transaction in financialBatch.Transactions)
            {
                transaction.LoadAttributes();
                foreach (var transactionDetail in transaction.TransactionDetails)
                {
                    transactionDetail.LoadAttributes();
                    transactionDetail.Account.LoadAttributes();

                    var detailProject      = transactionDetail.GetAttributeValue("rocks.kfs.ShelbyFinancials.Project").AsGuidOrNull();
                    var transactionProject = transaction.GetAttributeValue("rocks.kfs.ShelbyFinancials.Project").AsGuidOrNull();
                    var accountProject     = transactionDetail.Account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Project").AsGuidOrNull();

                    var projectCode = string.Empty;
                    if (detailProject != null)
                    {
                        projectCode = DefinedValueCache.Get(( Guid )detailProject).Value;
                    }
                    else if (transactionProject != null)
                    {
                        projectCode = DefinedValueCache.Get(( Guid )transactionProject).Value;
                    }
                    else if (accountProject != null)
                    {
                        projectCode = DefinedValueCache.Get(( Guid )accountProject).Value;
                    }

                    if (transactionDetail.EntityTypeId.HasValue)
                    {
                        var registrationEntityType = EntityTypeCache.Get(typeof(Rock.Model.Registration));
                        var groupMemberEntityType  = EntityTypeCache.Get(typeof(Rock.Model.GroupMember));

                        if (transactionDetail.EntityId.HasValue && transactionDetail.EntityTypeId == registrationEntityType.Id)
                        {
                            foreach (var registration in new RegistrationService(rockContext)
                                     .Queryable().AsNoTracking()
                                     .Where(r =>
                                            r.RegistrationInstance != null &&
                                            r.RegistrationInstance.RegistrationTemplate != null &&
                                            r.Id == transactionDetail.EntityId))
                            {
                                registrationLinks.Add(registration.RegistrationInstance);
                            }
                        }
                        if (transactionDetail.EntityId.HasValue && transactionDetail.EntityTypeId == groupMemberEntityType.Id)
                        {
                            foreach (var groupMember in new GroupMemberService(rockContext)
                                     .Queryable().AsNoTracking()
                                     .Where(gm =>
                                            gm.Group != null &&
                                            gm.Id == transactionDetail.EntityId))
                            {
                                groupMemberLinks.Add(groupMember);
                            }
                        }
                    }

                    var transactionItem = new GLTransaction()
                    {
                        Amount             = transactionDetail.Amount,
                        FinancialAccountId = transactionDetail.AccountId,
                        Project            = projectCode
                    };

                    batchTransactions.Add(transactionItem);
                }
            }

            var batchTransactionsSummary = batchTransactions
                                           .GroupBy(d => new { d.FinancialAccountId, d.Project })
                                           .Select(s => new GLTransaction
            {
                FinancialAccountId = s.Key.FinancialAccountId,
                Project            = s.Key.Project,
                Amount             = s.Sum(f => ( decimal? )f.Amount) ?? 0.0M
            })
                                           .ToList();

            var batchSummary = new List <GLBatchTotals>();

            foreach (var summary in batchTransactionsSummary)
            {
                var account = new FinancialAccountService(rockContext).Get(summary.FinancialAccountId);
                account.LoadAttributes();

                var mergeFields = new Dictionary <string, object>();
                mergeFields.Add("Account", account);
                mergeFields.Add("Summary", summary);
                mergeFields.Add("Batch", financialBatch);
                mergeFields.Add("Registrations", registrationLinks);
                mergeFields.Add("GroupMembers", groupMemberLinks);
                mergeFields.Add("JournalCode", journalCode);
                mergeFields.Add("Period", period);

                var batchSummaryItem = new GLBatchTotals()
                {
                    CompanyNumber       = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Company"),
                    RegionNumber        = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Region"),
                    SuperFundNumber     = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.SuperFund"),
                    FundNumber          = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Fund"),
                    LocationNumber      = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Location"),
                    CostCenterNumber    = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.CostCenter"),
                    DepartmentNumber    = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.Department"),
                    CreditAccountNumber = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.CreditAccount"),
                    DebitAccountNumber  = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.DebitAccount"),
                    AccountSub          = account.GetAttributeValue("rocks.kfs.ShelbyFinancials.AccountSub"),
                    Amount             = summary.Amount,
                    Project            = summary.Project,
                    JournalNumber      = financialBatch.Id,
                    JournalDescription = DescriptionLava.ResolveMergeFields(mergeFields),
                    Date = financialBatch.BatchStartDateTime ?? RockDateTime.Now,
                    Note = financialBatch.Note
                };

                if (debugLava.Length < 6 && debugLava.AsBoolean())
                {
                    debugLava = mergeFields.lavaDebugInfo();
                }

                batchSummary.Add(batchSummaryItem);
            }

            return(GenerateLineItems(batchSummary));
        }
Пример #19
0
        /// <summary>
        /// Gets the warnings.
        /// </summary>
        /// <returns></returns>
        private List<string> GetWarnings( FinancialBatch batch )
        {
            var warningList = new List<string>();
            if ( batch.Status == BatchStatus.Open )
            {
                var transactionService = new FinancialTransactionService( new RockContext() );
                var transactionList = transactionService.Queryable().Where( trans => trans.BatchId == batch.Id && trans.AuthorizedPersonId == null ).ToList();
                if ( transactionList.Count > 0 )
                {
                    warningList.Add( "UNTIED" );
                }
            }

            return warningList;
        }
Пример #20
0
        /// <summary>
        /// Processes the confirmation.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        private bool ProcessConfirmation( out string errorMessage )
        {
            if ( string.IsNullOrWhiteSpace( TransactionCode ) )
            {
                GatewayComponent gateway = hfPaymentTab.Value == "ACH" ? _achGateway : _ccGateway;
                if ( gateway == null )
                {
                    errorMessage = "There was a problem creating the payment gateway information";
                    return false;
                }

                Person person = GetPerson( true );
                if ( person == null )
                {
                    errorMessage = "There was a problem creating the person information";
                    return false;
                }

                PaymentInfo paymentInfo = GetPaymentInfo();
                if ( paymentInfo == null )
                {
                    errorMessage = "There was a problem creating the payment information";
                    return false;
                }
                else
                {
                    paymentInfo.FirstName = person.FirstName;
                    paymentInfo.LastName = person.LastName;
                }

                if ( paymentInfo.CreditCardTypeValue != null )
                {
                    CreditCardTypeValueId = paymentInfo.CreditCardTypeValue.Id;
                } 

                PaymentSchedule schedule = GetSchedule();
                if ( schedule != null )
                {
                    schedule.PersonId = person.Id;

                    var scheduledTransaction = gateway.AddScheduledPayment( schedule, paymentInfo, out errorMessage );
                    if ( scheduledTransaction != null )
                    {
                        scheduledTransaction.TransactionFrequencyValueId = schedule.TransactionFrequencyValue.Id;
                        scheduledTransaction.AuthorizedPersonId = person.Id;
                        scheduledTransaction.GatewayEntityTypeId = EntityTypeCache.Read( gateway.TypeGuid ).Id;

                        foreach ( var account in SelectedAccounts.Where( a => a.Amount > 0 ) )
                        {
                            var transactionDetail = new FinancialScheduledTransactionDetail();
                            transactionDetail.Amount = account.Amount;
                            transactionDetail.AccountId = account.Id;
                            scheduledTransaction.ScheduledTransactionDetails.Add( transactionDetail );
                        }

                        var transactionService = new FinancialScheduledTransactionService();
                        transactionService.Add( scheduledTransaction, CurrentPersonId );
                        transactionService.Save( scheduledTransaction, CurrentPersonId );

                        ScheduleId = scheduledTransaction.GatewayScheduleId;
                        TransactionCode = scheduledTransaction.TransactionCode;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    var transaction = gateway.Charge( paymentInfo, out errorMessage );
                    if ( transaction != null )
                    {
                        transaction.TransactionDateTime = DateTime.Now;
                        transaction.AuthorizedPersonId = person.Id;
                        transaction.GatewayEntityTypeId = gateway.TypeId;
                        transaction.Amount = paymentInfo.Amount;
                        transaction.TransactionTypeValueId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION)).Id;
                        transaction.CurrencyTypeValueId = paymentInfo.CurrencyTypeValue.Id;
                        transaction.CreditCardTypeValueId = CreditCardTypeValueId;

                        Guid sourceGuid = Guid.Empty;
                        if (Guid.TryParse(GetAttributeValue("Source"), out sourceGuid))
                        {
                            transaction.SourceTypeValueId = DefinedValueCache.Read(sourceGuid).Id;
                        }
                        foreach ( var account in SelectedAccounts.Where( a => a.Amount > 0 ) )
                        {
                            var transactionDetail = new FinancialTransactionDetail();
                            transactionDetail.Amount = account.Amount;
                            transactionDetail.AccountId = account.Id;
                            transaction.TransactionDetails.Add( transactionDetail );
                        }

                        // Get the batch name
                        string ccSuffix = string.Empty;
                        if ( paymentInfo.CreditCardTypeValue != null )
                        {
                            ccSuffix = paymentInfo.CreditCardTypeValue.GetAttributeValue( "BatchNameSuffix" );
                        }
                        if ( string.IsNullOrWhiteSpace( ccSuffix ) )
                        {
                            ccSuffix = paymentInfo.CurrencyTypeValue.Name;
                        }
                        string batchName = GetAttributeValue( "BatchNamePrefix" ).Trim() + " " + ccSuffix;

                        using ( new UnitOfWorkScope() )
                        {
                            var batchService = new FinancialBatchService();
                            var batch = batchService.Queryable()
                                .Where( b =>
                                    b.Status == BatchStatus.Open &&
                                    b.BatchStartDateTime <= transaction.TransactionDateTime &&
                                    b.BatchEndDateTime > transaction.TransactionDateTime &&
                                    b.Name == batchName )
                                .FirstOrDefault();
                            if ( batch == null )
                            {
                                batch = new FinancialBatch();
                                batch.Name = batchName;
                                batch.Status = BatchStatus.Open;
                                batch.BatchStartDateTime = transaction.TransactionDateTime.Value.Date.Add( gateway.BatchTimeOffset );
                                if ( batch.BatchStartDateTime > transaction.TransactionDateTime )
                                {
                                    batch.BatchStartDateTime.Value.AddDays( -1 );
                                }
                                batch.BatchEndDateTime = batch.BatchStartDateTime.Value.AddDays( 1 ).AddMilliseconds( -1 );
                                batch.CreatedByPersonId = person.Id;
                                batchService.Add( batch, CurrentPersonId );
                                batchService.Save( batch, CurrentPersonId );

                                batch = batchService.Get( batch.Id );
                            }

                            batch.ControlAmount += transaction.Amount;
                            batchService.Save( batch, CurrentPersonId );

                            var transactionService = new FinancialTransactionService();
                            transaction.BatchId = batch.Id;
                            transactionService.Add( transaction, CurrentPersonId );
                            transactionService.Save( transaction, CurrentPersonId );
                        }

                        TransactionCode = transaction.TransactionCode;
                    }
                    else
                    {
                        return false;
                    }
                }

                tdTransactionCode.Description = TransactionCode;
                tdTransactionCode.Visible = !string.IsNullOrWhiteSpace( TransactionCode );

                tdScheduleId.Description = ScheduleId;
                tdScheduleId.Visible = !string.IsNullOrWhiteSpace( ScheduleId );

                // If there was a transaction code returned and this was not already created from a previous saved account, 
                // show the option to save the account.
                if ( !( paymentInfo is ReferencePaymentInfo ) && !string.IsNullOrWhiteSpace( TransactionCode ) )
                {
                    cbSaveAccount.Visible = true;
                    pnlSaveAccount.Visible = true;
                    txtSaveAccount.Visible = true;

                    // If current person does not have a login, have them create a username and password
                    phCreateLogin.Visible = !new UserLoginService().GetByPersonId( person.Id ).Any();
                }
                else
                {
                    pnlSaveAccount.Visible = false;
                }

                return true;
            }
            else
            {
                pnlDupWarning.Visible = true;
                errorMessage = string.Empty;
                return false;
            }
        }
Пример #21
0
        /// <summary>
        /// Shows the edit details.
        /// </summary>
        /// <param name="batch">The financial batch.</param>
        protected void ShowEditDetails( FinancialBatch batch )
        {
            if ( batch != null )
            {
                hfBatchId.Value = batch.Id.ToString();
                string title = batch.Id > 0 ?
                    ActionTitle.Edit( FinancialBatch.FriendlyTypeName ) :
                    ActionTitle.Add( FinancialBatch.FriendlyTypeName );

                SetHeadingInfo( batch, title );

                SetEditMode( true );

                tbName.Text = batch.Name;

                ddlStatus.BindToEnum( typeof( BatchStatus ) );
                ddlStatus.SelectedIndex = (int)(BatchStatus)batch.Status;

                campCampus.Campuses = new CampusService( new RockContext() ).Queryable().OrderBy( a => a.Name ).ToList();
                if ( batch.CampusId.HasValue )
                {
                    campCampus.SetValue( batch.CampusId.Value );
                }

                tbControlAmount.Text = batch.ControlAmount.ToString( "N2" );

                dtpStart.SelectedDateTime = batch.BatchStartDateTime;
                dtpEnd.SelectedDateTime = batch.BatchEndDateTime;

                tbAccountingCode.Text = batch.AccountingSystemCode;
            }
        }
Пример #22
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="batchId">The financial batch identifier.</param>
        public void ShowDetail(int batchId)
        {
            FinancialBatch batch = null;

            bool editAllowed = true;

            if (!batchId.Equals(0))
            {
                batch = GetBatch(batchId);
                if (batch != null)
                {
                    editAllowed = batch.IsAuthorized(Authorization.EDIT, CurrentPerson);
                    pdAuditDetails.SetEntity(batch, ResolveRockUrl("~"));
                }
            }

            if (batch == null)
            {
                batch = new FinancialBatch {
                    Id = 0, Status = BatchStatus.Open
                };

                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }
            else
            {
                string quickReturnLava        = "{{ Batch.Name | AddQuickReturn:'Batches', 50 }}";
                var    quickReturnMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson, new Rock.Lava.CommonMergeFieldsOptions {
                    GetLegacyGlobalMergeFields = false
                });
                quickReturnMergeFields.Add("Batch", batch);
                quickReturnLava.ResolveMergeFields(quickReturnMergeFields);
            }

            hfBatchId.Value = batch.Id.ToString();

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!editAllowed || !IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(FinancialBatch.FriendlyTypeName);
            }
            else if (batch.Status == BatchStatus.Closed)
            {
                if (!batch.IsAuthorized("ReopenBatch", this.CurrentPerson))
                {
                    readOnly = true;
                    nbEditModeMessage.Text = "Batch is closed and requires authorization to re-open before editing.";
                }
            }

            if (readOnly)
            {
                lbEdit.Visible = false;
                ShowReadonlyDetails(batch);
            }
            else
            {
                lbEdit.Visible = true;
                if (batch.Id > 0)
                {
                    ShowReadonlyDetails(batch);
                }
                else
                {
                    ShowEditDetails(batch);
                }
            }

            lbSave.Visible = !readOnly;
        }
Пример #23
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();
            }
        }
Пример #24
0
        /// <summary>
        /// Exports any contributions.
        /// </summary>
        public static void ExportContributions()
        {
            try
            {
                // Retrieve & Output the Fund Accounts
                using (var dtFunds = GetTableData(SQL_FINANCIAL_ACCOUNTS))
                {
                    foreach (DataRow row in dtFunds.Rows)
                    {
                        FinancialAccount account = SkFinancialAccount.Translate(row);
                        if (account is null)
                        {
                            continue;
                        }

                        ImportPackage.WriteToPackage(account);
                    }
                }

                // Retrieve & Output the Batches
                using (var dtBatches = GetTableData(SQL_FINANCIAL_BATCHES))
                {
                    foreach (DataRow row in dtBatches.Rows)
                    {
                        FinancialBatch batch = SkFinancialBatch.Translate(row);
                        if (batch is null)
                        {
                            continue;
                        }

                        ImportPackage.WriteToPackage(batch);
                    }
                }

                // Retrieve & Output the Contributions
                using (var dtContributions = GetTableData(SQL_FINANCIAL_CONTRIBUTIONS))
                {
                    foreach (DataRow row in dtContributions.Rows)
                    {
                        FinancialTransaction transaction = SkFinancialContribution.Translate(row);
                        if (transaction is null)
                        {
                            continue;
                        }

                        ImportPackage.WriteToPackage(transaction);
                    }
                }

                // Retrieve & Output the Contribution Details
                using (var dtContributionDetails = GetTableData(SQL_FINANCIAL_CONTRIBUTIONDETAILS))
                {
                    foreach (DataRow row in dtContributionDetails.Rows)
                    {
                        FinancialTransactionDetail details = SkFinancialContributionDetail.Translate(row);
                        if (details is null)
                        {
                            continue;
                        }

                        ImportPackage.WriteToPackage(details);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
            }
        }
Пример #25
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapBatch(IQueryable <Row> tableData, long totalRows = 0)
        {
            var newBatches = new List <FinancialBatch>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var earliestBatchDate = ImportDateTime;
            var completedItems    = 0;
            var percentage        = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying batch import ({totalRows:N0} found, {ImportedBatches.Count:N0} already exist).");
            foreach (var row in tableData.Where(r => r != null))
            {
                var batchId = row["BatchID"] as int?;
                if (batchId.HasValue && !ImportedBatches.ContainsKey(( int )batchId))
                {
                    var batch = new FinancialBatch
                    {
                        CreatedByPersonAliasId = ImportPersonAliasId,
                        ForeignKey             = batchId.ToString(),
                        ForeignId            = batchId,
                        Note                 = string.Empty,
                        Status               = BatchStatus.Closed,
                        AccountingSystemCode = string.Empty
                    };

                    var name = row["BatchName"] as string;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        name           = name.Trim();
                        batch.Name     = name.Truncate(50);
                        batch.CampusId = GetCampusId(name);
                    }

                    var batchDate = row["BatchDate"] as DateTime?;
                    if (batchDate.HasValue)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;

                        if (batchDate < earliestBatchDate)
                        {
                            earliestBatchDate = ( DateTime )batchDate;
                        }
                    }

                    var amount = row["BatchAmount"] as decimal?;
                    if (amount.HasValue)
                    {
                        batch.ControlAmount = amount.Value;
                    }

                    newBatches.Add(batch);
                    completedItems++;
                    if (completedItems % percentage < 1)
                    {
                        var percentComplete = completedItems / percentage;
                        ReportProgress(percentComplete, $"{completedItems:N0} batches imported ({percentComplete}% complete).");
                    }

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);
                        newBatches.ForEach(b => ImportedBatches.Add(( int )b.ForeignId, ( int? )b.Id));
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch
                {
                    CreatedDateTime        = ImportDateTime,
                    CreatedByPersonAliasId = ImportPersonAliasId,
                    BatchStartDateTime     = earliestBatchDate,
                    Status        = BatchStatus.Closed,
                    Name          = $"Default Batch (Imported {ImportDateTime})",
                    ControlAmount = 0.0m,
                    ForeignKey    = "0",
                    ForeignId     = 0
                };

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add(( int )b.ForeignId, ( int? )b.Id));
            }

            ImportedBatches = new FinancialBatchService(new RockContext()).Queryable().AsNoTracking()
                              .Where(b => b.ForeignId.HasValue)
                              .ToDictionary(t => ( int )t.ForeignId, t => ( int? )t.Id);

            ReportProgress(100, $"Finished batch import: {completedItems:N0} batches imported.");
        }
Пример #26
0
        public List <JournalEntryLine> GetGlEntries(RockContext rockContext, FinancialBatch financialBatch, string journal, string encumbranceStatus = "Regular")
        {
            //
            // Group/Sum Transactions by Account and Project since Project can come from Account or Transaction Details
            //
            var batchTransactions = new List <GLTransaction>();

            foreach (var transaction in financialBatch.Transactions)
            {
                transaction.LoadAttributes();
                foreach (var transactionDetail in transaction.TransactionDetails)
                {
                    transactionDetail.LoadAttributes();
                    transactionDetail.Account.LoadAttributes();

                    var detailProject  = transactionDetail.GetAttributeValue("rocks.kfs.FinancialEdge.PROJECTID").AsGuidOrNull();
                    var accountProject = transactionDetail.Account.GetAttributeValue("rocks.kfs.FinancialEdge.PROJECTID").AsGuidOrNull();

                    var projectCode = string.Empty;
                    if (detailProject != null)
                    {
                        projectCode = detailProject.ToString();
                    }
                    else if (accountProject != null)
                    {
                        projectCode = accountProject.ToString();
                    }

                    var transactionItem = new GLTransaction()
                    {
                        Amount             = transactionDetail.Amount,
                        CreditAccount      = transactionDetail.Account.GetAttributeValue("rocks.kfs.FinancialEdge.ACCOUNTNO"),
                        DebitAccount       = transactionDetail.Account.GetAttributeValue("rocks.kfs.FinancialEdge.DEBITACCOUNTNO"),
                        Project            = projectCode,
                        FinancialAccountId = transactionDetail.Account.Id,
                        DebitProject       = transactionDetail.Account.GetAttributeValue("rocks.kfs.FinancialEdge.DEBITPROJECTID"),
                    };

                    batchTransactions.Add(transactionItem);
                }
            }

            var creditLines = batchTransactions
                              .GroupBy(d => new { d.CreditAccount, d.Project })
                              .Select(s => new GLTransactionLine
            {
                Account = s.Key.CreditAccount,
                Project = s.Key.Project,
                Amount  = s.Sum(f => ( decimal? )f.Amount) ?? 0.0M
            })
                              .ToList();

            var debitLines = batchTransactions
                             .GroupBy(d => new { d.DebitAccount, d.DebitProject })
                             .Select(s => new GLTransactionLine
            {
                Account = s.Key.DebitAccount,
                Project = s.Key.DebitProject,
                Amount  = s.Sum(f => ( decimal? )f.Amount) ?? 0.0M,
            })
                             .ToList();

            var batchName = string.Format("{0} ({1})", financialBatch.Name, financialBatch.Id);

            return(GenerateLineItems(rockContext, creditLines, debitLines, financialBatch.BatchStartDateTime, journal, batchName, encumbranceStatus));
        }
Пример #27
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;

                // 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();
            }
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            var contextEntity = this.ContextEntity();
            if ( contextEntity != null )
            {
                if ( contextEntity is Person )
                {
                    _person = contextEntity as Person;
                }
                else if ( contextEntity is FinancialBatch )
                {
                    _batch = contextEntity as FinancialBatch;
                    gfTransactions.Visible = false;
                }
            }

            if ( !Page.IsPostBack )
            {
                BindFilter();
                BindGrid();
            }
        }
Пример #29
0
        /// <summary>
        /// Updates the batch UI.
        /// </summary>
        /// <param name="selectedBatch">The selected batch.</param>
        private void UpdateBatchUI(FinancialBatch selectedBatch)
        {
            if (selectedBatch == null)
            {
                grdBatchItems.DataContext = null;
                DisplayTransactionCount();
                HideBatch();
                return;
            }
            else
            {
                ShowBatch(false);
            }

            RockConfig     rockConfig = RockConfig.Load();
            RockRestClient client     = new RockRestClient(rockConfig.RockBaseUrl);

            client.Login(rockConfig.Username, rockConfig.Password);
            SelectedFinancialBatch       = selectedBatch;
            lblBatchNameReadOnly.Content = selectedBatch.Name;
            lblBatchIdReadOnly.Content   = string.Format("Batch Id: {0}", selectedBatch.Id);

            lblBatchCampusReadOnly.Content = selectedBatch.CampusId.HasValue ? client.GetData <Campus>(string.Format("api/Campuses/{0}", selectedBatch.CampusId ?? 0)).Name : string.Empty;
            lblBatchDateReadOnly.Content   = selectedBatch.BatchStartDateTime.Value.ToString("d");
            var createdByPerson = client.GetData <Person>(string.Format("api/People/GetByPersonAliasId/{0}", selectedBatch.CreatedByPersonAliasId ?? 0));

            if (createdByPerson != null)
            {
                lblBatchCreatedByReadOnly.Content = string.Format("{0} {1}", createdByPerson.NickName, createdByPerson.LastName);
            }
            else
            {
                lblBatchCreatedByReadOnly.Content = string.Empty;
            }

            lblBatchControlAmountReadOnly.Content = selectedBatch.ControlAmount.ToString("F");

            txtBatchName.Text = selectedBatch.Name;
            if (selectedBatch.CampusId.HasValue)
            {
                cbCampus.SelectedValue = selectedBatch.CampusId;
            }
            else
            {
                cbCampus.SelectedValue = 0;
            }

            dpBatchDate.SelectedDate = selectedBatch.BatchStartDateTime;
            lblCreatedBy.Content     = lblBatchCreatedByReadOnly.Content as string;
            txtControlAmount.Text    = selectedBatch.ControlAmount.ToString("F");
            txtNote.Text             = selectedBatch.Note;

            // start a background thread to download transactions since this could take a little while and we want a Wait cursor
            BackgroundWorker bw = new BackgroundWorker();

            Rock.Wpf.WpfHelper.FadeOut(lblCount, 0);
            lblCount.Content = "Loading...";
            Rock.Wpf.WpfHelper.FadeIn(lblCount, 300);
            List <FinancialTransaction> transactions = null;

            grdBatchItems.DataContext = null;
            bw.DoWork += delegate(object s, DoWorkEventArgs ee)
            {
                ee.Result = null;

                transactions = client.GetData <List <FinancialTransaction> >("api/FinancialTransactions/", string.Format("BatchId eq {0}", selectedBatch.Id));
            };

            bw.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs ee)
            {
                this.Cursor = null;
                foreach (var transaction in transactions)
                {
                    if (transaction.FinancialPaymentDetailId.HasValue)
                    {
                        transaction.FinancialPaymentDetail = transaction.FinancialPaymentDetail ?? client.GetData <FinancialPaymentDetail>(string.Format("api/FinancialPaymentDetails/{0}", transaction.FinancialPaymentDetailId ?? 0));
                        if (transaction.FinancialPaymentDetail != null)
                        {
                            transaction.FinancialPaymentDetail.CurrencyTypeValue = this.CurrencyValueList.FirstOrDefault(a => a.Id == transaction.FinancialPaymentDetail.CurrencyTypeValueId);
                        }
                    }
                }

                // sort starting with most recent first
                var bindingList = new BindingList <FinancialTransaction>(transactions.OrderByDescending(a => a.CreatedDateTime).ToList());
                bindingList.RaiseListChangedEvents = true;
                bindingList.ListChanged           += bindingList_ListChanged;

                grdBatchItems.DataContext = bindingList;
                DisplayTransactionCount();
            };

            this.Cursor = Cursors.Wait;
            bw.RunWorkerAsync();
        }
Пример #30
0
 /// <summary>
 /// Handles the Click event of the btnAddBatch control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
 private void btnAddBatch_Click( object sender, RoutedEventArgs e )
 {
     var financialBatch = new FinancialBatch { Id = 0, BatchStartDateTime = DateTime.Now.Date, CreatedByPersonAliasId = LoggedInPerson.PrimaryAlias.Id };
     UpdateBatchUI( financialBatch );
     ShowBatch( true );
 }
        private static void CreateFinancialTransactions(
            int personAliasId,
            int count,
            FinancialAccount account,
            FinancialBatch batch)
        {
            var currencyTypeGuid = string.Empty;

            for (var i = 0; i < count; i++)
            {
                int?   currencyTypeId     = 0;
                int?   cardTypeId         = null;
                string checkMicrEncrypted = null;
                string checkMicrHash      = null;
                string checkMicrParts     = null;

                var transactionDateTime = RockDateTime.Now.AddDays(i * -1);

                if (i == 0)
                {
                    _endDate = _startDate = transactionDateTime.AddDays(1);
                }

                // Dates are going backwards in time, adjuect start
                if (transactionDateTime < _startDate)
                {
                    _startDate = transactionDateTime;
                }

                if (i % 5 == 0)
                {
                    // Checks
                    currencyTypeId     = _checkValue.Id;
                    cardTypeId         = null;
                    checkMicrEncrypted = $"{Guid.NewGuid().ToString().Replace( "-", "" )}{Guid.NewGuid().ToString().Replace( "-", "" )}{Guid.NewGuid().ToString().Replace( "-", "" )}";
                    checkMicrHash      = null;
                    checkMicrParts     = null;
                }
                else if (i % 6 == 0)
                {
                    // Cash
                    currencyTypeId     = _cashValue.Id;
                    cardTypeId         = null;
                    checkMicrEncrypted = null;
                    checkMicrHash      = null;
                    checkMicrParts     = null;
                }
                else
                {
                    // Credit Cards
                    currencyTypeId     = _creditCardValue.Id;
                    cardTypeId         = _visaValue.Id;
                    checkMicrEncrypted = null;
                    checkMicrHash      = null;
                    checkMicrParts     = null;
                }

                var payment           = CreateFinancialPaymentDetail(currencyTypeId, cardTypeId, transactionDateTime);
                var transaction       = CreateFinancialTransaction(personAliasId, batch.Id, payment.Id, i, transactionDateTime, checkMicrEncrypted, checkMicrHash, checkMicrParts);
                var transactionDetail = CreateFinancialTransactionDetail(account.Id, transaction.Id, i, transactionDateTime);
            }

            _startDate = _startDate.AddDays(-1);
            _rockContext.SaveChanges(true);
        }
Пример #32
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapBatch(IQueryable <Row> tableData)
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches        = new List <FinancialBatch>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying batch import ({0:N0} found, {1:N0} already exist).", totalRows, ImportedBatches.Count));
            foreach (var row in tableData.Where(r => r != null))
            {
                int?batchId = row["BatchID"] as int?;
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey             = batchId.ToString();
                    batch.ForeignId            = batchId;
                    batch.Note                 = string.Empty;
                    batch.Status               = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row["BatchName"] as string;
                    if (name != null)
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    DateTime?batchDate = row["BatchDate"] as DateTime?;
                    if (batchDate != null)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;
                    }

                    decimal?amount = row["BatchAmount"] as decimal?;
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} batches imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);
                        newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime        = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status        = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name          = string.Format("Default Batch (Imported {0})", ImportDateTime);
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey    = "0";
                defaultBatch.ForeignId     = 0;

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, string.Format("Finished batch import: {0:N0} batches imported.", completed));
        }
Пример #33
0
        /// <summary>
        /// Updates the batch UI.
        /// </summary>
        /// <param name="selectedBatch">The selected batch.</param>
        private void UpdateBatchUI( FinancialBatch selectedBatch )
        {
            if ( selectedBatch == null )
            {
                HideBatch();
                return;
            }
            else
            {
                ShowBatch( false );
            }

            RockConfig rockConfig = RockConfig.Load();
            RockRestClient client = new RockRestClient( rockConfig.RockBaseUrl );
            client.Login( rockConfig.Username, rockConfig.Password );
            SelectedFinancialBatch = selectedBatch;
            lblBatchNameReadOnly.Content = selectedBatch.Name;

            lblBatchCampusReadOnly.Content = selectedBatch.CampusId.HasValue ? client.GetData<Campus>( string.Format( "api/Campus/{0}", selectedBatch.CampusId ) ).Name : None.Text;
            lblBatchDateReadOnly.Content = selectedBatch.BatchStartDateTime.Value.ToString( "d" );
            lblBatchCreatedByReadOnly.Content = client.GetData<Person>( string.Format( "api/People/GetByPersonAliasId/{0}", selectedBatch.CreatedByPersonAliasId ) ).FullName;
            lblBatchControlAmountReadOnly.Content = selectedBatch.ControlAmount.ToString( "F" );

            txtBatchName.Text = selectedBatch.Name;
            if ( selectedBatch.CampusId.HasValue )
            {
                cbCampus.SelectedValue = selectedBatch.CampusId;
            }
            else
            {
                cbCampus.SelectedValue = 0;
            }

            dpBatchDate.SelectedDate = selectedBatch.BatchStartDateTime;
            lblCreatedBy.Content = lblBatchCreatedByReadOnly.Content as string;
            txtControlAmount.Text = selectedBatch.ControlAmount.ToString( "F" );

            List<FinancialTransaction> transactions = client.GetData<List<FinancialTransaction>>( "api/FinancialTransactions/", string.Format( "BatchId eq {0}", selectedBatch.Id ) );
            foreach (var transaction in transactions)
            {
                transaction.TransactionDetails = client.GetData<List<FinancialTransactionDetail>>( "api/FinancialTransactionDetails/", string.Format( "TransactionId eq {0}", transaction.Id ) );
            }

            grdBatchItems.DataContext = transactions.OrderByDescending( a => a.CreatedDateTime );
        }
Пример #34
0
        /// <summary>
        /// Get the GLRecords for the given batch, with the appropriate information about
        /// the export data.
        /// </summary>
        /// <param name="batch">Batch to be exported.</param>
        /// <param name="date">The date of this deposit.</param>
        /// <param name="accountingPeriod">Accounting period as defined in the GL system.</param>
        /// <param name="journalType">The type of journal entry to create as defined in the GL system.</param>
        /// <returns>A collection of GLRecord objects to be imported into the GL system.</returns>
        List <GLRecord> GLRecordsForBatch(FinancialBatch batch, DateTime date, string accountingPeriod, string journalType)
        {
            List <GLRecord> records = new List <GLRecord>();

            //
            // Load all the transaction details, load their attributes and then group
            // by the account attributes, GLBankAccount+GLCompany+GLFund.
            //
            var transactions = batch.Transactions
                               .SelectMany(t => t.TransactionDetails)
                               .ToList();

            foreach (var d in transactions)
            {
                d.LoadAttributes();
                d.Account.LoadAttributes();
            }
            var accounts = transactions.GroupBy(d => new { GLBankAccount = d.Account.GetAttributeValue("GLBankAccount"), GLCompany = d.Account.GetAttributeValue("GLCompany"), GLFund = d.Account.GetAttributeValue("GLFund") }, d => d).OrderBy(g => g.Key.GLBankAccount);

            //
            // Go through each group and build the line items.
            //
            foreach (var grp in accounts)
            {
                GLRecord record = new GLRecord();

                //
                // Build the bank account deposit line item.
                //
                record.AccountingPeriod = accountingPeriod;
                record.AccountNumber    = grp.Key.GLBankAccount;
                record.Amount           = grp.Sum(d => d.Amount);
                record.Company          = grp.Key.GLCompany;
                record.Date             = date;
                record.Department       = string.Empty;
                record.Description1     = batch.Name + " (" + batch.Id.ToString() + ")";
                record.Description2     = string.Empty;
                record.Fund             = grp.Key.GLFund;
                record.Journal          = "0";
                record.JournalType      = journalType;
                record.Project          = string.Empty;

                records.Add(record);

                //
                // Build each of the revenue fund withdrawls.
                //
                foreach (var grpTransactions in grp.GroupBy(t => t.AccountId, t => t))
                {
                    record = new GLRecord();

                    record.AccountingPeriod = accountingPeriod;
                    record.AccountNumber    = grpTransactions.First().Account.GetAttributeValue("GLRevenueAccount");
                    record.Amount           = -(grpTransactions.Sum(t => t.Amount));
                    record.Company          = grp.Key.GLCompany;
                    record.Date             = date;
                    record.Department       = grpTransactions.First().Account.GetAttributeValue("GLRevenueDepartment");
                    record.Description1     = grpTransactions.First().Account.Name;
                    record.Description2     = string.Empty;
                    record.Fund             = grp.Key.GLFund;
                    record.Journal          = "0";
                    record.JournalType      = journalType;
                    record.Project          = string.Empty;

                    records.Add(record);
                }
            }

            return(records);
        }
        /// <summary>
        /// Handles the Click event of the btnConfirm 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 btnConfirm_Click(object sender, EventArgs e)
        {
            // send signalR message to start progress indicator
            int progress = 0;

            _hubContext.Clients.All.receiveNotification(signalREventName, "0");

            XDocument xml       = null;
            int?      total     = null;
            int?      batchId   = null;
            string    batchName = string.Empty;

            int?attributeId      = null;
            int?binaryFileTypeId = null;

            using (var rockContext = new RockContext())
            {
                // Get the XML
                var binaryFile = new BinaryFileService(rockContext).Get(_binaryFileId.Value);
                if (binaryFile != null)
                {
                    using (var stream = binaryFile.ContentStream)
                    {
                        xml = XDocument.Load(stream);
                    }
                }

                // Get the number of transactions
                if (xml != null)
                {
                    total = xml.Root.Descendants().Where(n => n.Name == "Gift").Count();
                }

                if (xml != null && total.HasValue && total.Value > 0)
                {
                    var            batchService = new FinancialBatchService(rockContext);
                    FinancialBatch batch        = null;

                    // Load (or create) the batch
                    batchId = ddlBatch.SelectedValueAsInt();
                    if (batchId.HasValue)
                    {
                        batch = batchService.Get(batchId.Value);
                    }

                    if (batch == null)
                    {
                        batch                    = new FinancialBatch();
                        batch.Guid               = Guid.NewGuid();
                        batch.Name               = Path.GetFileNameWithoutExtension(binaryFile.FileName);
                        batch.Status             = BatchStatus.Open;
                        batch.BatchStartDateTime = RockDateTime.Today;
                        batch.BatchEndDateTime   = batch.BatchStartDateTime.Value.AddDays(1);
                        batch.ControlAmount      = 0;
                        batchService.Add(batch);

                        rockContext.SaveChanges();

                        batchId = batch.Id;
                    }

                    batchName = batch.Name;

                    // Get the attribute id for the envelop number attribute
                    int?personEntityTypeId = EntityTypeCache.GetId <Rock.Model.Person>();
                    attributeId = new AttributeService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(a =>
                                         a.EntityTypeId == personEntityTypeId &&
                                         a.Key == "GivingEnvelopeNumber")
                                  .Select(a => a.Id)
                                  .FirstOrDefault();

                    // Get the binary file type for contribution images
                    var binaryFileType = new BinaryFileTypeService(rockContext).Get(Rock.SystemGuid.BinaryFiletype.CONTRIBUTION_IMAGE.AsGuid());
                    if (binaryFileType != null)
                    {
                        binaryFileTypeId = binaryFileType.Id;
                    }
                }
            }

            // Initialize the status variables
            int matchCount   = 0;
            int unmatchCount = 0;
            int errorCount   = 0;

            var allErrorMessages = new List <string>();

            // Process each transaction
            foreach (var node in xml.Root.Descendants().Where(n => n.Name == "Gift"))
            {
                var errorMessages = new List <string>();

                var status = ProcessTransaction(node, batchId, attributeId, binaryFileTypeId, out errorMessages);

                switch (status)
                {
                case ProcessStatus.Matched: matchCount++; break;

                case ProcessStatus.Unmatched: unmatchCount++; break;

                case ProcessStatus.Error: errorCount++; break;
                }

                allErrorMessages.AddRange(errorMessages);

                // Update progress using signalR
                progress++;
                int percentage = (progress * 100) / total.Value;
                _hubContext.Clients.All.receiveNotification(signalREventName, percentage.ToString("N0"));
            }

            // update success message to indicate the txns that were updated
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("<li>{0:N0} {1} processed.</li>", total.Value, "transaction".PluralizeIf(total.Value > 1));
            sb.AppendFormat("<li>{0:N0} {1} matched to an existing person.</li>", matchCount,
                            (matchCount == 1 ? "transaction was" : "transactions were"));
            sb.AppendFormat("<li>{0:N0} {1} NOT matched to an existing person.</li>", unmatchCount,
                            (unmatchCount == 1 ? "transaction was" : "transactions were"));
            if (errorCount > 0)
            {
                sb.AppendFormat("<li>{0:N0} {1} NOT imported due to error during import (see errors below).</li>", errorCount,
                                (errorCount == 1 ? "transaction was" : "transactions were"));
            }

            using (var rockContext = new RockContext())
            {
                var batch = new FinancialBatchService(rockContext).Get(batchId.Value);
                if (batch != null)
                {
                    // update batch control amount
                    batch.ControlAmount += _totalAmount;
                    rockContext.SaveChanges();

                    // Add link to batch
                    var qryParam = new Dictionary <string, string>();
                    qryParam.Add("batchId", batchId.ToString());
                    string batchUrl  = LinkedPageUrl("BatchDetailPage", qryParam);
                    string batchLink = string.Format("<a href='{0}'>{1}</a>", batchUrl, batch.Name);

                    int    totalTransactions = matchCount + unmatchCount;
                    string summaryformat     = totalTransactions == 1 ?
                                               "<li>{0} transaction of {1} was added to the {2} batch.</li>" :
                                               "<li>{0} transactions totaling {1} were added to the {2} batch</li>";
                    sb.AppendFormat(summaryformat, totalTransactions.ToString("N0"), _totalAmount.FormatAsCurrency(), batchLink);
                }
            }

            nbSuccess.Text = string.Format("<ul>{0}</ul>", sb.ToString());

            // Display any errors that occurred
            if (allErrorMessages.Any())
            {
                StringBuilder sbErrors = new StringBuilder();
                foreach (var errorMsg in allErrorMessages)
                {
                    sbErrors.AppendFormat("<li>{0}</li>", errorMsg);
                }

                nbErrors.Text    = string.Format("<ul>{0}</ul>", sbErrors.ToString());
                nbErrors.Visible = true;
            }
            else
            {
                nbErrors.Visible = false;
            }

            ShowResults();
        }
Пример #36
0
        /// <summary>
        /// Shows the edit details.
        /// </summary>
        /// <param name="financialBatch">The financial batch.</param>
        protected void ShowEdit( FinancialBatch financialBatch )
        {
            if ( financialBatch.Id > 0 )
            {
                lTitle.Text = ActionTitle.Edit( FinancialBatch.FriendlyTypeName ).FormatAsHtmlTitle();
            }
            else
            {
                lTitle.Text = ActionTitle.Add( FinancialBatch.FriendlyTypeName ).FormatAsHtmlTitle();
            }

            SetEditMode( true );

            ddlStatus.BindToEnum( typeof( BatchStatus ) );
            hfBatchId.Value = financialBatch.Id.ToString();
            tbName.Text = financialBatch.Name;
            tbControlAmount.Text = financialBatch.ControlAmount.ToString();
            ddlStatus.SelectedIndex = (int)(BatchStatus)financialBatch.Status;
            campCampus.Campuses = new CampusService( new RockContext() ).Queryable().OrderBy( a => a.Name ).ToList();
            if ( financialBatch.CampusId.HasValue )
            {
                campCampus.SelectedCampusId = financialBatch.CampusId;
            }

            drpBatchDate.LowerValue = financialBatch.BatchStartDateTime;
            drpBatchDate.UpperValue = financialBatch.BatchEndDateTime;
        }
Пример #37
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;
                }
            }
        }
Пример #38
0
        /// <summary>
        /// Shows the financial batch summary.
        /// </summary>
        /// <param name="financialBatch">The financial batch.</param>
        private void ShowSummary( FinancialBatch financialBatch )
        {
            string batchDate = string.Empty;
            if ( financialBatch.BatchStartDateTime != null )
            {
                batchDate = financialBatch.BatchStartDateTime.Value.ToShortDateString();
            }

            lTitle.Text = string.Format( "{0} <small>{1}</small>", financialBatch.Name.FormatAsHtmlTitle(), batchDate );

            SetEditMode( false );

            string campus = string.Empty;
            if ( financialBatch.CampusId.HasValue )
            {
                campus = financialBatch.Campus.ToString();
            }

            hfBatchId.SetValue( financialBatch.Id );
            lDetailsLeft.Text = new DescriptionList()
                .Add( "Title", financialBatch.Name )
                .Add( "Status", financialBatch.Status.ToString() )
                .Add( "Batch Start Date", Convert.ToDateTime( financialBatch.BatchStartDateTime ).ToString( "MM/dd/yyyy" ) )
                .Html;

            lDetailsRight.Text = new DescriptionList()
                .Add( "Control Amount", financialBatch.ControlAmount.ToString() )
                .Add( "Campus", campus )
                .Add( "Batch End Date", Convert.ToDateTime( financialBatch.BatchEndDateTime ).ToString( "MM/dd/yyyy" ) )
                .Html;
        }
Пример #39
0
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e)
        {
            var            rockContext  = new RockContext();
            var            batchService = new FinancialBatchService(rockContext);
            FinancialBatch batch        = null;

            int batchId = hfBatchId.Value.AsInteger();

            if (batchId == 0)
            {
                batch = new FinancialBatch();
                batchService.Add(batch);
            }
            else
            {
                batch = batchService.Get(batchId);
            }

            if (batch != null)
            {
                batch.Name               = tbName.Text;
                batch.Status             = (BatchStatus)ddlStatus.SelectedIndex;
                batch.CampusId           = campCampus.SelectedCampusId;
                batch.BatchStartDateTime = dtpStart.SelectedDateTimeIsBlank ? null : dtpStart.SelectedDateTime;
                if (dtpEnd.SelectedDateTimeIsBlank && batch.BatchStartDateTime.HasValue)
                {
                    batch.BatchEndDateTime = batch.BatchStartDateTime.Value.AddDays(1);
                }
                else
                {
                    batch.BatchEndDateTime = dtpEnd.SelectedDateTimeIsBlank ? null : dtpEnd.SelectedDateTime;
                }
                batch.ControlAmount        = tbControlAmount.Text.AsDecimal();
                batch.AccountingSystemCode = tbAccountingCode.Text;

                if (!Page.IsValid || !batch.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                rockContext.SaveChanges();

                if (batchId == 0)
                {
                    // If created a new batch, navigate to same page so that transaction list displays correctly
                    var pageReference = CurrentPageReference;
                    pageReference.Parameters.AddOrReplace("batchId", batch.Id.ToString());
                    NavigateToPage(pageReference);
                }
                else
                {
                    hfBatchId.SetValue(batch.Id);

                    // Requery the batch to support EF navigation properties
                    var savedBatch = GetBatch(batch.Id);

                    ShowReadonlyDetails(savedBatch);
                }
            }
        }
Пример #40
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapBatch(CSVInstance csvData)
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches        = new List <FinancialBatch>();

            int completed = 0;

            ReportProgress(0, string.Format("Verifying batch import ({0:N0} already exist).", ImportedBatches.Count));
            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string batchIdKey = row[BatchID];
                int?   batchId    = batchIdKey.AsType <int?>();
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey             = batchId.ToString();
                    batch.ForeignId            = batchId;
                    batch.Note                 = string.Empty;
                    batch.Status               = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row[BatchName] as string;
                    if (name != null)
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    string   batchDateKey = row[BatchDate];
                    DateTime?batchDate    = batchDateKey.AsType <DateTime?>();
                    if (batchDate != null)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;
                    }

                    string  amountKey = row[BatchAmount];
                    decimal?amount    = amountKey.AsType <decimal?>();
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, string.Format("{0:N0} batches imported.", completed));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);
                        newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime        = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status        = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name          = string.Format("Default Batch (Imported {0})", ImportDateTime);
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey    = "0";
                defaultBatch.ForeignId     = 0;

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, string.Format("Finished batch import: {0:N0} batches imported.", completed));
            return(completed);
        }
Пример #41
0
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e )
        {
            var rockContext = new RockContext();
            var batchService = new FinancialBatchService( rockContext );
            FinancialBatch batch = null;

            int batchId = hfBatchId.Value.AsInteger();
            if ( batchId == 0 )
            {
                batch = new FinancialBatch();
                batchService.Add( batch );
            }
            else
            {
                batch = batchService.Get( batchId );
            }

            if ( batch != null )
            {
                batch.Name = tbName.Text;
                batch.Status = (BatchStatus)ddlStatus.SelectedIndex;
                batch.CampusId = campCampus.SelectedCampusId;
                batch.BatchStartDateTime = dtpStart.SelectedDateTimeIsBlank ? null : dtpStart.SelectedDateTime;
                if ( dtpEnd.SelectedDateTimeIsBlank && batch.BatchStartDateTime.HasValue )
                {
                    batch.BatchEndDateTime = batch.BatchStartDateTime.Value.AddDays( 1 );
                }
                else
                {
                    batch.BatchEndDateTime = dtpEnd.SelectedDateTimeIsBlank ? null : dtpEnd.SelectedDateTime;
                }
                batch.ControlAmount = tbControlAmount.Text.AsDecimal();
                batch.AccountingSystemCode = tbAccountingCode.Text;

                if ( !Page.IsValid || !batch.IsValid )
                {
                    // Controls will render the error messages
                    return;
                }

                rockContext.SaveChanges();
                hfBatchId.SetValue( batch.Id );

                // Requery the batch to support EF navigation properties
                var savedBatch = GetBatch( batch.Id );

                ShowReadonlyDetails( savedBatch );
            }
        }
Пример #42
0
        /// <summary>
        /// Gets the specified name prefix.
        /// </summary>
        /// <param name="namePrefix">The name prefix.</param>
        /// <param name="currencyType">Type of the currency.</param>
        /// <param name="creditCardType">Type of the credit card.</param>
        /// <param name="transactionDate">The transaction date.</param>
        /// <param name="batchTimeOffset">The batch time offset.</param>
        /// <param name="batches">The batches.</param>
        /// <returns></returns>
        public FinancialBatch Get( string namePrefix, DefinedValueCache currencyType, DefinedValueCache creditCardType,
            DateTime transactionDate, TimeSpan batchTimeOffset, List<FinancialBatch> batches = null )
        {
            // Use the credit card type's batch name suffix, or if that doesn't exist, use the currency type value
            string ccSuffix = string.Empty;
            
            if (creditCardType != null )
            {
                ccSuffix = creditCardType.GetAttributeValue( "BatchNameSuffix" );
                if ( string.IsNullOrWhiteSpace( ccSuffix ) )
                {
                    ccSuffix = creditCardType.Value;
                }
            }

            if ( string.IsNullOrWhiteSpace( ccSuffix ) && currencyType != null )
            {
                ccSuffix = currencyType.Value;
            }

            string batchName = namePrefix.Trim() + ( string.IsNullOrWhiteSpace( ccSuffix ) ? "" : " " + ccSuffix );

            FinancialBatch batch = null;

            // If a list of batches was passed, search those first
            if ( batches != null )
            {
                batch = batches
                    .Where( b =>
                        b.Status == BatchStatus.Open &&
                        b.BatchStartDateTime <= transactionDate &&
                        b.BatchEndDateTime > transactionDate &&
                        b.Name == batchName )
                    .OrderByDescending( b => b.BatchStartDateTime )
                    .FirstOrDefault();

                if ( batch != null )
                {
                    return batch;
                }
            }

            // If batch was not found in existing list, search database
            batch = Queryable()
                .Where( b =>
                    b.Status == BatchStatus.Open &&
                    b.BatchStartDateTime <= transactionDate &&
                    b.BatchEndDateTime > transactionDate &&
                    b.Name == batchName )
                .OrderByDescending( b => b.BatchStartDateTime )
                .FirstOrDefault();

            // If still no batch, create a new one
            if ( batch == null )
            {
                batch = new FinancialBatch();
                batch.Guid = Guid.NewGuid();
                batch.Name = batchName;
                batch.Status = BatchStatus.Open;
                batch.BatchStartDateTime = transactionDate.Date.Add( batchTimeOffset );
                if ( batch.BatchStartDateTime > transactionDate )
                {
                    batch.BatchStartDateTime.Value.AddDays( -1 );
                }

                batch.BatchEndDateTime = batch.BatchStartDateTime.Value.AddDays( 1 );
                batch.ControlAmount = 0;
                Add( batch );
            }

            // Add the batch to the list
            if ( batches != null )
            {
                batches.Add( batch );
            }

            return batch;
        }
Пример #43
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 campus = string.Empty;
                if ( batch.Campus != null )
                {
                    campus = batch.Campus.ToString();
                }

                decimal txnTotal = batch.Transactions.Sum( t => (decimal?)( t.TransactionDetails.Sum( d => (decimal?)d.Amount ) ?? 0.0M ) ) ?? 0.0M;
                decimal variance = txnTotal - batch.ControlAmount;
                string amountFormat = string.Format( "{0} / {1} / " + ( variance == 0.0M ? "{2}" : "<span class='label label-danger'>{2}</span>" ),
                    txnTotal.ToString( "C2" ), batch.ControlAmount.ToString( "C2" ), variance.ToString( "C2" ) );

                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;
                //Account Summary
                gAccounts.DataSource = batch.Transactions
                    .SelectMany( t => t.TransactionDetails )
                    .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 = batch.Transactions
                    .Select( t => new
                    {
                        CurrencyId = t.FinancialPaymentDetail != null && t.FinancialPaymentDetail.CurrencyTypeValue != null ? t.FinancialPaymentDetail.CurrencyTypeValue.Id : 0,
                        CurrencyName = t.FinancialPaymentDetail != null && t.FinancialPaymentDetail.CurrencyTypeValue != null ? t.FinancialPaymentDetail.CurrencyTypeValue.Value : "None",
                        TotalAmount = t.TotalAmount
                    } )
                    .GroupBy( c => new
                    {
                        c.CurrencyId,
                        c.CurrencyName
                    } )
                    .Select( s => new
                    {
                        Id = s.Key.CurrencyId,
                        Name = s.Key.CurrencyName,
                        Amount = s.Sum( a => (decimal?)a.TotalAmount ) ?? 0.0M
                    } )
                    .OrderBy( s => s.Name )
                    .ToList();
                gCurrencyTypes.DataBind();
            }
        }
Пример #44
0
        /// <summary>Process all transactions (payments) from Service Reef.</summary>
        /// <param name="message">The message that is returned depending on the result.</param>
        /// <param name="state">The state of the process.</param>
        /// <returns><see cref="WorkerResultStatus"/></returns>
        public void Execute(IJobExecutionContext context)
        {
            RockContext                 dbContext                   = new RockContext();
            FinancialBatchService       financialBatchService       = new FinancialBatchService(dbContext);
            PersonService               personService               = new PersonService(dbContext);
            PersonAliasService          personAliasService          = new PersonAliasService(dbContext);
            FinancialAccountService     financialAccountService     = new FinancialAccountService(dbContext);
            FinancialAccountService     accountService              = new FinancialAccountService(dbContext);
            FinancialTransactionService financialTransactionService = new FinancialTransactionService(dbContext);
            FinancialGatewayService     financialGatewayService     = new FinancialGatewayService(dbContext);
            DefinedValueService         definedValueService         = new DefinedValueService(dbContext);
            DefinedTypeService          definedTypeService          = new DefinedTypeService(dbContext);
            TransactionService          transactionService          = new TransactionService(new PayPalReporting.Data.PayPalReportingContext());

            // Get the datamap for loading attributes
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            String warnings = string.Empty;

            FinancialBatch batch       = null;
            Double         totalAmount = 0;
            var            total       = 1;
            var            processed   = 0;

            try
            {
                DateRange dateRange = Rock.Web.UI.Controls.SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||");

                String            SRApiKey          = Encryption.DecryptString(dataMap.GetString("ServiceReefAPIKey"));
                String            SRApiSecret       = Encryption.DecryptString(dataMap.GetString("ServiceReefAPISecret"));
                String            SRApiUrl          = dataMap.GetString("ServiceReefAPIURL");
                DefinedValueCache transactionSource = DefinedValueCache.Read(dataMap.GetString("TransactionSource").AsGuid(), dbContext);
                DefinedValueCache connectionStatus  = DefinedValueCache.Read(dataMap.GetString("ConnectionStatus").AsGuid(), dbContext);
                DefinedValueCache contribution      = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION);

                // Setup some lookups
                DefinedTypeCache        creditCards = DefinedTypeCache.Read(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE.AsGuid(), dbContext);
                DefinedTypeCache        tenderType  = DefinedTypeCache.Get(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE.AsGuid(), dbContext);
                FinancialAccount        specialFund = accountService.Get(dataMap.GetString("Account").AsGuid());
                FinancialGateway        gateway     = financialGatewayService.Get(dataMap.GetString("FinancialGateway").AsGuid());
                List <FinancialAccount> trips       = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList();

                // Get the trips
                DefinedValueCache serviceReefAccountType = DefinedValueCache.Get(dataMap.Get("ServiceReefAccountType").ToString().AsGuid());

                // Setup the ServiceReef API Client
                var client = new RestClient(SRApiUrl);
                client.Authenticator = new HMACAuthenticator(SRApiKey, SRApiSecret);

                // Get all payments from ServiceReef
                var request = new RestRequest("v1/payments", Method.GET);
                request.AddParameter("pageSize", 100);
                if (dateRange.Start.HasValue)
                {
                    request.AddParameter("startDate", dateRange.Start.Value.ToString("o"));
                }
                if (dateRange.End.HasValue)
                {
                    request.AddParameter("endDate", dateRange.End.Value.ToString("o"));
                }
                request.AddParameter("page", 1);

                while (total > processed)
                {
                    var response = client.Execute <Contracts.Payments>(request);
                    if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    {
                        throw new Exception("ServiceReef API Response: " + response.StatusDescription + " Content Length: " + response.ContentLength);
                    }
                    if (response.Data != null && response.Data.PageInfo != null)
                    {
                        total = response.Data.PageInfo.TotalRecords;
                        foreach (Contracts.Payments.Result result in response.Data.Results)
                        {
                            // Process the transaction
                            if (result.PaymentProcessorTransactionId != null)
                            {
                                if (result.FirstName == null || result.LastName == null)
                                {
                                    warnings += "Missing Firstname/Lastname for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine;
                                    processed++;
                                    continue;
                                }
                                FinancialAccount trip = null;
                                // Make sure we have a sub-account to go with this transaction
                                if (result.EventId > 0)
                                {
                                    trip = trips.Where(t => t.GlCode == result.EventCode && t.Url == result.EventUrl).FirstOrDefault();
                                }
                                if (trip == null)
                                {
                                    if (result.EventCode == null)
                                    {
                                        warnings += "Event Code is missing on the Service Reef Trip for ServiceReef transaction Id: " + result.TransactionId + Environment.NewLine;
                                        processed++;
                                        continue;
                                    }

                                    // Create the trip subaccount
                                    FinancialAccount tripFA = new FinancialAccount();
                                    tripFA.Name = result.EventName;
                                    // Name is limited to 50
                                    if (tripFA.Name.Length > 50)
                                    {
                                        tripFA.Name = tripFA.Name.Substring(0, 50);
                                    }
                                    tripFA.Description = "Service Reef Event.  Name: " + result.EventName + " ID: " + result.EventId;
                                    tripFA.GlCode      = result.EventCode;
                                    tripFA.Url         = result.EventUrl;
                                    tripFA.PublicName  = result.EventName;
                                    // Public Name is limited to 50
                                    if (tripFA.PublicName.Length > 50)
                                    {
                                        tripFA.PublicName = tripFA.PublicName.Substring(0, 50);
                                    }
                                    tripFA.IsTaxDeductible    = true;
                                    tripFA.IsPublic           = false;
                                    tripFA.ParentAccountId    = specialFund.Id;
                                    tripFA.Order              = specialFund.Order + 1;
                                    tripFA.AccountTypeValueId = serviceReefAccountType.Id;
                                    // Figure out what order it should be;
                                    foreach (FinancialAccount tmpTrip in trips)
                                    {
                                        if (tmpTrip.Name.CompareTo(tripFA.Name) < 0)
                                        {
                                            tripFA.Order++;
                                        }
                                    }

                                    financialAccountService.Add(tripFA);

                                    // Now save the trip
                                    dbContext.SaveChanges();
                                    // Increment all the rest of the Orders
                                    financialAccountService.Queryable().Where(fa => fa.Order >= tripFA.Order && fa.Id != tripFA.Id).ToList().ForEach(c => c.Order++);
                                    dbContext.SaveChanges();
                                    trips = financialAccountService.Queryable().Where(fa => fa.ParentAccountId == specialFund.Id).OrderBy(fa => fa.Order).ToList();
                                    trip  = tripFA;
                                }

                                FinancialTransaction tran = financialTransactionService.Queryable().Where(tx => tx.TransactionCode == result.PaymentProcessorTransactionId).FirstOrDefault();

                                // We haven't processed this before so get busy!
                                if (tran == null)
                                {
                                    tran = new FinancialTransaction();
                                    tran.FinancialPaymentDetail = new FinancialPaymentDetail();
                                    if (result.Type == "CreditCard")
                                    {
                                        tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id;
                                    }
                                    else
                                    {
                                        tran.TransactionTypeValueId = tenderType.DefinedValues.Where(t => t.Value == "Credit Card").FirstOrDefault().Id;
                                    }

                                    Person person = null;
                                    // Find the person this transaction belongs to
                                    // 1. First start by determining whether this was a person
                                    //    paying their application fee or contributing to themselves
                                    //    because then we can just use their member info
                                    if (result.UserId > 0 &&
                                        result.DonatedToUserId == result.UserId &&
                                        result.DonatedToFirstName == result.FirstName &&
                                        result.DonatedToLastName == result.LastName)
                                    {
                                        var memberRequest = new RestRequest("v1/members/{userId}", Method.GET);
                                        memberRequest.AddUrlSegment("userId", result.UserId.ToString());
                                        var memberResult = client.Execute <Contracts.Member>(memberRequest);
                                        if (memberResult.Data != null && memberResult.Data.ArenaId > 0)
                                        {
                                            try
                                            {
                                                Person personMatch = personAliasService.Queryable().Where(pa => pa.AliasPersonId == memberResult.Data.ArenaId).Select(pa => pa.Person).FirstOrDefault();
                                                if (personMatch == null)
                                                {
                                                    throw new Exception("Person not found: " + memberResult.Data.ArenaId);
                                                }
                                                person = personMatch;
                                            } catch (Exception e)
                                            {
                                                warnings += "Loading the person failed transaction id " + result.TransactionId + " for " + result.FirstName + " " + result.LastName + " with the following error: " + e.Message + Environment.NewLine;
                                                processed++;
                                                continue;
                                            }
                                        }
                                    }
                                    // 2. If we didn't get a person match via their Alias Id
                                    //    then just use the standard person match logic
                                    if (person == null)
                                    {
                                        String street1    = null;
                                        String postalCode = null;
                                        if (result.Address != null)
                                        {
                                            street1    = result.Address.Address1;
                                            postalCode = result.Address.Zip;
                                        }
                                        List <Person> matches = personService.GetByMatch(result.FirstName.Trim(), result.LastName.Trim(), null, result.Email, null, street1, postalCode).ToList();

                                        if (matches.Count > 1)
                                        {
                                            // Find the oldest member record in the list
                                            person = matches.Where(p => p.ConnectionStatusValue.Value == "Member").OrderBy(p => p.Id).FirstOrDefault();
                                            if (person == null)
                                            {
                                                // Find the oldest attendee record in the list
                                                person = matches.Where(p => p.ConnectionStatusValue.Value == "Attendee").OrderBy(p => p.Id).FirstOrDefault();
                                                if (person == null)
                                                {
                                                    person = matches.OrderBy(p => p.Id).First();
                                                }
                                            }
                                        }
                                        else if (matches.Count == 1)
                                        {
                                            person = matches.First();
                                        }
                                        else
                                        {
                                            // Create the person
                                            person           = new Person();
                                            person.FirstName = result.FirstName.Trim();
                                            person.LastName  = result.LastName.Trim();
                                            if (result.Email.IsValidEmail())
                                            {
                                                person.Email = result.Email.Trim();
                                            }
                                            person.RecordTypeValueId       = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid()).Id;
                                            person.ConnectionStatusValueId = connectionStatus.Id;
                                            person.RecordStatusValueId     = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid()).Id;
                                            Group         family   = PersonService.SaveNewPerson(person, dbContext);
                                            GroupLocation location = new GroupLocation();
                                            location.GroupLocationTypeValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME).Id;
                                            location.Location = new Location()
                                            {
                                                Street1    = result.Address.Address1,
                                                Street2    = result.Address.Address2,
                                                City       = result.Address.City,
                                                State      = result.Address.State,
                                                PostalCode = result.Address.Zip,
                                                Country    = result.Address.Country
                                            };
                                            family.CampusId = CampusCache.All().FirstOrDefault().Id;
                                            family.GroupLocations.Add(location);
                                            dbContext.SaveChanges();
                                        }
                                    }

                                    // Get details about the transaction from our PayPal report table
                                    Transaction tx = transactionService.Get(result.PaymentProcessorTransactionId);
                                    if (tx != null)
                                    {
                                        if (tx.TenderType.Contains("ACH"))
                                        {
                                            result.Type   = "ACH";
                                            result.Method = null;
                                        }
                                        else
                                        {
                                            result.Type   = "Credit Card";
                                            result.Method = tx.TenderType;
                                        }
                                    }
                                    else
                                    {
                                        // Defaults
                                        result.Type   = "Credit Card";
                                        result.Method = "Visa";

                                        warnings += "Unable to find transaction in _org_secc_PaypalReporting_Transaction table: " + result.TransactionId + Environment.NewLine;
                                    }

                                    // If we don't have a batch, create one
                                    if (batch == null)
                                    {
                                        batch = new FinancialBatch();
                                        batch.BatchStartDateTime = result.Date;
                                        batch.BatchEndDateTime   = DateTime.Now;
                                        batch.Name   = "Service Reef Payments";
                                        batch.Status = BatchStatus.Open;
                                        financialBatchService.Add(batch);
                                        dbContext.SaveChanges();
                                    }

                                    // Complete the FinancialTransaction
                                    tran.AuthorizedPersonAliasId = person.PrimaryAliasId;
                                    tran.BatchId             = batch.Id;
                                    tran.Summary             = "F" + specialFund.Id + ":$" + result.Amount.ToString();
                                    tran.TransactionDateTime = result.Date;
                                    tran.FinancialGatewayId  = gateway.Id;

                                    FinancialTransactionDetail financialTransactionDetail = new FinancialTransactionDetail();
                                    financialTransactionDetail.AccountId = trip.Id;
                                    financialTransactionDetail.Amount    = result.Amount.ToString().AsDecimal();
                                    tran.TransactionDetails.Add(financialTransactionDetail);
                                    tran.TransactionTypeValueId = contribution.Id;

                                    tran.FinancialPaymentDetail = new FinancialPaymentDetail();
                                    tran.FinancialPaymentDetail.CurrencyTypeValueId = tenderType.DefinedValues.Where(type => type.Value.ToLower() == result.Type.ToLower()).FirstOrDefault().Id;
                                    if (result.Method != null)
                                    {
                                        tran.FinancialPaymentDetail.CreditCardTypeValueId = creditCards.DefinedValues.Where(card => card.Value.ToLower() == result.Method.ToLower()).FirstOrDefault().Id;
                                    }
                                    tran.TransactionCode   = result.PaymentProcessorTransactionId;
                                    tran.SourceTypeValueId = transactionSource.Id;

                                    financialTransactionService.Add(tran);
                                    dbContext.SaveChanges();

                                    totalAmount += result.Amount;
                                }
                            }
                            processed++;
                        }
                    }
                    else
                    {
                        total = 0;
                    }
                    // Update the page number for the next request
                    var pageParam = request.Parameters.Where(p => p.Name == "page").FirstOrDefault();
                    pageParam.Value = (int)pageParam.Value + 1;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("ServiceReef Job Failed", ex);
            } finally
            {
                if (batch != null && totalAmount > 0)
                {
                    batch.ControlAmount = (Decimal)totalAmount;
                }
                dbContext.SaveChanges();
            }
            if (warnings.Length > 0)
            {
                throw new Exception(warnings);
            }
            context.Result = "Successfully imported " + processed + " transactions.";
        }
Пример #45
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="batchId">The financial batch identifier.</param>
        public void ShowDetail(int batchId)
        {
            FinancialBatch batch = null;

            bool editAllowed = true;

            if (!batchId.Equals(0))
            {
                batch = GetBatch(batchId);
                if (batch != null)
                {
                    editAllowed = batch.IsAuthorized(Authorization.EDIT, CurrentPerson);
                    pdAuditDetails.SetEntity(batch, ResolveRockUrl("~"));
                }
            }

            if (batch == null)
            {
                batch = new FinancialBatch {
                    Id = 0, Status = BatchStatus.Open
                };

                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            hfBatchId.Value = batch.Id.ToString();

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if (!editAllowed || !IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(FinancialBatch.FriendlyTypeName);
            }
            else if (batch.Status == BatchStatus.Closed)
            {
                if (!batch.IsAuthorized("ReopenBatch", this.CurrentPerson))
                {
                    readOnly = true;
                    nbEditModeMessage.Text = "Batch is closed and requires authorization to re-open before editing.";
                }
            }

            if (readOnly)
            {
                lbEdit.Visible = false;
                ShowReadonlyDetails(batch);
            }
            else
            {
                lbEdit.Visible = true;
                if (batch.Id > 0)
                {
                    ShowReadonlyDetails(batch);
                }
                else
                {
                    ShowEditDetails(batch);
                }
            }

            lbSave.Visible = !readOnly;
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            bool promptWithFilter = true;
            var contextEntity = this.ContextEntity();
            if ( contextEntity != null )
            {
                if ( contextEntity is Person )
                {
                    _person = contextEntity as Person;
                    promptWithFilter = false;
                }
                else if ( contextEntity is FinancialBatch )
                {
                    _batch = contextEntity as FinancialBatch;
                    gfTransactions.Visible = false;
                    promptWithFilter = false;
                }
                else if ( contextEntity is FinancialScheduledTransaction )
                {
                    _scheduledTxn = contextEntity as FinancialScheduledTransaction;
                    gfTransactions.Visible = false;
                    promptWithFilter = false;
                }
            }

            if ( !Page.IsPostBack )
            {
                BindFilter();

                if ( promptWithFilter && gfTransactions.Visible )
                {
                    //// NOTE: Special Case for this List Block since there could be a very large number of transactions:
                    //// If the filter is shown and we aren't filtering by anything else, don't automatically populate the grid. Wait for them to hit apply on the filter
                    gfTransactions.Show();
                }
                else
                {
                    BindGrid();
                }
            }

            if ( _canEdit && _batch != null )
            {
                string script = string.Format( @"
            $('#{0}').change(function( e ){{
            var count = $(""#{1} input[id$='_cbSelect_0']:checked"").length;
            if (count == 0) {{
            eval({2});
            }}
            else
            {{
            var $ddl = $(this);
            if ($ddl.val() != '') {{
                Rock.dialogs.confirm('Are you sure you want to move the selected transactions to a new batch (the control amounts on each batch will be updated to reflect the moved transaction\'s amounts)?', function (result) {{
                    if (result) {{
                        eval({2});
                    }}
                    $ddl.val('');
                }});
            }}
            }}
            }});
            ", _ddlMove.ClientID, gTransactions.ClientID, Page.ClientScript.GetPostBackEventReference( this, "MoveTransactions" ) );
                ScriptManager.RegisterStartupScript( _ddlMove, _ddlMove.GetType(), "moveTransaction", script, true );
            }
        }
Пример #47
0
        /// <summary>
        /// Shows the edit details.
        /// </summary>
        /// <param name="batch">The financial batch.</param>
        protected void ShowEditDetails(FinancialBatch batch)
        {
            if (batch == null || batch.Id == 0)
            {
                // if the "BatchNames" configuration setting is set, and this is a new batch present a DropDown of BatchNames instead of a text box
                var batchNamesDefinedTypeGuid = this.GetAttributeValue("BatchNames").AsGuidOrNull();
                ddlBatchName.Visible = false;
                tbName.Visible       = true;

                if (batchNamesDefinedTypeGuid.HasValue)
                {
                    var batchNamesDefinedType = DefinedTypeCache.Read(batchNamesDefinedTypeGuid.Value);
                    if (batchNamesDefinedType != null)
                    {
                        ddlBatchName.BindToDefinedType(batchNamesDefinedType, true, false);
                        if (batchNamesDefinedType.DefinedValues.Any(a => !string.IsNullOrWhiteSpace(a.Value)))
                        {
                            ddlBatchName.Visible = true;
                            tbName.Visible       = false;
                        }
                    }
                }
            }

            if (batch != null)
            {
                hfBatchId.Value = batch.Id.ToString();
                string title = batch.Id > 0 ?
                               ActionTitle.Edit(FinancialBatch.FriendlyTypeName) :
                               ActionTitle.Add(FinancialBatch.FriendlyTypeName);

                SetHeadingInfo(batch, title);

                SetEditMode(true);

                tbName.Text = batch.Name;

                ddlStatus.BindToEnum <BatchStatus>();
                ddlStatus.SelectedIndex = (int)(BatchStatus)batch.Status;
                ddlStatus.Enabled       = true;
                if (batch.Status == BatchStatus.Closed)
                {
                    if (!batch.IsAuthorized("ReopenBatch", this.CurrentPerson))
                    {
                        ddlStatus.Enabled = false;
                    }
                }

                if (batch.IsAutomated == true && batch.Status == BatchStatus.Pending)
                {
                    ddlStatus.Enabled = false;
                }

                campCampus.Campuses = CampusCache.All();
                if (batch.CampusId.HasValue)
                {
                    campCampus.SetValue(batch.CampusId.Value);
                }

                tbControlAmount.Text = batch.ControlAmount.ToString("N2");

                dtpStart.SelectedDateTime = batch.BatchStartDateTime;
                dtpEnd.SelectedDateTime   = batch.BatchEndDateTime;

                tbAccountingCode.Text = batch.AccountingSystemCode;
                tbNote.Text           = batch.Note;

                SetEditableForBatchStatus(ddlStatus.SelectedValueAsEnum <BatchStatus>());
            }
        }
Пример #48
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                RockConfig     rockConfig = RockConfig.Load();
                RockRestClient client     = new RockRestClient(rockConfig.RockBaseUrl);
                client.Login(rockConfig.Username, rockConfig.Password);

                FinancialBatch financialBatch = null;
                if (SelectedFinancialBatchId.Equals(0))
                {
                    financialBatch = new FinancialBatch {
                        Id = 0, Guid = Guid.NewGuid(), Status = BatchStatus.Pending, CreatedByPersonId = LoggedInPerson.Id
                    };
                }
                else
                {
                    financialBatch = client.GetData <FinancialBatch>(string.Format("api/FinancialBatches/{0}", SelectedFinancialBatchId));
                }

                txtBatchName.Text = txtBatchName.Text.Trim();

                financialBatch.Name = txtBatchName.Text;
                Campus selectedCampus = cbCampus.SelectedItem as Campus;
                if (selectedCampus.Id > 0)
                {
                    financialBatch.CampusId = selectedCampus.Id;
                }
                else
                {
                    financialBatch.CampusId = null;
                }

                financialBatch.BatchStartDateTime = dpBatchDate.SelectedDate;

                if (!string.IsNullOrWhiteSpace(txtControlAmount.Text))
                {
                    financialBatch.ControlAmount = decimal.Parse(txtControlAmount.Text.Replace("$", string.Empty));
                }
                else
                {
                    financialBatch.ControlAmount = 0.00M;
                }

                if (financialBatch.Id == 0)
                {
                    client.PostData <FinancialBatch>("api/FinancialBatches/", financialBatch);
                }
                else
                {
                    client.PutData <FinancialBatch>("api/FinancialBatches/", financialBatch);
                }

                if (SelectedFinancialBatchId.Equals(0))
                {
                    // refetch the batch to get the Id if it was just Inserted
                    financialBatch = client.GetDataByGuid <FinancialBatch>("api/FinancialBatches", financialBatch.Guid);

                    SelectedFinancialBatchId = financialBatch.Id;
                }

                LoadFinancialBatchesGrid();

                ShowBatch(false);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }
Пример #49
0
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            nbClosedWarning.Visible = false;
            nbResult.Visible = false;

            var contextEntity = this.ContextEntity();
            if ( contextEntity != null )
            {
                if ( contextEntity is Person )
                {
                    _person = contextEntity as Person;
                }
                else if ( contextEntity is FinancialBatch )
                {
                    _batch = contextEntity as FinancialBatch;
                    gfTransactions.Visible = false;
                }
                else if ( contextEntity is FinancialScheduledTransaction )
                {
                    _scheduledTxn = contextEntity as FinancialScheduledTransaction;
                    gfTransactions.Visible = false;
                }
                else if ( contextEntity is Registration )
                {
                    _registration = contextEntity as Registration;
                    gfTransactions.Visible = false;
                }

            }

            if ( !Page.IsPostBack )
            {
                BindFilter();
                BindGrid();
            }
            else
            {
                ShowDialog();
            }

            if ( _canEdit && _batch != null )
            {
                string script = string.Format( @"
            $('#{0}').change(function( e ){{
            var count = $(""#{1} input[id$='_cbSelect_0']:checked"").length;
            if (count == 0) {{
            {2};
            }}
            else
            {{
            var $ddl = $(this);
            if ($ddl.val() != '') {{
                Rock.dialogs.confirm('Are you sure you want to move the selected transactions to a new batch (the control amounts on each batch will be updated to reflect the moved transaction\'s amounts)?', function (result) {{
                    if (result) {{
                        {2};
                    }}
                    $ddl.val('');
                }});
            }}
            }}
            }});
            ", _ddlMove.ClientID, gTransactions.ClientID, Page.ClientScript.GetPostBackEventReference( this, "MoveTransactions" ) );
                ScriptManager.RegisterStartupScript( _ddlMove, _ddlMove.GetType(), "moveTransaction", script, true );
            }
        }
Пример #50
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapBatch( IQueryable<Row> tableData )
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches = new List<FinancialBatch>();

            int completed = 0;
            int totalRows = tableData.Count();
            int percentage = ( totalRows - 1 ) / 100 + 1;
            ReportProgress( 0, string.Format( "Verifying batch import ({0:N0} found, {1:N0} already exist).", totalRows, ImportedBatches.Count ) );
            foreach ( var row in tableData.Where( r => r != null ) )
            {
                int? batchId = row["BatchID"] as int?;
                if ( batchId != null && !ImportedBatches.ContainsKey( (int)batchId ) )
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey = batchId.ToString();
                    batch.ForeignId = batchId;
                    batch.Note = string.Empty;
                    batch.Status = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row["BatchName"] as string;
                    if ( name != null )
                    {
                        name = name.Trim();
                        batch.Name = name.Left( 50 );
                        batch.CampusId = CampusList.Where( c => name.StartsWith( c.Name ) || name.StartsWith( c.ShortCode ) )
                            .Select( c => (int?)c.Id ).FirstOrDefault();
                    }

                    DateTime? batchDate = row["BatchDate"] as DateTime?;
                    if ( batchDate != null )
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime = batchDate;
                    }

                    decimal? amount = row["BatchAmount"] as decimal?;
                    if ( amount != null )
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add( batch );
                    completed++;
                    if ( completed % percentage < 1 )
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress( percentComplete, string.Format( "{0:N0} batches imported ({1}% complete).", completed, percentComplete ) );
                    }
                    else if ( completed % ReportingNumber < 1 )
                    {
                        SaveFinancialBatches( newBatches );
                        newBatches.ForEach( b => ImportedBatches.Add( (int)b.ForeignId, (int?)b.Id ) );
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if ( !ImportedBatches.ContainsKey( 0 ) )
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name = string.Format( "Default Batch (Imported {0})", ImportDateTime );
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey = "0";
                defaultBatch.ForeignId = 0;

                newBatches.Add( defaultBatch );
            }

            if ( newBatches.Any() )
            {
                SaveFinancialBatches( newBatches );
                newBatches.ForEach( b => ImportedBatches.Add( (int)b.ForeignId, (int?)b.Id ) );
            }

            ReportProgress( 100, string.Format( "Finished batch import: {0:N0} batches imported.", completed ) );
        }
Пример #51
0
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e )
        {
            var rockContext = new RockContext();
            var batchService = new FinancialBatchService( rockContext );
            FinancialBatch batch = null;

            var changes = new List<string>();

            int batchId = hfBatchId.Value.AsInteger();
            if ( batchId == 0 )
            {
                batch = new FinancialBatch();
                batchService.Add( batch );
                changes.Add( "Created the batch" );
            }
            else
            {
                batch = batchService.Get( batchId );
            }

            if ( batch != null )
            {
                History.EvaluateChange( changes, "Batch Name", batch.Name, tbName.Text );
                batch.Name = tbName.Text;

                BatchStatus batchStatus = (BatchStatus)ddlStatus.SelectedIndex;
                History.EvaluateChange( changes, "Status", batch.Status, batchStatus );
                batch.Status = batchStatus;

                CampusCache oldCampus = null;
                if ( batch.CampusId.HasValue )
                {
                    oldCampus = CampusCache.Read( batch.CampusId.Value );
                }

                CampusCache newCampus = null;
                if ( campCampus.SelectedCampusId.HasValue )
                {
                    newCampus = CampusCache.Read( campCampus.SelectedCampusId.Value );
                }

                History.EvaluateChange( changes, "Campus", oldCampus != null ? oldCampus.Name : "None", newCampus != null ? newCampus.Name : "None" );
                batch.CampusId = campCampus.SelectedCampusId;

                DateTime? startDateTime = dtpStart.SelectedDateTimeIsBlank ? null : dtpStart.SelectedDateTime;
                History.EvaluateChange( changes, "Start Date/Time", batch.BatchStartDateTime, startDateTime );
                batch.BatchStartDateTime = startDateTime;

                DateTime? endDateTime;
                if ( dtpEnd.SelectedDateTimeIsBlank && batch.BatchStartDateTime.HasValue )
                {
                    endDateTime = batch.BatchStartDateTime.Value.AddDays( 1 );
                }
                else
                {
                    endDateTime = dtpEnd.SelectedDateTimeIsBlank ? null : dtpEnd.SelectedDateTime;
                }

                History.EvaluateChange( changes, "End Date/Time", batch.BatchEndDateTime, endDateTime );
                batch.BatchEndDateTime = endDateTime;

                decimal controlAmount = tbControlAmount.Text.AsDecimal();
                History.EvaluateChange( changes, "Control Amount", batch.ControlAmount.FormatAsCurrency(), controlAmount.FormatAsCurrency() );
                batch.ControlAmount = controlAmount;

                History.EvaluateChange( changes, "Accounting System Code", batch.AccountingSystemCode, tbAccountingCode.Text );
                batch.AccountingSystemCode = tbAccountingCode.Text;

                History.EvaluateChange( changes, "Notes", batch.Note, tbNote.Text );
                batch.Note = tbNote.Text;

                cvBatch.IsValid = batch.IsValid;
                if ( !Page.IsValid || !batch.IsValid )
                {
                    cvBatch.ErrorMessage = batch.ValidationResults.Select( a => a.ErrorMessage ).ToList().AsDelimited( "<br />" );
                    return;
                }

                rockContext.WrapTransaction( () =>
                {
                    if ( rockContext.SaveChanges() > 0 )
                    {
                        if ( changes.Any() )
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof( FinancialBatch ),
                                Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(),
                                batch.Id,
                                changes );
                        }
                    }
                } );

                if ( batchId == 0 )
                {
                    // If created a new batch, navigate to same page so that transaction list displays correctly
                    var pageReference = CurrentPageReference;
                    pageReference.Parameters.AddOrReplace( "batchId", batch.Id.ToString() );
                    NavigateToPage( pageReference );
                }
                else
                {
                    hfBatchId.SetValue( batch.Id );

                    // Requery the batch to support EF navigation properties
                    var savedBatch = GetBatch( batch.Id );
                    ShowReadonlyDetails( savedBatch );

                    // If there is a batch context item, update the context's properties with new values
                    var contextObjects = new Dictionary<string, object>();
                    foreach ( var contextEntityType in RockPage.GetContextEntityTypes() )
                    {
                        var contextEntity = RockPage.GetCurrentContext( contextEntityType );
                        if ( contextEntity is FinancialBatch )
                        {
                            var contextBatch = contextEntity as FinancialBatch;
                            contextBatch.CopyPropertiesFrom( batch );
                        }
                    }

                    // Then refresh transaction list
                    RockPage.UpdateBlocks( "~/Blocks/Finance/TransactionList.ascx" );
                }
            }
        }
Пример #52
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                RockConfig     rockConfig = RockConfig.Load();
                RockRestClient client     = new RockRestClient(rockConfig.RockBaseUrl);
                client.Login(rockConfig.Username, rockConfig.Password);

                FinancialBatch financialBatch = null;
                if (SelectedFinancialBatch == null || SelectedFinancialBatch.Id == 0)
                {
                    financialBatch = new FinancialBatch {
                        Id = 0, Guid = Guid.NewGuid(), Status = BatchStatus.Pending, CreatedByPersonAliasId = LoggedInPerson.PrimaryAliasId
                    };
                }
                else
                {
                    financialBatch = client.GetData <FinancialBatch>(string.Format("api/FinancialBatches/{0}", SelectedFinancialBatch.Id));
                }

                txtBatchName.Text = txtBatchName.Text.Trim();
                if (string.IsNullOrWhiteSpace(txtBatchName.Text))
                {
                    txtBatchName.Style = this.FindResource("textboxStyleError") as Style;
                    return;
                }
                else
                {
                    txtBatchName.Style = this.FindResource("textboxStyle") as Style;
                }

                financialBatch.Name = txtBatchName.Text;
                Campus selectedCampus = cbCampus.SelectedItem as Campus;
                if (selectedCampus.Id > 0)
                {
                    financialBatch.CampusId = selectedCampus.Id;
                }
                else
                {
                    financialBatch.CampusId = null;
                }

                financialBatch.BatchStartDateTime = dpBatchDate.SelectedDate;

                if (!string.IsNullOrWhiteSpace(txtControlAmount.Text))
                {
                    financialBatch.ControlAmount = decimal.Parse(txtControlAmount.Text.Replace("$", string.Empty));
                }
                else
                {
                    financialBatch.ControlAmount = 0.00M;
                }

                txtNote.Text        = txtNote.Text.Trim();
                financialBatch.Note = txtNote.Text;

                if (financialBatch.Id == 0)
                {
                    client.PostData <FinancialBatch>("api/FinancialBatches/", financialBatch);
                }
                else
                {
                    client.PutData <FinancialBatch>("api/FinancialBatches/", financialBatch, financialBatch.Id);
                }

                if (SelectedFinancialBatch == null || SelectedFinancialBatch.Id == 0)
                {
                    // refetch the batch to get the Id if it was just Inserted
                    financialBatch = client.GetDataByGuid <FinancialBatch>("api/FinancialBatches", financialBatch.Guid);

                    SelectedFinancialBatch = financialBatch;
                }

                LoadFinancialBatchesGrid();
                UpdateBatchUI(financialBatch);

                ShowBatch(false);
            }
            catch (Exception ex)
            {
                ShowException(ex);
            }
        }
Пример #53
0
        /// <summary>
        /// Sets the heading information.
        /// </summary>
        /// <param name="batch">The batch.</param>
        /// <param name="title">The title.</param>
        private void SetHeadingInfo( FinancialBatch batch, string title )
        {
            lTitle.Text = title.FormatAsHtmlTitle();

            hlStatus.Text = batch.Status.ConvertToString();
            switch ( batch.Status )
            {
                case BatchStatus.Pending: hlStatus.LabelType = LabelType.Danger;
                    break;
                case BatchStatus.Open: hlStatus.LabelType = LabelType.Warning;
                    break;
                case BatchStatus.Closed: hlStatus.LabelType = LabelType.Default;
                    break;
            }

            if ( batch.Campus != null )
            {
                hlCampus.Visible = true;
                hlCampus.Text = batch.Campus.Name;
            }
            else
            {
                hlCampus.Visible = false;
            }

            hlBatchId.Text = string.Format( "Batch #{0}", batch.Id.ToString() );
            hlBatchId.Visible = batch.Id != 0;
        }
Пример #54
0
        /// <summary>
        /// Handles the SelectionChanged event of the grdBatches control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void grdBatches_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            FinancialBatch selectedBatch = grdBatches.SelectedValue as FinancialBatch;

            UpdateBatchUI(selectedBatch);
        }
Пример #55
0
        /// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="batchId">The financial batch identifier.</param>
        public void ShowDetail( int batchId )
        {
            FinancialBatch batch = null;

            bool editAllowed = true;

            if ( !batchId.Equals( 0 ) )
            {
                batch = GetBatch( batchId );
                if ( batch != null )
                {
                    editAllowed = batch.IsAuthorized( Authorization.EDIT, CurrentPerson );
                }
            }

            if ( batch == null )
            {
                batch = new FinancialBatch { Id = 0 };
            }

            hfBatchId.Value = batch.Id.ToString();

            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;
            if ( !editAllowed || !IsUserAuthorized( Authorization.EDIT ) )
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( FinancialBatch.FriendlyTypeName );
            }

            if ( readOnly )
            {
                lbEdit.Visible = false;
                ShowReadonlyDetails( batch );
            }
            else
            {
                lbEdit.Visible = true;
                if ( batch.Id > 0 )
                {
                    ShowReadonlyDetails( batch );
                }
                else
                {
                    ShowEditDetails( batch );
                }
            }

            lbSave.Visible = !readOnly;
        }
        /// <summary>
        /// Gets the by name and date.
        /// </summary>
        /// <param name="batchName">Name of the batch.</param>
        /// <param name="transactionDate">The transaction date.</param>
        /// <param name="batchTimeOffset">The batch time offset.</param>
        /// <param name="batches">The batches.</param>
        /// <returns></returns>
        public FinancialBatch GetByNameAndDate( string batchName, DateTime transactionDate, TimeSpan batchTimeOffset, List<FinancialBatch> batches = null )
        {
            FinancialBatch batch = null;

            // If a list of batches was passed, search those first
            if ( batches != null )
            {
                batch = batches
                    .Where( b =>
                        b.Status == BatchStatus.Open &&
                        b.BatchStartDateTime <= transactionDate &&
                        b.BatchEndDateTime > transactionDate &&
                        b.Name == batchName )
                    .OrderByDescending( b => b.BatchStartDateTime )
                    .FirstOrDefault();

                if ( batch != null )
                {
                    return batch;
                }
            }

            // If batch was not found in existing list, search database
            batch = Queryable()
                .Where( b =>
                    b.Status == BatchStatus.Open &&
                    b.BatchStartDateTime <= transactionDate &&
                    b.BatchEndDateTime > transactionDate &&
                    b.Name == batchName )
                .OrderByDescending( b => b.BatchStartDateTime )
                .FirstOrDefault();

            // If still no batch, create a new one
            if ( batch == null )
            {
                batch = new FinancialBatch();
                batch.Guid = Guid.NewGuid();
                batch.Name = batchName;
                batch.Status = BatchStatus.Open;

                var batchStartDateTime = transactionDate.Date.Add( batchTimeOffset );
                if ( batchStartDateTime > transactionDate )
                {
                    batchStartDateTime = batchStartDateTime.AddDays( -1 );
                }
                batch.BatchStartDateTime = batchStartDateTime;
                batch.BatchEndDateTime = batchStartDateTime.AddDays( 1 );

                batch.ControlAmount = 0;
                Add( batch );
            }

            // Add the batch to the list
            if ( batches != null )
            {
                batches.Add( batch );
            }

            return batch;
        }