Example #1
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (RegistrantState != null)
            {
                RockContext            rockContext                    = new RockContext();
                var                    personService                  = new PersonService(rockContext);
                var                    registrantService              = new RegistrationRegistrantService(rockContext);
                var                    registrantFeeService           = new RegistrationRegistrantFeeService(rockContext);
                var                    registrationTemplateFeeService = new RegistrationTemplateFeeService(rockContext);
                RegistrationRegistrant registrant = null;
                if (RegistrantState.Id > 0)
                {
                    registrant = registrantService.Get(RegistrantState.Id);
                }

                bool newRegistrant     = false;
                var  registrantChanges = new List <string>();

                if (registrant == null)
                {
                    newRegistrant             = true;
                    registrant                = new RegistrationRegistrant();
                    registrant.RegistrationId = RegistrantState.RegistrationId;
                    registrantService.Add(registrant);
                    registrantChanges.Add("Created Registrant");
                }

                if (!registrant.PersonAliasId.Equals(ppPerson.PersonAliasId))
                {
                    string prevPerson = (registrant.PersonAlias != null && registrant.PersonAlias.Person != null) ?
                                        registrant.PersonAlias.Person.FullName : string.Empty;
                    string newPerson = ppPerson.PersonName;
                    History.EvaluateChange(registrantChanges, "Person", prevPerson, newPerson);
                }
                int?personId = ppPerson.PersonId.Value;
                registrant.PersonAliasId = ppPerson.PersonAliasId.Value;

                // Get the name of registrant for history
                string registrantName = "Unknown";
                if (ppPerson.PersonId.HasValue)
                {
                    var person = personService.Get(ppPerson.PersonId.Value);
                    if (person != null)
                    {
                        registrantName = person.FullName;
                    }
                }

                History.EvaluateChange(registrantChanges, "Cost", registrant.Cost, cbCost.Text.AsDecimal());
                registrant.Cost = cbCost.Text.AsDecimal();

                if (!Page.IsValid)
                {
                    return;
                }

                // Remove/delete any registrant fees that are no longer in UI with quantity
                foreach (var dbFee in registrant.Fees.ToList())
                {
                    if (!RegistrantState.FeeValues.Keys.Contains(dbFee.RegistrationTemplateFeeId) ||
                        RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId] == null ||
                        !RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId]
                        .Any(f =>
                             f.Option == dbFee.Option &&
                             f.Quantity > 0))
                    {
                        registrantChanges.Add(string.Format("Removed '{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}",
                                                            dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option));

                        registrant.Fees.Remove(dbFee);
                        registrantFeeService.Delete(dbFee);
                    }
                }

                // Add/Update any of the fees from UI
                foreach (var uiFee in RegistrantState.FeeValues.Where(f => f.Value != null))
                {
                    foreach (var uiFeeOption in uiFee.Value)
                    {
                        var dbFee = registrant.Fees
                                    .Where(f =>
                                           f.RegistrationTemplateFeeId == uiFee.Key &&
                                           f.Option == uiFeeOption.Option)
                                    .FirstOrDefault();

                        if (dbFee == null)
                        {
                            dbFee = new RegistrationRegistrantFee();
                            dbFee.RegistrationTemplateFeeId = uiFee.Key;
                            dbFee.Option = uiFeeOption.Option;
                            registrant.Fees.Add(dbFee);
                        }

                        var templateFee = dbFee.RegistrationTemplateFee;
                        if (templateFee == null)
                        {
                            templateFee = registrationTemplateFeeService.Get(uiFee.Key);
                        }

                        string feeName = templateFee != null ? templateFee.Name : "Fee";
                        if (!string.IsNullOrWhiteSpace(uiFeeOption.Option))
                        {
                            feeName = string.Format("{0} ({1})", feeName, uiFeeOption.Option);
                        }

                        if (dbFee.Id <= 0)
                        {
                            registrantChanges.Add(feeName + " Fee Added");
                        }

                        History.EvaluateChange(registrantChanges, feeName + " Quantity", dbFee.Quantity, uiFeeOption.Quantity);
                        dbFee.Quantity = uiFeeOption.Quantity;

                        History.EvaluateChange(registrantChanges, feeName + " Cost", dbFee.Cost, uiFeeOption.Cost);
                        dbFee.Cost = uiFeeOption.Cost;
                    }
                }

                if (TemplateState.RequiredSignatureDocumentTemplate != null)
                {
                    var person = new PersonService(rockContext).Get(personId.Value);

                    var documentService        = new SignatureDocumentService(rockContext);
                    var binaryFileService      = new BinaryFileService(rockContext);
                    SignatureDocument document = null;

                    int?signatureDocumentId = hfSignedDocumentId.Value.AsIntegerOrNull();
                    int?binaryFileId        = fuSignedDocument.BinaryFileId;
                    if (signatureDocumentId.HasValue)
                    {
                        document = documentService.Get(signatureDocumentId.Value);
                    }

                    if (document == null && binaryFileId.HasValue)
                    {
                        var instance = new RegistrationInstanceService(rockContext).Get(RegistrationInstanceId);

                        document = new SignatureDocument();
                        document.SignatureDocumentTemplateId = TemplateState.RequiredSignatureDocumentTemplate.Id;
                        document.AppliesToPersonAliasId      = registrant.PersonAliasId.Value;
                        document.AssignedToPersonAliasId     = registrant.PersonAliasId.Value;
                        document.Name = string.Format("{0}_{1}",
                                                      (instance != null ? instance.Name : TemplateState.Name),
                                                      (person != null ? person.FullName.RemoveSpecialCharacters() : string.Empty));
                        document.Status         = SignatureDocumentStatus.Signed;
                        document.LastStatusDate = RockDateTime.Now;
                        documentService.Add(document);
                    }

                    if (document != null)
                    {
                        int?origBinaryFileId = document.BinaryFileId;
                        document.BinaryFileId = binaryFileId;

                        if (origBinaryFileId.HasValue && origBinaryFileId.Value != document.BinaryFileId)
                        {
                            // if a new the binaryFile was uploaded, mark the old one as Temporary so that it gets cleaned up
                            var oldBinaryFile = binaryFileService.Get(origBinaryFileId.Value);
                            if (oldBinaryFile != null && !oldBinaryFile.IsTemporary)
                            {
                                oldBinaryFile.IsTemporary = true;
                            }
                        }

                        // ensure the IsTemporary is set to false on binaryFile associated with this document
                        if (document.BinaryFileId.HasValue)
                        {
                            var binaryFile = binaryFileService.Get(document.BinaryFileId.Value);
                            if (binaryFile != null && binaryFile.IsTemporary)
                            {
                                binaryFile.IsTemporary = false;
                            }
                        }
                    }
                }

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

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction(() =>
                {
                    rockContext.SaveChanges();

                    registrant.LoadAttributes();
                    foreach (var field in TemplateState.Forms
                             .SelectMany(f => f.Fields
                                         .Where(t =>
                                                t.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                                                t.AttributeId.HasValue)))
                    {
                        var attribute = AttributeCache.Read(field.AttributeId.Value);
                        if (attribute != null)
                        {
                            string originalValue = registrant.GetAttributeValue(attribute.Key);
                            var fieldValue       = RegistrantState.FieldValues
                                                   .Where(f => f.Key == field.Id)
                                                   .Select(f => f.Value.FieldValue)
                                                   .FirstOrDefault();
                            string newValue = fieldValue != null ? fieldValue.ToString() : string.Empty;

                            if ((originalValue ?? string.Empty).Trim() != (newValue ?? string.Empty).Trim())
                            {
                                string formattedOriginalValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(originalValue))
                                {
                                    formattedOriginalValue = attribute.FieldType.Field.FormatValue(null, originalValue, attribute.QualifierValues, false);
                                }

                                string formattedNewValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(newValue))
                                {
                                    formattedNewValue = attribute.FieldType.Field.FormatValue(null, newValue, attribute.QualifierValues, false);
                                }

                                History.EvaluateChange(registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue);
                            }

                            if (fieldValue != null)
                            {
                                registrant.SetAttributeValue(attribute.Key, fieldValue.ToString());
                            }
                        }
                    }

                    registrant.SaveAttributeValues(rockContext);
                });

                if (newRegistrant && TemplateState.GroupTypeId.HasValue && ppPerson.PersonId.HasValue)
                {
                    using (var newRockContext = new RockContext())
                    {
                        var reloadedRegistrant = new RegistrationRegistrantService(newRockContext).Get(registrant.Id);
                        if (reloadedRegistrant != null &&
                            reloadedRegistrant.Registration != null &&
                            reloadedRegistrant.Registration.Group != null &&
                            reloadedRegistrant.Registration.Group.GroupTypeId == TemplateState.GroupTypeId.Value)
                        {
                            int?groupRoleId = TemplateState.GroupMemberRoleId.HasValue ?
                                              TemplateState.GroupMemberRoleId.Value :
                                              reloadedRegistrant.Registration.Group.GroupType.DefaultGroupRoleId;
                            if (groupRoleId.HasValue)
                            {
                                var groupMemberService = new GroupMemberService(newRockContext);
                                var groupMember        = groupMemberService
                                                         .Queryable().AsNoTracking()
                                                         .Where(m =>
                                                                m.GroupId == reloadedRegistrant.Registration.Group.Id &&
                                                                m.PersonId == reloadedRegistrant.PersonId &&
                                                                m.GroupRoleId == groupRoleId.Value)
                                                         .FirstOrDefault();
                                if (groupMember == null)
                                {
                                    groupMember = new GroupMember();
                                    groupMemberService.Add(groupMember);
                                    groupMember.GroupId           = reloadedRegistrant.Registration.Group.Id;
                                    groupMember.PersonId          = ppPerson.PersonId.Value;
                                    groupMember.GroupRoleId       = groupRoleId.Value;
                                    groupMember.GroupMemberStatus = TemplateState.GroupMemberStatus;

                                    newRockContext.SaveChanges();

                                    registrantChanges.Add(string.Format("Registrant added to {0} group", reloadedRegistrant.Registration.Group.Name));
                                }
                                else
                                {
                                    registrantChanges.Add(string.Format("Registrant group member reference updated to existing person in {0} group", reloadedRegistrant.Registration.Group.Name));
                                }

                                reloadedRegistrant.GroupMemberId = groupMember.Id;
                                newRockContext.SaveChanges();
                            }
                        }
                    }
                }

                HistoryService.SaveChanges(
                    rockContext,
                    typeof(Registration),
                    Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                    registrant.RegistrationId,
                    registrantChanges,
                    "Registrant: " + registrantName,
                    null, null);
            }

            NavigateToRegistration();
        }
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click( object sender, EventArgs e )
        {
            if ( RegistrantState != null )
            {
                RockContext rockContext = new RockContext();
                var personService = new PersonService( rockContext );
                var registrantService = new RegistrationRegistrantService( rockContext );
                var registrantFeeService = new RegistrationRegistrantFeeService( rockContext );
                var registrationTemplateFeeService = new RegistrationTemplateFeeService( rockContext );
                RegistrationRegistrant registrant = null;
                if ( RegistrantState.Id > 0 )
                {
                    registrant = registrantService.Get( RegistrantState.Id );
                }

                bool newRegistrant = false;
                var registrantChanges = new List<string>();

                if ( registrant == null )
                {
                    newRegistrant = true;
                    registrant = new RegistrationRegistrant();
                    registrant.RegistrationId = RegistrantState.RegistrationId;
                    registrantService.Add( registrant );
                    registrantChanges.Add( "Created Registrant" );
                }

                if ( !registrant.PersonAliasId.Equals( ppPerson.PersonAliasId ) )
                {
                    string prevPerson = ( registrant.PersonAlias != null && registrant.PersonAlias.Person != null ) ?
                        registrant.PersonAlias.Person.FullName : string.Empty;
                    string newPerson = ppPerson.PersonName;
                    History.EvaluateChange( registrantChanges, "Person", prevPerson, newPerson );
                }
                registrant.PersonAliasId = ppPerson.PersonAliasId.Value;

                // Get the name of registrant for history
                string registrantName = "Unknown";
                if ( ppPerson.PersonId.HasValue )
                {
                    var person = personService.Get( ppPerson.PersonId.Value );
                    if ( person != null )
                    {
                        registrantName = person.FullName;
                    }
                }

                History.EvaluateChange( registrantChanges, "Cost", registrant.Cost, cbCost.Text.AsDecimal() );
                registrant.Cost = cbCost.Text.AsDecimal();

                if ( !Page.IsValid )
                {
                    return;
                }

                // Remove/delete any registrant fees that are no longer in UI with quantity
                foreach ( var dbFee in registrant.Fees.ToList() )
                {
                    if ( !RegistrantState.FeeValues.Keys.Contains( dbFee.RegistrationTemplateFeeId ) ||
                        RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId] == null ||
                        !RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId]
                            .Any( f =>
                                f.Option == dbFee.Option &&
                                f.Quantity > 0 ) )
                    {
                        registrantChanges.Add( string.Format( "Removed '{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}",
                            dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option ) );

                        registrant.Fees.Remove( dbFee );
                        registrantFeeService.Delete( dbFee );
                    }
                }

                // Add/Update any of the fees from UI
                foreach ( var uiFee in RegistrantState.FeeValues.Where( f => f.Value != null ) )
                {
                    foreach ( var uiFeeOption in uiFee.Value )
                    {
                        var dbFee = registrant.Fees
                            .Where( f =>
                                f.RegistrationTemplateFeeId == uiFee.Key &&
                                f.Option == uiFeeOption.Option )
                            .FirstOrDefault();

                        if ( dbFee == null )
                        {
                            dbFee = new RegistrationRegistrantFee();
                            dbFee.RegistrationTemplateFeeId = uiFee.Key;
                            dbFee.Option = uiFeeOption.Option;
                            registrant.Fees.Add( dbFee );
                        }

                        var templateFee = dbFee.RegistrationTemplateFee;
                        if ( templateFee == null )
                        {
                            templateFee = registrationTemplateFeeService.Get( uiFee.Key );
                        }

                        string feeName = templateFee != null ? templateFee.Name : "Fee";
                        if ( !string.IsNullOrWhiteSpace( uiFeeOption.Option ) )
                        {
                            feeName = string.Format( "{0} ({1})", feeName, uiFeeOption.Option );
                        }

                        if ( dbFee.Id <= 0 )
                        {
                            registrantChanges.Add( feeName + " Fee Added" );
                        }

                        History.EvaluateChange( registrantChanges, feeName + " Quantity", dbFee.Quantity, uiFeeOption.Quantity );
                        dbFee.Quantity = uiFeeOption.Quantity;

                        History.EvaluateChange( registrantChanges, feeName + " Cost", dbFee.Cost, uiFeeOption.Cost );
                        dbFee.Cost = uiFeeOption.Cost;
                    }
                }

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

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction( () =>
                {
                    rockContext.SaveChanges();

                    registrant.LoadAttributes();
                    foreach ( var field in TemplateState.Forms
                        .SelectMany( f => f.Fields
                            .Where( t =>
                                t.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                                t.AttributeId.HasValue ) ) )
                    {
                        var attribute = AttributeCache.Read( field.AttributeId.Value );
                        if ( attribute != null )
                        {
                            string originalValue = registrant.GetAttributeValue( attribute.Key );
                            var fieldValue = RegistrantState.FieldValues
                                .Where( f => f.Key == field.Id )
                                .Select( f => f.Value.FieldValue )
                                .FirstOrDefault();
                            string newValue = fieldValue != null ? fieldValue.ToString() : string.Empty;

                            if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() )
                            {
                                string formattedOriginalValue = string.Empty;
                                if ( !string.IsNullOrWhiteSpace( originalValue ) )
                                {
                                    formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false );
                                }

                                string formattedNewValue = string.Empty;
                                if ( !string.IsNullOrWhiteSpace( newValue ) )
                                {
                                    formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false );
                                }

                                History.EvaluateChange( registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue );
                            }

                            if ( fieldValue != null )
                            {
                                registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() );
                            }
                        }
                    }

                    registrant.SaveAttributeValues( rockContext );
                } );

                if ( newRegistrant && TemplateState.GroupTypeId.HasValue && ppPerson.PersonId.HasValue )
                {
                    using ( var newRockContext = new RockContext() )
                    {
                        var reloadedRegistrant = new RegistrationRegistrantService( newRockContext ).Get( registrant.Id );
                        if ( reloadedRegistrant != null &&
                            reloadedRegistrant.Registration != null &&
                            reloadedRegistrant.Registration.Group != null &&
                            reloadedRegistrant.Registration.Group.GroupTypeId == TemplateState.GroupTypeId.Value )
                        {
                            int? groupRoleId = TemplateState.GroupMemberRoleId.HasValue ?
                                TemplateState.GroupMemberRoleId.Value :
                                reloadedRegistrant.Registration.Group.GroupType.DefaultGroupRoleId;
                            if ( groupRoleId.HasValue )
                            {
                                var groupMemberService = new GroupMemberService( newRockContext );
                                var groupMember = groupMemberService
                                    .Queryable().AsNoTracking()
                                    .Where( m =>
                                        m.GroupId == reloadedRegistrant.Registration.Group.Id &&
                                        m.PersonId == reloadedRegistrant.PersonId &&
                                        m.GroupRoleId == groupRoleId.Value )
                                    .FirstOrDefault();
                                if ( groupMember == null )
                                {
                                    groupMember = new GroupMember();
                                    groupMemberService.Add( groupMember );
                                    groupMember.GroupId = reloadedRegistrant.Registration.Group.Id;
                                    groupMember.PersonId = ppPerson.PersonId.Value;
                                    groupMember.GroupRoleId = groupRoleId.Value;
                                    groupMember.GroupMemberStatus = TemplateState.GroupMemberStatus;

                                    newRockContext.SaveChanges();

                                    registrantChanges.Add( string.Format( "Registrant added to {0} group", reloadedRegistrant.Registration.Group.Name ) );
                                }
                                else
                                {
                                    registrantChanges.Add( string.Format( "Registrant group member reference updated to existing person in {0} group", reloadedRegistrant.Registration.Group.Name ) );
                                }

                                reloadedRegistrant.GroupMemberId = groupMember.Id;
                                newRockContext.SaveChanges();
                            }
                        }
                    }
                }

                HistoryService.SaveChanges(
                    rockContext,
                    typeof( Registration ),
                    Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                    registrant.RegistrationId,
                    registrantChanges,
                    "Registrant: " + registrantName,
                    null, null );
            }

            NavigateToRegistration();
        }
Example #3
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (RegistrantState != null)
            {
                RockContext            rockContext                    = new RockContext();
                var                    personService                  = new PersonService(rockContext);
                var                    registrantService              = new RegistrationRegistrantService(rockContext);
                var                    registrantFeeService           = new RegistrationRegistrantFeeService(rockContext);
                var                    registrationTemplateFeeService = new RegistrationTemplateFeeService(rockContext);
                RegistrationRegistrant registrant = null;
                if (RegistrantState.Id > 0)
                {
                    registrant = registrantService.Get(RegistrantState.Id);
                }

                var registrantChanges = new List <string>();

                if (registrant == null)
                {
                    registrant = new RegistrationRegistrant();
                    registrant.RegistrationId = RegistrantState.RegistrationId;
                    registrantService.Add(registrant);
                    registrantChanges.Add("Created Registrant");
                }

                if (!registrant.PersonAliasId.Equals(ppPerson.PersonAliasId))
                {
                    string prevPerson = (registrant.PersonAlias != null && registrant.PersonAlias.Person != null) ?
                                        registrant.PersonAlias.Person.FullName : string.Empty;
                    string newPerson = ppPerson.PersonName;
                    History.EvaluateChange(registrantChanges, "Person", prevPerson, newPerson);
                }
                registrant.PersonAliasId = ppPerson.PersonAliasId.Value;

                // Get the name of registrant for history
                string registrantName = "Unknown";
                if (ppPerson.PersonId.HasValue)
                {
                    var person = personService.Get(ppPerson.PersonId.Value);
                    if (person != null)
                    {
                        registrantName = person.FullName;
                    }
                }

                History.EvaluateChange(registrantChanges, "Cost", registrant.Cost, cbCost.Text.AsDecimal());
                registrant.Cost = cbCost.Text.AsDecimal();

                if (!Page.IsValid)
                {
                    return;
                }

                // Remove/delete any registrant fees that are no longer in UI with quantity
                foreach (var dbFee in registrant.Fees.ToList())
                {
                    if (!RegistrantState.FeeValues.Keys.Contains(dbFee.RegistrationTemplateFeeId) ||
                        RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId] != null ||
                        !RegistrantState.FeeValues[dbFee.RegistrationTemplateFeeId]
                        .Any(f =>
                             f.Option == dbFee.Option &&
                             f.Quantity > 0))
                    {
                        registrantChanges.Add(string.Format("Removed '{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}",
                                                            dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option));

                        registrant.Fees.Remove(dbFee);
                        registrantFeeService.Delete(dbFee);
                    }
                }

                // Add/Update any of the fees from UI
                foreach (var uiFee in RegistrantState.FeeValues.Where(f => f.Value != null))
                {
                    foreach (var uiFeeOption in uiFee.Value)
                    {
                        var dbFee = registrant.Fees
                                    .Where(f =>
                                           f.RegistrationTemplateFeeId == uiFee.Key &&
                                           f.Option == uiFeeOption.Option)
                                    .FirstOrDefault();

                        if (dbFee == null)
                        {
                            dbFee = new RegistrationRegistrantFee();
                            dbFee.RegistrationTemplateFeeId = uiFee.Key;
                            dbFee.Option = uiFeeOption.Option;
                            registrant.Fees.Add(dbFee);
                        }

                        var templateFee = dbFee.RegistrationTemplateFee;
                        if (templateFee == null)
                        {
                            templateFee = registrationTemplateFeeService.Get(uiFee.Key);
                        }

                        string feeName = templateFee != null ? templateFee.Name : "Fee";
                        if (!string.IsNullOrWhiteSpace(uiFeeOption.Option))
                        {
                            feeName = string.Format("{0} ({1})", feeName, uiFeeOption.Option);
                        }

                        if (dbFee.Id <= 0)
                        {
                            registrantChanges.Add(feeName + " Fee Added");
                        }

                        History.EvaluateChange(registrantChanges, feeName + " Quantity", dbFee.Quantity, uiFeeOption.Quantity);
                        dbFee.Quantity = uiFeeOption.Quantity;

                        History.EvaluateChange(registrantChanges, feeName + " Cost", dbFee.Cost, uiFeeOption.Cost);
                        dbFee.Cost = uiFeeOption.Cost;
                    }
                }

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

                // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
                rockContext.WrapTransaction(() =>
                {
                    rockContext.SaveChanges();

                    registrant.LoadAttributes();
                    foreach (var field in TemplateState.Forms
                             .SelectMany(f => f.Fields
                                         .Where(t =>
                                                t.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                                                t.AttributeId.HasValue)))
                    {
                        var attribute = AttributeCache.Read(field.AttributeId.Value);
                        if (attribute != null)
                        {
                            string originalValue = registrant.GetAttributeValue(attribute.Key);
                            var fieldValue       = RegistrantState.FieldValues
                                                   .Where(f => f.Key == field.Id)
                                                   .Select(f => f.Value)
                                                   .FirstOrDefault();
                            string newValue = fieldValue != null ? fieldValue.ToString() : string.Empty;

                            if ((originalValue ?? string.Empty).Trim() != (newValue ?? string.Empty).Trim())
                            {
                                string formattedOriginalValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(originalValue))
                                {
                                    formattedOriginalValue = attribute.FieldType.Field.FormatValue(null, originalValue, attribute.QualifierValues, false);
                                }

                                string formattedNewValue = string.Empty;
                                if (!string.IsNullOrWhiteSpace(newValue))
                                {
                                    formattedNewValue = attribute.FieldType.Field.FormatValue(null, newValue, attribute.QualifierValues, false);
                                }

                                History.EvaluateChange(registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue);
                            }

                            if (fieldValue != null)
                            {
                                registrant.SetAttributeValue(attribute.Key, fieldValue.ToString());
                            }
                        }
                    }

                    registrant.SaveAttributeValues(rockContext);

                    HistoryService.SaveChanges(
                        rockContext,
                        typeof(Registration),
                        Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                        registrant.RegistrationId,
                        registrantChanges,
                        "Registrant: " + registrantName,
                        null, null);
                });

                NavigateToRegistration();
            }
        }