Esempio n. 1
0
        public async Task <IActionResult> Register(Register model)
        {
            if (string.IsNullOrEmpty(model.BrainTreePayment.Nonce))
            {
                ModelState.AddModelError("", "incomplete payment information provided");
            }
            else
            {
                try
                {
                    // get model state errors
                    var errors = ModelState.Values.SelectMany(v => v.Errors);

                    // if paying with a credit card the fields for credit card number/cvs/month/year will be invalid because we do not send them to the server
                    // so count the errors on the field validation that do not start with 'card ' (comes from the property attributes in the model class Apply.cs)
                    // TODO validate if this is still needed - all card validation has been removed b/c client side validation requires 'name' properties
                    //      which have been removed for PCI compliance.
                    var errorCount = errors.Count(m => !m.ErrorMessage.StartsWith("card "));
                    var result     = new ServiceResult();
                    if (errorCount == 0)
                    {
                        #region Process Payment
                        var paymentMethod = (PaymentTypeEnum)Enum.Parse(typeof(PaymentTypeEnum), model.BrainTreePayment.PaymentMethod);
                        var phone         = model.Attendee1PhoneNumber;
                        var paymentResult = new ServiceResult();

                        var paymentRequestResult = new ServiceResult();

                        if (paymentMethod == PaymentTypeEnum.Paypal)
                        {
                            paymentResult = _paymentService.SendPayment(model.TotalAmountDue,
                                                                        model.BrainTreePayment.Nonce,
                                                                        true,
                                                                        paymentMethod,
                                                                        model.BrainTreePayment.DeviceData,
                                                                        "golf reg fee",
                                                                        model.CustomerNotes,
                                                                        model.BrainTreePayment.PayeeFirstName,
                                                                        model.BrainTreePayment.PayeeLastName,
                                                                        phone,
                                                                        model.Attendee1EmailAddress);
                        }
                        else
                        {
                            var stateCode = _context.States.First(p => p.Id == model.BrainTreePayment.PayeeAddressStateId).Code;

                            paymentRequestResult = _paymentService.SendPayment(model.TotalAmountDue,
                                                                               model.BrainTreePayment.Nonce,
                                                                               true,
                                                                               paymentMethod,
                                                                               model.BrainTreePayment.DeviceData,
                                                                               "golf reg fee",
                                                                               model.CustomerNotes,
                                                                               model.BrainTreePayment.PayeeFirstName,
                                                                               model.BrainTreePayment.PayeeLastName,
                                                                               model.BrainTreePayment.PayeeAddressStreet1,
                                                                               model.BrainTreePayment.PayeeAddressStreet2,
                                                                               model.BrainTreePayment.PayeeAddressCity,
                                                                               stateCode,
                                                                               model.BrainTreePayment.PayeeAddressPostalCode,
                                                                               "US",
                                                                               phone,
                                                                               model.Attendee1EmailAddress);
                        }

                        if (!paymentRequestResult.IsSuccess)
                        {
                            // TODO: handle failure to pay
                            result.IsSuccess = false;
                            result.Messages.Add("Payment Failure - see below for details: ");
                            result.Messages.AddRange(paymentRequestResult.Messages);

                            _logger.LogError("Golf Registration Fee Payment Failed {@GolfRegFeePaymentErrors}", result.Messages);
                            ModelState.AddModelError("", "Unable to process your payment. Try again, and if the problem persists see your system administrator.");
                            foreach (var error in paymentRequestResult.Messages)
                            {
                                ModelState.AddModelError("", error);
                            }

                            RedirectToAction("Register");
                        }

                        // payment is a success. capture the transaction id from braintree
                        model.BrainTreePayment.BraintreeTransactionId = paymentRequestResult.NewKey;
                        #endregion

                        #region Database

                        var eventId        = new Guid(_systemServices.GetSetting("GolfTournamentId").Value);
                        var registrationId = Guid.NewGuid();

                        var numberOfTickets = 0;
                        if (!string.IsNullOrEmpty(model.Attendee1FirstName))
                        {
                            numberOfTickets += 1;
                        }
                        if (!string.IsNullOrEmpty(model.Attendee2FirstName))
                        {
                            numberOfTickets += 1;
                        }
                        if (!string.IsNullOrEmpty(model.Attendee3FirstName))
                        {
                            numberOfTickets += 1;
                        }
                        if (!string.IsNullOrEmpty(model.Attendee4FirstName))
                        {
                            numberOfTickets += 1;
                        }


                        #region Copy ViewModel to database Model
                        var dbRegistration = new Models.EventRegistration
                        {
                            Id                     = registrationId,
                            EventId                = eventId,
                            AmountPaid             = model.TotalAmountDue,
                            CommentsFromRegistrant = model.CustomerNotes,
                            HasPaid                = true,
                            SubmittedTimestamp     = DateTime.Now,
                            NumberTicketsBought    = numberOfTickets
                        };

                        dbRegistration.EventRegistrationPersons = new List <Models.EventRegistrationPerson>();

                        if (!string.IsNullOrEmpty(model.Attendee1FirstName))
                        {
                            dbRegistration.EventRegistrationPersons.Add(new Models.EventRegistrationPerson
                            {
                                Id                            = 1,
                                Address1                      = model.Attendee1AddressStreet1,
                                Address2                      = model.Attendee1AddressStreet2,
                                AmountPaid                    = model.Attendee1TicketPrice,
                                City                          = model.Attendee1AddressCity,
                                EmailAddress                  = model.Attendee1EmailAddress,
                                EventRegistrationId           = registrationId,
                                EventRegistrationPersonTypeId = int.Parse(model.Attendee1Type),
                                FirstName                     = model.Attendee1FirstName,
                                LastName                      = model.Attendee1LastName,
                                IsPrimaryPerson               = true,
                                FullName                      = model.Attendee1FullName,
                                StatesId                      = model.Attendee1AddressStateId,
                                PhoneNumber                   = model.Attendee1PhoneNumber,
                                ZipCode                       = model.Attendee1AddressPostalCode
                            });
                        }

                        if (!string.IsNullOrEmpty(model.Attendee2FirstName))
                        {
                            dbRegistration.EventRegistrationPersons.Add(new Models.EventRegistrationPerson
                            {
                                Id                            = 2,
                                Address1                      = model.Attendee2AddressStreet1,
                                Address2                      = model.Attendee2AddressStreet2,
                                AmountPaid                    = model.Attendee2TicketPrice,
                                City                          = model.Attendee2AddressCity,
                                EmailAddress                  = model.Attendee2EmailAddress,
                                EventRegistrationId           = registrationId,
                                EventRegistrationPersonTypeId = int.Parse(model.Attendee2Type),
                                FirstName                     = model.Attendee2FirstName,
                                LastName                      = model.Attendee2LastName,
                                IsPrimaryPerson               = false,
                                FullName                      = model.Attendee2FullName,
                                StatesId                      = model.Attendee2AddressStateId,
                                PhoneNumber                   = model.Attendee2PhoneNumber,
                                ZipCode                       = model.Attendee2AddressPostalCode
                            });
                        }

                        if (!string.IsNullOrEmpty(model.Attendee3FirstName))
                        {
                            dbRegistration.EventRegistrationPersons.Add(new Models.EventRegistrationPerson
                            {
                                Id                            = 3,
                                Address1                      = model.Attendee3AddressStreet1,
                                Address2                      = model.Attendee3AddressStreet2,
                                AmountPaid                    = model.Attendee3TicketPrice,
                                City                          = model.Attendee3AddressCity,
                                EmailAddress                  = model.Attendee3EmailAddress,
                                EventRegistrationId           = registrationId,
                                EventRegistrationPersonTypeId = int.Parse(model.Attendee3Type),
                                FirstName                     = model.Attendee3FirstName,
                                LastName                      = model.Attendee3LastName,
                                IsPrimaryPerson               = true,
                                FullName                      = model.Attendee3FullName,
                                StatesId                      = model.Attendee3AddressStateId,
                                PhoneNumber                   = model.Attendee3PhoneNumber,
                                ZipCode                       = model.Attendee3AddressPostalCode
                            });
                        }

                        if (!string.IsNullOrEmpty(model.Attendee4FirstName))
                        {
                            dbRegistration.EventRegistrationPersons.Add(new Models.EventRegistrationPerson
                            {
                                Id                            = 4,
                                Address1                      = model.Attendee4AddressStreet1,
                                Address2                      = model.Attendee4AddressStreet2,
                                AmountPaid                    = model.Attendee4TicketPrice,
                                City                          = model.Attendee4AddressCity,
                                EmailAddress                  = model.Attendee4EmailAddress,
                                EventRegistrationId           = registrationId,
                                EventRegistrationPersonTypeId = int.Parse(model.Attendee4Type),
                                FirstName                     = model.Attendee4FirstName,
                                LastName                      = model.Attendee4LastName,
                                IsPrimaryPerson               = true,
                                FullName                      = model.Attendee4FullName,
                                StatesId                      = model.Attendee4AddressStateId,
                                PhoneNumber                   = model.Attendee4PhoneNumber,
                                ZipCode                       = model.Attendee4AddressPostalCode
                            });
                        }
                        #endregion

                        #region Add to Database
                        _context.Add(dbRegistration);
                        #endregion

                        #region Save to Database and check exceptions
                        try
                        {
                            _logger.LogInformation("Saving golf registration to database: {@dbRegistration}", dbRegistration);
                            var numChanges = _context.SaveChanges();
                            if (numChanges > 0)
                            {
                                result.IsSuccess = true;
                            }
                        }
                        catch (DbUpdateException ex)
                        {
                            _logger.LogError(new EventId(1), ex, "Database Update Exception saving golf registration");
                        }
                        catch (InvalidOperationException ex)
                        {
                            _logger.LogError(new EventId(1), ex, "Invalid Operation Exception saving golf registration");
                        }
                        #endregion

                        #endregion

                        #region Send Emails
                        var groupEmail = _systemServices.GetSetting("Email-Golf").Value;

                        var subject = string.Join(" - ", "[TXHR Web]", "6th Annual Texas Husky Rescue Golf Registration");

                        var bodyText = @" 
Thank you for registering for Texas Husky Rescue's 6th Annual Golf Tournament.  We are very excited for this year's event and we have no doubt you will have a fabulous time.

You will be sent an email closer to the tournament with detailed information.  If you have any questions prior to then, please feel free to email us at [email protected].

Thanks again,
Texas Husky Rescue Golf Committee
1-877-TX-HUSKY (894-8759) (phone/fax)
PO Box 118891, Carrollton, TX 75011
";


                        // Send email to the primary registrant
                        if (model.Attendee1IsAttending)
                        {
                            var emailAppResult = await _emailService.SendEmailAsync(model.Attendee1EmailAddress, groupEmail, groupEmail, subject, bodyText, "golf-registration");
                        }
                        if (model.Attendee2IsAttending)
                        {
                            var emailAppResult = await _emailService.SendEmailAsync(model.Attendee2EmailAddress, groupEmail, groupEmail, subject, bodyText, "golf-registration");
                        }
                        if (model.Attendee3IsAttending)
                        {
                            var emailAppResult = await _emailService.SendEmailAsync(model.Attendee3EmailAddress, groupEmail, groupEmail, subject, bodyText, "golf-registration");
                        }
                        if (model.Attendee4IsAttending)
                        {
                            var emailAppResult = await _emailService.SendEmailAsync(model.Attendee4EmailAddress, groupEmail, groupEmail, subject, bodyText, "golf-registration");
                        }

                        bodyText  = "Golf registration for " + numberOfTickets + " attendees.";
                        bodyText += Environment.NewLine;
                        bodyText += Environment.NewLine;
                        bodyText += "Attendee 1: " + Environment.NewLine;
                        bodyText += "Name: " + model.Attendee1FullName + Environment.NewLine;
                        bodyText += "Address: " + model.Attendee1AddressStreet1 + " " + model.Attendee1AddressStreet2 + ", " + model.Attendee1AddressCity + ", " + model.Attendee1AddressPostalCode + Environment.NewLine;
                        bodyText += "Phone: " + (string.IsNullOrEmpty(model.Attendee1PhoneNumber) ? "not provided" : model.Attendee1PhoneNumber) + Environment.NewLine;
                        bodyText += "Email: " + (string.IsNullOrEmpty(model.Attendee1EmailAddress) ? "not provided" : model.Attendee1EmailAddress) + Environment.NewLine;
                        bodyText += "Mailable?: " + model.Attendee1FutureContact + Environment.NewLine;
                        bodyText += "Attendance Type: " + model.Attendee1Type + Environment.NewLine;
                        bodyText += "Ticket Price: " + model.Attendee1TicketPrice + Environment.NewLine;
                        bodyText += "-------------------------------------------------------------" + Environment.NewLine;
                        if (model.Attendee2IsAttending)
                        {
                            bodyText += "Attendee 2: " + Environment.NewLine;
                            bodyText += "Name: " + model.Attendee2FullName + Environment.NewLine;
                            bodyText += "Address: " + model.Attendee2AddressStreet1 + " " + model.Attendee2AddressStreet2 + ", " + model.Attendee2AddressCity + ", " + model.Attendee2AddressPostalCode + Environment.NewLine;
                            bodyText += "Phone: " + (string.IsNullOrEmpty(model.Attendee2PhoneNumber) ? "not provided" : model.Attendee2PhoneNumber) + Environment.NewLine;
                            bodyText += "Email: " + (string.IsNullOrEmpty(model.Attendee2EmailAddress) ? "not provided" : model.Attendee2EmailAddress) + Environment.NewLine;
                            bodyText += "Mailable?: " + model.Attendee2FutureContact + Environment.NewLine;
                            bodyText += "Attendance Type: " + model.Attendee2Type + Environment.NewLine;
                            bodyText += "Ticket Price: " + model.Attendee2TicketPrice + Environment.NewLine;
                            bodyText += "-------------------------------------------------------------" + Environment.NewLine;
                        }
                        if (model.Attendee3IsAttending)
                        {
                            bodyText += "Attendee 3: " + Environment.NewLine;
                            bodyText += "Name: " + model.Attendee3FullName + Environment.NewLine;
                            bodyText += "Address: " + model.Attendee3AddressStreet1 + " " + model.Attendee3AddressStreet2 + ", " + model.Attendee3AddressCity + ", " + model.Attendee3AddressPostalCode + Environment.NewLine;
                            bodyText += "Phone: " + (string.IsNullOrEmpty(model.Attendee3PhoneNumber) ? "not provided" : model.Attendee3PhoneNumber) + Environment.NewLine;
                            bodyText += "Email: " + (string.IsNullOrEmpty(model.Attendee3EmailAddress) ? "not provided" : model.Attendee3EmailAddress) + Environment.NewLine;
                            bodyText += "Mailable?: " + model.Attendee3FutureContact + Environment.NewLine;
                            bodyText += "Attendance Type: " + model.Attendee3Type + Environment.NewLine;
                            bodyText += "Ticket Price: " + model.Attendee3TicketPrice + Environment.NewLine;
                            bodyText += "-------------------------------------------------------------" + Environment.NewLine;
                        }
                        if (model.Attendee4IsAttending)
                        {
                            bodyText += "Attendee 4: " + Environment.NewLine;
                            bodyText += "Name: " + model.Attendee4FullName + Environment.NewLine;
                            bodyText += "Address: " + model.Attendee4AddressStreet1 + " " + model.Attendee4AddressStreet2 + ", " + model.Attendee4AddressCity + ", " + model.Attendee4AddressPostalCode + Environment.NewLine;
                            bodyText += "Phone: " + (string.IsNullOrEmpty(model.Attendee4PhoneNumber) ? "not provided" : model.Attendee4PhoneNumber) + Environment.NewLine;
                            bodyText += "Email: " + (string.IsNullOrEmpty(model.Attendee4EmailAddress) ? "not provided" : model.Attendee4EmailAddress) + Environment.NewLine;
                            bodyText += "Mailable?: " + model.Attendee4FutureContact + Environment.NewLine;
                            bodyText += "Attendance Type: " + model.Attendee4Type + Environment.NewLine;
                            bodyText += "Ticket Price: " + model.Attendee4TicketPrice + Environment.NewLine;
                            bodyText += "-------------------------------------------------------------" + Environment.NewLine;
                        }
                        bodyText += "Notes from the register: " + model.CustomerNotes + Environment.NewLine;
                        bodyText += "-------------------------------------------------------------" + Environment.NewLine;
                        bodyText += "Payee: " + Environment.NewLine;
                        bodyText += "Paid with " + model.BrainTreePayment.PaymentMethod + Environment.NewLine;
                        bodyText += "Name: " + model.BrainTreePayment.PayeeFirstName + " " + model.BrainTreePayment.PayeeLastName + Environment.NewLine;

                        var emailGroupResult = await _emailService.SendEmailAsync(groupEmail, groupEmail, groupEmail, subject, bodyText, "golf-registration");

                        #endregion

                        if (result.IsSuccess)
                        {
                            return(RedirectToAction("RegisterThankYou"));
                        }
                        else
                        {
                            foreach (var error in result.Messages)
                            {
                                ModelState.AddModelError(error.GetHashCode().ToString(), error);
                                _logger.LogError("Data Exception saving Golf Registration {@modelGolfReg}", model);
                            }

                            return(RedirectToAction("Register"));
                        }
                    }
                    _logger.LogInformation("Adoption App Model Errors {@errors} {@modelGolfReg}", result.Messages, model);
                }
                catch (Exception dex)
                {
                    //Log the error (uncomment dex variable name and add a line here to write a log.
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
                    _logger.LogError(new EventId(6), dex, "Data Exception saving Golf Registration {@modelGolfReg}", model);
                }
            }
            return(RedirectToAction("Register"));
        }
        public async Task <IActionResult> Apply(ApplyToAdoptViewModel model)
        {
            // TODO: add exception handling and display error message to user

            // payment information in an encrypted string rather than sending the payment information to the server from the client
            if (string.IsNullOrEmpty(model.BrainTreePayment.Nonce))
            {
                ModelState.AddModelError("", "incomplete payment information provided");
            }
            else
            {
                try
                {
                    // get model state errors
                    var errors = ModelState.Values.SelectMany(v => v.Errors);

                    // if paying with a credit card the fields for credit card number/cvs/month/year will be invalid because we do not send them to the server
                    // so count the errors on the field validation that do not start with 'card ' (comes from the property attributes in the model class Apply.cs)
                    // TODO validate if this is still needed - all card validation has been removed b/c client side validation requires 'name' properties
                    //      which have been removed for PCI compliance.
                    var errorCount = errors.Count(m => !m.ErrorMessage.StartsWith("card "));

                    if (errorCount == 0)
                    {
                        var result = new ServiceResult();

                        #region Process Payment
                        var paymentMethod = (Models.BrainTreeViewModels.PaymentTypeEnum)Enum.Parse(typeof(Models.BrainTreeViewModels.PaymentTypeEnum), model.BrainTreePayment.PaymentMethod);
                        var phone         = string.IsNullOrEmpty(model.AppCellPhone) ? model.AppHomePhone : model.AppCellPhone;

                        var paymentRequestResult = new ServiceResult();

                        if (paymentMethod == PaymentTypeEnum.Paypal)
                        {
                            paymentRequestResult = _paymentService.SendPayment(model.ApplicationFeeAmount,
                                                                               model.BrainTreePayment.Nonce,
                                                                               true,
                                                                               paymentMethod,
                                                                               model.BrainTreePayment.DeviceData,
                                                                               "adoption app fee",
                                                                               model.Comments,
                                                                               model.BrainTreePayment.PayeeFirstName,
                                                                               model.BrainTreePayment.PayeeLastName,
                                                                               phone,
                                                                               model.AppEmail);
                        }
                        else
                        {
                            var stateCode = _context.States.First(p => p.Id == model.BrainTreePayment.PayeeAddressStateId).Code;

                            paymentRequestResult = _paymentService.SendPayment(model.ApplicationFeeAmount,
                                                                               model.BrainTreePayment.Nonce,
                                                                               true,
                                                                               paymentMethod,
                                                                               model.BrainTreePayment.DeviceData,
                                                                               "adoption app fee",
                                                                               model.Comments,
                                                                               model.BrainTreePayment.PayeeFirstName,
                                                                               model.BrainTreePayment.PayeeLastName,
                                                                               model.BrainTreePayment.PayeeAddressStreet1,
                                                                               model.BrainTreePayment.PayeeAddressStreet2,
                                                                               model.BrainTreePayment.PayeeAddressCity,
                                                                               stateCode,
                                                                               model.BrainTreePayment.PayeeAddressPostalCode,
                                                                               "US",
                                                                               phone,
                                                                               model.AppEmail);
                        }

                        if (!paymentRequestResult.IsSuccess)
                        {
                            // TODO: handle failure to pay
                            result.IsSuccess = false;
                            result.Messages.Add("Payment Failure - see below for details: ");
                            result.Messages.AddRange(paymentRequestResult.Messages);

                            _logger.LogError("Adoption App Fee Payment Failed {@AdoptionAppFeePaymentErrors}", result.Messages);
                            ModelState.AddModelError("", "Unable to process your payment. Try again, and if the problem persists see your system administrator.");
                            foreach (var error in paymentRequestResult.Messages)
                            {
                                ModelState.AddModelError("", error);
                            }

                            RedirectToAction("Apply");
                        }

                        // payment is a success. capture the transaction id from braintree
                        model.BrainTreePayment.BraintreeTransactionId = paymentRequestResult.NewKey;
                        #endregion

                        #region Database

                        var personId    = Guid.NewGuid();
                        var applicantId = Guid.NewGuid();

                        #region Copy ViewModel to database Model
                        var dbApplicant = new Models.ApplicationAdoption
                        {
                            Id                                                  = applicantId,
                            PersonId                                            = personId,
                            AppAddressStateId                                   = model.AppAddressStateId,
                            AppAddressCity                                      = model.AppAddressCity,
                            AppAddressStreet1                                   = model.AppAddressStreet1,
                            AppAddressZIP                                       = model.AppAddressZip,
                            AppCellPhone                                        = model.AppCellPhone,
                            AppDateBirth                                        = model.AppDateBirth,
                            AppEmail                                            = model.AppEmail,
                            AppEmployer                                         = model.AppEmployer,
                            AppHomePhone                                        = model.AppHomePhone,
                            AppNameFirst                                        = model.AppNameFirst,
                            AppNameLast                                         = model.AppNameLast,
                            AppSpouseNameFirst                                  = model.AppSpouseNameFirst,
                            AppSpouseNameLast                                   = model.AppSpouseNameLast,
                            AppTravelFrequency                                  = model.AppTravelFrequency,
                            FilterAppCatsOwnedCount                             = model.FilterAppCatsOwnedCount,
                            FilterAppDogsInterestedIn                           = model.FilterAppDogsInterestedIn,
                            FilterAppHasOwnedHuskyBefore                        = model.FilterAppHasOwnedHuskyBefore != null && model.FilterAppHasOwnedHuskyBefore.Value,
                            FilterAppIsAwareHuskyAttributes                     = model.FilterAppIsAwareHuskyAttributes != null && model.FilterAppIsAwareHuskyAttributes.Value,
                            FilterAppIsCatOwner                                 = model.FilterAppIsCatOwner != null && model.FilterAppIsCatOwner.Value,
                            FilterAppTraitsDesired                              = model.FilterAppTraitsDesired,
                            DateSubmitted                                       = DateTime.Today,
                            IsAllAdultsAgreedOnAdoption                         = model.IsAllAdultsAgreedOnAdoption,
                            IsAllAdultsAgreedOnAdoptionReason                   = model.IsAllAdultsAgreedOnAdoptionReason,
                            IsAppOrSpouseStudent                                = model.IsAppOrSpouseStudent != null && model.IsAppOrSpouseStudent.Value,
                            IsAppTravelFrequent                                 = model.IsAppTravelFrequent != null && model.IsAppTravelFrequent.Value,
                            IsPetAdoptionReasonCompanionChild                   = model.IsPetAdoptionReasonCompanionChild,
                            IsPetAdoptionReasonCompanionPet                     = model.IsPetAdoptionReasonCompanionPet,
                            IsPetAdoptionReasonGift                             = model.IsPetAdoptionReasonGift,
                            IsPetAdoptionReasonGuardDog                         = model.IsPetAdoptionReasonGuardDog,
                            IsPetAdoptionReasonHousePet                         = model.IsPetAdoptionReasonHousePet,
                            IsPetAdoptionReasonJoggingPartner                   = model.IsPetAdoptionReasonJoggingPartner,
                            IsPetAdoptionReasonOther                            = model.IsPetAdoptionReasonOther,
                            IsPetAdoptionReasonWatchDog                         = model.IsPetAdoptionReasonWatchDog,
                            IsPetKeptLocationAloneRestrictionBasement           = model.IsPetKeptLocationAloneRestrictionBasement,
                            IsPetKeptLocationAloneRestrictionCratedIndoors      = model.IsPetKeptLocationAloneRestrictionCratedIndoors,
                            IsPetKeptLocationAloneRestrictionCratedOutdoors     = model.IsPetKeptLocationAloneRestrictionCratedOutdoors,
                            IsPetKeptLocationAloneRestrictionGarage             = model.IsPetKeptLocationAloneRestrictionGarage,
                            IsPetKeptLocationAloneRestrictionLooseInBackyard    = model.IsPetKeptLocationAloneRestrictionLooseInBackyard,
                            IsPetKeptLocationAloneRestrictionLooseIndoors       = model.IsPetKeptLocationAloneRestrictionLooseIndoors,
                            IsPetKeptLocationAloneRestrictionOther              = model.IsPetKeptLocationAloneRestrictionOther,
                            IsPetKeptLocationAloneRestrictionOutsideKennel      = model.IsPetKeptLocationAloneRestrictionOutsideKennel,
                            IsPetKeptLocationAloneRestrictionTiedUpOutdoors     = model.IsPetKeptLocationAloneRestrictionTiedUpOutdoors,
                            IsPetKeptLocationInOutDoorMostlyOutside             = model.IsPetKeptLocationInOutDoorMostlyOutsides,
                            IsPetKeptLocationInOutDoorsMostlyInside             = model.IsPetKeptLocationInOutDoorsMostlyInside,
                            IsPetKeptLocationInOutDoorsTotallyInside            = model.IsPetKeptLocationInOutDoorsTotallyInside,
                            IsPetKeptLocationInOutDoorsTotallyOutside           = model.IsPetKeptLocationInOutDoorsTotallyOutside,
                            IsPetKeptLocationSleepingRestrictionBasement        = model.IsPetKeptLocationSleepingRestrictionBasement,
                            IsPetKeptLocationSleepingRestrictionCratedIndoors   = model.IsPetKeptLocationSleepingRestrictionCratedIndoors,
                            IsPetKeptLocationSleepingRestrictionCratedOutdoors  = model.IsPetKeptLocationSleepingRestrictionCratedOutdoors,
                            IsPetKeptLocationSleepingRestrictionGarage          = model.IsPetKeptLocationSleepingRestrictionGarage,
                            IsPetKeptLocationSleepingRestrictionInBedOwner      = model.IsPetKeptLocationSleepingRestrictionInBedOwner,
                            IsPetKeptLocationSleepingRestrictionLooseInBackyard = model.IsPetKeptLocationSleepingRestrictionLooseInBackyard,
                            IsPetKeptLocationSleepingRestrictionLooseIndoors    = model.IsPetKeptLocationSleepingRestrictionLooseIndoors,
                            IsPetKeptLocationSleepingRestrictionOther           = model.IsPetKeptLocationSleepingRestrictionOther,
                            IsPetKeptLocationSleepingRestrictionOutsideKennel   = model.IsPetKeptLocationSleepingRestrictionOutsideKennel,
                            IsPetKeptLocationSleepingRestrictionTiedUpOutdoors  = model.IsPetKeptLocationSleepingRestrictionTiedUpOutdoors,
                            ResIdenceIsYardFenced                               = model.ResidenceIsYardFenced != null && model.ResidenceIsYardFenced.Value,
                            ResidenceAgesOfChildren                             = model.ResidenceAgesOfChildren,
                            ResidenceFenceTypeHeight                            = model.ResidenceFenceTypeHeight,
                            ResidenceIsPetAllowed                               = model.ResidenceIsPetAllowed,
                            ResidenceIsPetDepositPaid                           = model.ResidenceIsPetDepositPaid,
                            ResidenceIsPetDepositRequired                       = model.ResidenceIsPetDepositRequired,
                            ResidenceLandlordName                               = model.ResidenceLandlordName,
                            ResidenceLandlordNumber                             = model.ResidenceLandlordNumber,
                            ResidenceLengthOfResidence                          = model.ResidenceLengthOfResidence,
                            ResidenceNumberOccupants                            = model.ResidenceNumberOccupants,
                            ApplicationResidenceOwnershipTypeId                 = model.ResidenceOwnershipId,
                            ResidencePetDepositAmount                           = model.ResidencePetDepositAmount,
                            ApplicationResidencePetDepositCoverageTypeId        = model.ResidencePetDepositCoverageId,
                            ResidencePetSizeWeightLimit                         = model.ResidencePetSizeWeightLimit,
                            ApplicationResidenceTypeId                          = model.ResidenceTypeId,
                            PetLeftAloneDays                                    = model.PetLeftAloneDays,
                            PetLeftAloneHours                                   = model.PetLeftAloneHours,
                            ApplicationStudentTypeId                            = model.StudentTypeId,
                            PetAdoptionReasonExplain                            = model.PetAdoptionReasonExplain,
                            PetKeptLocationAloneRestriction                     = model.PetKeptLocationAloneRestriction,
                            PetKeptLocationAloneRestrictionExplain              = model.PetKeptLocationAloneRestrictionExplain,
                            PetKeptLocationInOutDoors                           = model.PetKeptLocationInOutDoors,
                            PetKeptLocationInOutDoorsExplain                    = model.PetKeptLocationInOutDoorsExplain,
                            PetKeptLocationSleepingRestriction                  = model.PetKeptLocationSleepingRestriction,
                            PetKeptLocationSleepingRestrictionExplain           = model.PetKeptLocationSleepingRestrictionExplain,
                            WhatIfMovingPetPlacement                            = model.WhatIfMovingPetPlacement,
                            WhatIfTravelPetPlacement                            = model.WhatIfTravelPetPlacement,
                            ApplicationFeeAmount                                = model.ApplicationFeeAmount,
                            ApplicationFeePaymentMethod                         = model.BrainTreePayment.PaymentMethod,
                            ApplicationFeeTransactionId                         = model.BrainTreePayment.BraintreeTransactionId,
                            Comments                                            = model.Comments,
                            VeterinarianDoctorName                              = model.VeterinarianDoctorName,
                            VeterinarianOfficeName                              = model.VeterinarianOfficeName,
                            VeterinarianPhoneNumber                             = model.PhoneNumber
                        };

                        dbApplicant.ApplicationAdoptionStatuses = new List <Models.ApplicationAdoptionStatus> {
                            new Models.ApplicationAdoptionStatus {
                                Id = 0,
                                ApplicationAdoptionId           = applicantId,
                                ApplicationAdoptionStatusTypeId = 0,
                                Timestamp = DateTime.Now
                            }
                        };

                        dbApplicant.ApplicationAppAnimals = new List <Models.ApplicationAppAnimal>();

                        if (!string.IsNullOrEmpty(model.Name1))
                        {
                            dbApplicant.ApplicationAppAnimals.Add(new Models.ApplicationAppAnimal
                            {
                                Id                    = Guid.NewGuid(),
                                ApplicantId           = applicantId,
                                Age                   = model.Age1,
                                Breed                 = model.Breed1,
                                Sex                   = model.Sex1,
                                OwnershipLength       = model.OwnershipLength1,
                                Name                  = model.Name1,
                                IsAltered             = model.IsAltered1 != null && model.IsAltered1.Value,
                                AlteredReason         = model.AlteredReason1,
                                IsFullyVaccinated     = model.IsFullyVaccinated1 != null && model.IsFullyVaccinated1.Value,
                                FullyVaccinatedReason = model.FullyVaccinatedReason1,
                                IsHwPrevention        = model.IsHwPrevention1 != null && model.IsHwPrevention1.Value,
                                HwPreventionReason    = model.HwPreventionReason1,
                                IsStillOwned          = model.IsStillOwned1 != null && model.IsStillOwned1.Value,
                                IsStillOwnedReason    = model.IsStillOwnedReason1
                            });
                        }
                        if (!string.IsNullOrEmpty(model.Name2))
                        {
                            dbApplicant.ApplicationAppAnimals.Add(new Models.ApplicationAppAnimal
                            {
                                Id                    = Guid.NewGuid(),
                                ApplicantId           = applicantId,
                                Age                   = model.Age2,
                                Breed                 = model.Breed2,
                                Sex                   = model.Sex2,
                                OwnershipLength       = model.OwnershipLength2,
                                Name                  = model.Name2,
                                IsAltered             = model.IsAltered2 != null && model.IsAltered2.Value,
                                AlteredReason         = model.AlteredReason2,
                                IsFullyVaccinated     = model.IsFullyVaccinated2 != null && model.IsFullyVaccinated2.Value,
                                FullyVaccinatedReason = model.FullyVaccinatedReason2,
                                IsHwPrevention        = model.IsHwPrevention2 != null && model.IsHwPrevention2.Value,
                                HwPreventionReason    = model.HwPreventionReason2,
                                IsStillOwned          = model.IsStillOwned2 != null && model.IsStillOwned2.Value,
                                IsStillOwnedReason    = model.IsStillOwnedReason2
                            });
                        }
                        if (!string.IsNullOrEmpty(model.Name3))
                        {
                            dbApplicant.ApplicationAppAnimals.Add(new Models.ApplicationAppAnimal
                            {
                                Id                    = Guid.NewGuid(),
                                ApplicantId           = applicantId,
                                Age                   = model.Age3,
                                Breed                 = model.Breed3,
                                Sex                   = model.Sex3,
                                OwnershipLength       = model.OwnershipLength3,
                                Name                  = model.Name3,
                                IsAltered             = model.IsAltered3 != null && model.IsAltered3.Value,
                                AlteredReason         = model.AlteredReason3,
                                IsFullyVaccinated     = model.IsFullyVaccinated3 != null && model.IsFullyVaccinated3.Value,
                                FullyVaccinatedReason = model.FullyVaccinatedReason3,
                                IsHwPrevention        = model.IsHwPrevention3 != null && model.IsHwPrevention3.Value,
                                HwPreventionReason    = model.HwPreventionReason3,
                                IsStillOwned          = model.IsStillOwned3 != null && model.IsStillOwned3.Value,
                                IsStillOwnedReason    = model.IsStillOwnedReason3
                            });
                        }
                        if (!string.IsNullOrEmpty(model.Name4))
                        {
                            dbApplicant.ApplicationAppAnimals.Add(new Models.ApplicationAppAnimal
                            {
                                Id                    = Guid.NewGuid(),
                                ApplicantId           = applicantId,
                                Age                   = model.Age4,
                                Breed                 = model.Breed4,
                                Sex                   = model.Sex4,
                                OwnershipLength       = model.OwnershipLength4,
                                Name                  = model.Name4,
                                IsAltered             = model.IsAltered4 != null && model.IsAltered4.Value,
                                AlteredReason         = model.AlteredReason4,
                                IsFullyVaccinated     = model.IsFullyVaccinated4 != null && model.IsFullyVaccinated4.Value,
                                FullyVaccinatedReason = model.FullyVaccinatedReason4,
                                IsHwPrevention        = model.IsHwPrevention4 != null && model.IsHwPrevention4.Value,
                                HwPreventionReason    = model.HwPreventionReason4,
                                IsStillOwned          = model.IsStillOwned4 != null && model.IsStillOwned4.Value,
                                IsStillOwnedReason    = model.IsStillOwnedReason4
                            });
                        }
                        if (!string.IsNullOrEmpty(model.Name5))
                        {
                            dbApplicant.ApplicationAppAnimals.Add(new Models.ApplicationAppAnimal
                            {
                                Id                    = Guid.NewGuid(),
                                ApplicantId           = applicantId,
                                Age                   = model.Age5,
                                Breed                 = model.Breed5,
                                Sex                   = model.Sex5,
                                OwnershipLength       = model.OwnershipLength5,
                                Name                  = model.Name5,
                                IsAltered             = model.IsAltered5 != null && model.IsAltered5.Value,
                                AlteredReason         = model.AlteredReason5,
                                IsFullyVaccinated     = model.IsFullyVaccinated5 != null && model.IsFullyVaccinated5.Value,
                                FullyVaccinatedReason = model.FullyVaccinatedReason5,
                                IsHwPrevention        = model.IsHwPrevention5 != null && model.IsHwPrevention5.Value,
                                HwPreventionReason    = model.HwPreventionReason5,
                                IsStillOwned          = model.IsStillOwned5 != null && model.IsStillOwned5.Value,
                                IsStillOwnedReason    = model.IsStillOwnedReason5
                            });
                        }

                        var dbPerson = new Models.Person
                        {
                            Id = personId,
                            CreatedTimestamp = DateTime.Today,
                            FirstName        = model.AppNameFirst,
                            LastName         = model.AppNameLast,
                            IsActive         = true,
                            IsAdopter        = true,
                            FullName         = model.AppFullName,
                            CanEmail         = model.IsEmailable.HasValue ? model.IsEmailable.Value : false
                        };

                        dbPerson.Addresses = new List <Models.Address> {
                            new Models.Address
                            {
                                Id                = Guid.NewGuid(),
                                PersonId          = personId,
                                Address1          = model.AppAddressStreet1,
                                StatesId          = model.AppAddressStateId,
                                AddressTypeId     = 1, //Primary
                                City              = model.AppAddressCity,
                                IsShippingAddress = true,
                                ZipCode           = model.AppAddressZip,
                            }
                        };

                        if (!string.IsNullOrEmpty(model.AppEmail))
                        {
                            dbPerson.Emails = new List <Models.Email>
                            {
                                new Models.Email
                                {
                                    Id          = Guid.NewGuid(),
                                    PersonId    = personId,
                                    Address     = model.AppEmail,
                                    EmailTypeId = 0
                                }
                            };
                        }

                        if (!string.IsNullOrEmpty(model.AppHomePhone) || !string.IsNullOrEmpty(model.AppCellPhone))
                        {
                            dbPerson.Phones = new List <Models.Phone>();
                            if (!string.IsNullOrEmpty(model.AppHomePhone))
                            {
                                dbPerson.Phones.Add(new Models.Phone
                                {
                                    Id          = Guid.NewGuid(),
                                    PersonId    = personId,
                                    Number      = model.AppHomePhone,
                                    PhoneTypeId = 1
                                });
                            }
                            if (!string.IsNullOrEmpty(model.AppCellPhone))
                            {
                                dbPerson.Phones.Add(new Models.Phone
                                {
                                    Id          = Guid.NewGuid(),
                                    PersonId    = personId,
                                    Number      = model.AppCellPhone,
                                    PhoneTypeId = 1
                                });
                            }
                        }
                        #endregion

                        #region Add to Database
                        _context.Add(dbApplicant);
                        _context.Add(dbPerson);
                        #endregion

                        #region Save to Database and check exceptions
                        try
                        {
                            _logger.LogInformation("Saving application to database: {@dbApplicant}", dbApplicant);
                            var numChanges = _context.SaveChanges();
                            if (numChanges > 0)
                            {
                                result.IsSuccess = true;
                            }
                        }
                        //catch (DbEntityValidationException ex)
                        //{
                        //    _logger.LogError(ex, "Database Validation Exception saving Applicant");
                        //}
                        catch (DbUpdateException ex)
                        {
                            _logger.LogError(new EventId(1), ex, "Database Update Exception saving Applicant");
                        }
                        catch (InvalidOperationException ex)
                        {
                            _logger.LogError(new EventId(1), ex, "Invalid Operation Exception saving Applicant");
                        }
                        #endregion

                        #endregion

                        #region Generate PDF
                        var newPdfFileName = await _formService.CreateAdoptionApplicationPdf(dbApplicant);

                        #endregion

                        #region Send Emails
                        var groupEmail = _systemServices.GetSetting("Email-Contact").Value;

                        var subject = string.Join(" - ", "[TXHR Web Adoption App]", model.AppFullName);

                        var bodyText = string.Format(@"Thank you for your application.
                                Attached is a copy of your application sent to Texas Husky Rescue, Inc.
                                You can respond back to this email if you have any further questions or comments for us.
                                We will get back to you within the next 7 days regarding your application.
                                You're ${0} application fee will be applied towards your adoption fee if you are approved.
                                The confirmation number for your application fee is {1}", model.ApplicationFeeAmount, model.BrainTreePayment.BraintreeTransactionId);

                        byte[] pdfContentBytes;

                        using (var stream = new MemoryStream())
                        {
                            await _storageService.GetAppAdoption(newPdfFileName, stream);

                            pdfContentBytes = stream.ToArray();
                        }

                        var attachment = new PostmarkDotNet.PostmarkMessageAttachment
                        {
                            Content     = Convert.ToBase64String(pdfContentBytes),
                            ContentId   = Path.GetFileName(newPdfFileName),
                            ContentType = "application/pdf",
                            Name        = Path.GetFileName(newPdfFileName)
                        };

                        var attachments = new List <PostmarkDotNet.PostmarkMessageAttachment> {
                            attachment
                        };

                        // Send email to the adopter
                        var emailAppResult = await _emailService.SendEmailAsync(model.AppEmail, groupEmail, groupEmail, subject, bodyText, "adoption", attachments);

                        bodyText  = "Dogs interested in: " + model.FilterAppDogsInterestedIn + Environment.NewLine + Environment.NewLine;
                        bodyText += "Comments from app: " + model.Comments;

                        var emailGroupResult = await _emailService.SendEmailAsync(groupEmail, groupEmail, groupEmail, subject, bodyText, "adoption", attachments);

                        #endregion

                        if (result.IsSuccess)
                        {
                            return(RedirectToAction("ThankYou"));
                        }
                        else
                        {
                            foreach (var error in result.Messages)
                            {
                                ModelState.AddModelError(error.GetHashCode().ToString(), error);
                                _logger.LogError("Data Exception saving Adoption Application {@app}", model);
                            }

                            return(RedirectToAction("Apply"));
                        }
                    }
                    _logger.LogInformation("Adoption App Model Errors {@errors} {@app}", errors, model);
                }
                catch (Exception dex)
                {
                    //Log the error (uncomment dex variable name and add a line here to write a log.
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
                    _logger.LogError(new EventId(1), dex, "Data Exception saving Adoption Application {@app}", model);
                }
            }
            return(RedirectToAction("Apply"));
        }
        //[ValidateRecaptcha]
        public async Task <IActionResult> Donate(DonationViewModel model)
        {
            if (string.IsNullOrEmpty(model.BrainTreePayment.Nonce))
            {
                ModelState.AddModelError("", "incomplete payment information provided");
            }
            else
            {
                try
                {
                    // get model state errors
                    var errors = ModelState.Values.SelectMany(v => v.Errors);

                    // if paying with a credit card the fields for credit card number/cvs/month/year will be invalid because we do not send them to the server
                    // so count the errors on the field validation that do not start with 'card ' (comes from the property attributes in the model class Apply.cs)
                    // TODO validate if this is still needed - all card validation has been removed b/c client side validation requires 'name' properties
                    //      which have been removed for PCI compliance.
                    var errorCount = errors.Count(m => !m.ErrorMessage.StartsWith("card "));
                    var result     = new ServiceResult();
                    if (errorCount == 0)
                    {
                        #region Process Payment
                        var paymentMethod = (PaymentTypeEnum)Enum.Parse(typeof(PaymentTypeEnum), model.BrainTreePayment.PaymentMethod);
                        var phone         = model.DonorPhoneNumber;
                        var paymentResult = new ServiceResult();

                        var paymentRequestResult = new ServiceResult();

                        if (paymentMethod == PaymentTypeEnum.Paypal)
                        {
                            paymentResult = _paymentService.SendPayment(model.AmountDonation,
                                                                        model.BrainTreePayment.Nonce,
                                                                        true,
                                                                        paymentMethod,
                                                                        model.BrainTreePayment.DeviceData,
                                                                        "donation",
                                                                        model.Comments,
                                                                        model.BrainTreePayment.PayeeFirstName,
                                                                        model.BrainTreePayment.PayeeLastName,
                                                                        phone,
                                                                        model.DonorEmail);
                        }
                        else
                        {
                            var stateCode = _context.States.First(p => p.Id == model.BrainTreePayment.PayeeAddressStateId).Code;

                            paymentRequestResult = _paymentService.SendPayment(model.AmountDonation,
                                                                               model.BrainTreePayment.Nonce,
                                                                               true,
                                                                               paymentMethod,
                                                                               model.BrainTreePayment.DeviceData,
                                                                               "donation",
                                                                               model.Comments,
                                                                               model.BrainTreePayment.PayeeFirstName,
                                                                               model.BrainTreePayment.PayeeLastName,
                                                                               model.BrainTreePayment.PayeeAddressStreet1,
                                                                               model.BrainTreePayment.PayeeAddressStreet2,
                                                                               model.BrainTreePayment.PayeeAddressCity,
                                                                               stateCode,
                                                                               model.BrainTreePayment.PayeeAddressPostalCode,
                                                                               "US",
                                                                               phone,
                                                                               model.DonorEmail);
                        }

                        if (!paymentRequestResult.IsSuccess)
                        {
                            // TODO: handle failure to pay
                            result.IsSuccess = false;
                            result.Messages.Add("Payment Failure - see below for details: ");
                            result.Messages.AddRange(paymentRequestResult.Messages);

                            _logger.LogError("Donation Payment Failed {@DonationPaymentErrors}", result.Messages);
                            ModelState.AddModelError("", "Unable to process your payment. Try again, and if the problem persists see your system administrator.");
                            foreach (var error in paymentRequestResult.Messages)
                            {
                                ModelState.AddModelError("", error);
                            }

                            RedirectToAction("Index");
                        }

                        // payment is a success. capture the transaction id from braintree
                        model.BrainTreePayment.BraintreeTransactionId = paymentRequestResult.NewKey;
                        #endregion

                        #region Database

                        var donationId = Guid.NewGuid();
                        var personId   = Guid.NewGuid();

                        #region Copy ViewModel to database Model
                        var dbDonation = new Models.Donation
                        {
                            Id                 = donationId,
                            Amount             = model.AmountDonation,
                            DonorNote          = model.Comments,
                            DateTimeOfDonation = DateTime.Now,
                            PersonId           = personId,
                            PaymentType        = paymentMethod.ToString()
                        };

                        var dbPerson = new Models.Person
                        {
                            Id = personId,
                            CreatedTimestamp = DateTime.Today,
                            FirstName        = model.BrainTreePayment.PayeeFirstName,
                            LastName         = model.BrainTreePayment.PayeeLastName,
                            IsActive         = true,
                            IsDonor          = true,
                            FullName         = model.BrainTreePayment.PayeeFullName,
                            CanEmail         = model.IsEmailable.HasValue ? model.IsEmailable.Value : false
                        };

                        if (paymentMethod == PaymentTypeEnum.CreditCard)
                        {
                            dbPerson.Addresses = new List <Models.Address> {
                                new Models.Address
                                {
                                    Id               = Guid.NewGuid(),
                                    PersonId         = personId,
                                    Address1         = model.BrainTreePayment.PayeeAddressStreet1,
                                    Address2         = model.BrainTreePayment.PayeeAddressStreet2,
                                    StatesId         = model.BrainTreePayment.PayeeAddressStateId.Value,
                                    AddressTypeId    = 1, //Primary
                                    City             = model.BrainTreePayment.PayeeAddressCity,
                                    IsBillingAddress = true,
                                    ZipCode          = model.BrainTreePayment.PayeeAddressPostalCode
                                }
                            };
                        }

                        if (!string.IsNullOrEmpty(model.DonorEmail))
                        {
                            dbPerson.Emails = new List <Models.Email>
                            {
                                new Models.Email
                                {
                                    Id          = Guid.NewGuid(),
                                    PersonId    = personId,
                                    Address     = model.DonorEmail,
                                    EmailTypeId = 0
                                }
                            };
                        }

                        if (!string.IsNullOrEmpty(model.DonorPhoneNumber))
                        {
                            dbPerson.Phones = new List <Models.Phone>
                            {
                                new Models.Phone
                                {
                                    Id          = Guid.NewGuid(),
                                    PersonId    = personId,
                                    Number      = model.DonorPhoneNumber,
                                    PhoneTypeId = 1
                                }
                            };
                        }
                        #endregion

                        #region Add to Database
                        _context.Add(dbDonation);
                        _context.Add(dbPerson);
                        #endregion

                        #region Save to Database and check exceptions
                        try
                        {
                            _logger.LogInformation("Saving donation information to database: {@dbDonation}", dbDonation);
                            var numChanges = _context.SaveChanges();
                            if (numChanges > 0)
                            {
                                result.IsSuccess = true;
                            }
                        }
                        catch (DbUpdateException ex)
                        {
                            _logger.LogError(new EventId(7), ex, "Database Update Exception saving donation information");
                        }
                        catch (InvalidOperationException ex)
                        {
                            _logger.LogError(new EventId(7), ex, "Invalid Operation Exception saving donation information");
                        }
                        #endregion

                        #endregion

                        #region Send Emails
                        var groupEmail = _systemServices.GetSetting("Email-Contact").Value;

                        var subject  = string.Format("[TXHR Web] [Donation] [Amount=${0}] - {1}", model.AmountDonation, model.BrainTreePayment.PayeeFullName);
                        var bodyText = string.Format(@"
Thank you, {0}. Your donation of {1} is greatly appreciated. For your records:
Payment method: {2}
Payment Date: {3}
Payment Confirmation Id: {4}

Thanks again,
Texas Husky Rescue
1-877-TX-HUSKY (894-8759)(phone / fax)
PO Box 118891, Carrollton, TX 75007",
                                                     model.BrainTreePayment.PayeeFullName, model.AmountDonation, paymentMethod, DateTime.Now.Date, model.BrainTreePayment.BraintreeTransactionId);


                        var emailAppResult = await _emailService.SendEmailAsync(model.DonorEmail, groupEmail, groupEmail, subject, bodyText, "donation");

                        bodyText = string.Format(@"
Donor Name: {0}
Donor Email: {1}
Donor Phone: {2}
Donation Amount: {3}
Payment method: {4}
Payment Date: {5}
Payment Confirmation Id: {6}
Comments : {7}",
                                                 model.BrainTreePayment.PayeeFullName, model.DonorEmail, model.DonorPhoneNumber, model.AmountDonation, paymentMethod, DateTime.Now.Date, model.BrainTreePayment.BraintreeTransactionId, model.Comments);

                        var emailGroupResult = await _emailService.SendEmailAsync(groupEmail, groupEmail, groupEmail, subject, bodyText, "donation");

                        #endregion

                        if (result.IsSuccess)
                        {
                            return(RedirectToAction("ThankYou"));
                        }
                        else
                        {
                            foreach (var error in result.Messages)
                            {
                                ModelState.AddModelError(error.GetHashCode().ToString(), error);
                                _logger.LogError("Data Exception saving Donation {@modelGolfReg}", model);
                            }

                            return(RedirectToAction("ThankYou"));
                        }
                    }
                    _logger.LogInformation("Donation Model Errors {@errors} {@modelDonation}", result.Messages, model);
                }
                catch (Exception dex)
                {
                    //Log the error (uncomment dex variable name and add a line here to write a log.
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
                    _logger.LogError(new EventId(6), dex, "Data Exception saving Donation {@modelDonation}", model);
                }
            }
            return(RedirectToAction("Index"));
        }