/// <summary>
        /// Handles the Click event of the lbSaveFinancialBatch 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 lbSaveFinancialBatch_Click(object sender, EventArgs e)
        {
            var            rockContext           = new RockContext();
            var            financialBatchService = new FinancialBatchService(rockContext);
            FinancialBatch financialBatch        = null;

            int financialBatchId = 0;

            if (!string.IsNullOrEmpty(hfBatchId.Value))
            {
                financialBatchId = int.Parse(hfBatchId.Value);
            }

            if (financialBatchId == 0)
            {
                financialBatch = new Rock.Model.FinancialBatch();
                financialBatchService.Add(financialBatch);
            }
            else
            {
                financialBatch = financialBatchService.Get(financialBatchId);
            }

            financialBatch.Name = tbName.Text;
            financialBatch.BatchStartDateTime = drpBatchDate.LowerValue;
            financialBatch.BatchEndDateTime   = drpBatchDate.UpperValue;
            financialBatch.CampusId           = campCampus.SelectedCampusId;
            financialBatch.Status             = (BatchStatus)ddlStatus.SelectedIndex;
            decimal fcontrolamt = 0;

            decimal.TryParse(tbControlAmount.Text, out fcontrolamt);
            financialBatch.ControlAmount = fcontrolamt;

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

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

            foreach (var block in RockPage.RockBlocks.OfType <RockWeb.Blocks.Finance.TransactionList>())
            {
                ((RockWeb.Blocks.Finance.TransactionList)block).RefreshList();
            }

            var savedFinancialBatch = new FinancialBatchService(rockContext).Get(hfBatchId.ValueAsInt());

            ShowSummary(savedFinancialBatch);
        }
Example #2
0
        /// <summary>
        /// Handles the Click event of the btnSaveFinancialBatch 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 btnSaveFinancialBatch_Click(object sender, EventArgs e)
        {
            using (new Rock.Data.UnitOfWorkScope())
            {
                var            financialBatchService = new FinancialBatchService();
                FinancialBatch financialBatch        = null;

                int financialBatchId = 0;
                if (!string.IsNullOrEmpty(hfBatchId.Value))
                {
                    financialBatchId = int.Parse(hfBatchId.Value);
                }

                if (financialBatchId == 0)
                {
                    financialBatch = new Rock.Model.FinancialBatch();
                    financialBatch.CreatedByPersonId = CurrentPersonId.Value;
                    financialBatchService.Add(financialBatch, CurrentPersonId);
                }
                else
                {
                    financialBatch = financialBatchService.Get(financialBatchId);
                }

                financialBatch.Name = tbName.Text;
                financialBatch.BatchStartDateTime = dtBatchDate.LowerValue;
                financialBatch.BatchEndDateTime   = dtBatchDate.UpperValue;
                financialBatch.CampusId           = cpCampus.SelectedCampusId;
                financialBatch.Status             = (BatchStatus)ddlStatus.SelectedIndex;
                decimal fcontrolamt = 0;
                decimal.TryParse(tbControlAmount.Text, out fcontrolamt);
                financialBatch.ControlAmount = fcontrolamt;

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

                RockTransactionScope.WrapTransaction(() =>
                {
                    financialBatchService.Save(financialBatch, CurrentPersonId);
                    hfBatchId.SetValue(financialBatch.Id);
                });
            }

            var savedFinancialBatch = new FinancialBatchService().Get(hfBatchId.ValueAsInt());

            ShowReadOnly(savedFinancialBatch);
        }
        /// <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");
                }
            }
        }
Example #4
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);
                }
            }
        }
        /// <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();
        }
Example #6
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.";
        }
Example #7
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);
                }
            }
        }