Exemple #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);
                var                    registrationTemplateFeeItemService = new RegistrationTemplateFeeItemService(rockContext);
                RegistrationRegistrant registrant = null;
                if (RegistrantState.Id > 0)
                {
                    registrant = registrantService.Get(RegistrantState.Id);
                }

                var previousRegistrantPersonIds = registrantService.Queryable().Where(a => a.RegistrationId == RegistrantState.RegistrationId)
                                                  .Where(r => r.PersonAlias != null)
                                                  .Select(r => r.PersonAlias.PersonId)
                                                  .ToList();

                bool newRegistrant     = false;
                var  registrantChanges = new History.HistoryChangeList();

                if (registrant == null)
                {
                    newRegistrant             = true;
                    registrant                = new RegistrationRegistrant();
                    registrant.RegistrationId = RegistrantState.RegistrationId;
                    registrantService.Add(registrant);
                    registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "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;
                    newRegistrant = true;
                    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;
                    }
                }

                // set their status (wait list / registrant)
                registrant.OnWaitList = !tglWaitList.Checked;

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

                History.EvaluateChange(registrantChanges, "Discount Applies", registrant.DiscountApplies, cbDiscountApplies.Checked);
                registrant.DiscountApplies = cbDiscountApplies.Checked;

                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.RegistrationTemplateFeeItemId == dbFee.RegistrationTemplateFeeItemId &&
                             f.Quantity > 0))
                    {
                        var feeOldValue = string.Format("'{0}' Fee (Quantity:{1:N0}, Cost:{2:C2}, Option:{3}",
                                                        dbFee.RegistrationTemplateFee.Name, dbFee.Quantity, dbFee.Cost, dbFee.Option);

                        registrantChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Fee").SetOldValue(feeOldValue);
                        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.RegistrationTemplateFeeItemId == uiFeeOption.RegistrationTemplateFeeItemId)
                                    .FirstOrDefault();

                        if (dbFee == null)
                        {
                            dbFee = new RegistrationRegistrantFee();
                            dbFee.RegistrationTemplateFeeId = uiFee.Key;
                            var registrationTemplateFeeItem = uiFeeOption.RegistrationTemplateFeeItemId != null?registrationTemplateFeeItemService.GetNoTracking(uiFeeOption.RegistrationTemplateFeeItemId.Value) : null;

                            if (registrationTemplateFeeItem != null)
                            {
                                dbFee.Option = registrationTemplateFeeItem.Name;
                            }

                            dbFee.RegistrationTemplateFeeItemId = uiFeeOption.RegistrationTemplateFeeItemId;
                            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.FeeLabel))
                        {
                            feeName = string.Format("{0} ({1})", feeName, uiFeeOption.FeeLabel);
                        }

                        if (dbFee.Id <= 0)
                        {
                            registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Fee").SetNewValue(feeName);
                        }

                        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 (this.RegistrationTemplate.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 = this.RegistrationTemplate.RequiredSignatureDocumentTemplate.Id;
                        document.AppliesToPersonAliasId      = registrant.PersonAliasId.Value;
                        document.AssignedToPersonAliasId     = registrant.PersonAliasId.Value;
                        document.Name = string.Format(
                            "{0}_{1}",
                            instance != null ? instance.Name : this.RegistrationTemplate.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();
                    // NOTE: We will only have Registration Attributes displayed and editable on Registrant Detail.
                    // To Edit Person or GroupMember Attributes, they will have to go the PersonDetail or GroupMemberDetail blocks
                    foreach (var field in this.RegistrationTemplate.Forms
                             .SelectMany(f => f.Fields
                                         .Where(t =>
                                                t.FieldSource == RegistrationFieldSource.RegistrantAttribute &&
                                                t.AttributeId.HasValue)))
                    {
                        var attribute = AttributeCache.Get(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 && this.RegistrationTemplate.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 == this.RegistrationTemplate.GroupTypeId.Value)
                        {
                            int?groupRoleId = this.RegistrationTemplate.GroupMemberRoleId.HasValue ?
                                              this.RegistrationTemplate.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();
                                    groupMember.GroupId           = reloadedRegistrant.Registration.Group.Id;
                                    groupMember.PersonId          = ppPerson.PersonId.Value;
                                    groupMember.GroupRoleId       = groupRoleId.Value;
                                    groupMember.GroupMemberStatus = this.RegistrationTemplate.GroupMemberStatus;
                                    groupMemberService.Add(groupMember);

                                    newRockContext.SaveChanges();

                                    registrantChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, string.Format("Registrant to {0} group", reloadedRegistrant.Registration.Group.Name));
                                }
                                else
                                {
                                    registrantChanges.AddChange(History.HistoryVerb.Modify, History.HistoryChangeType.Record, string.Format("Registrant to existing person in {0} group", reloadedRegistrant.Registration.Group.Name));
                                }

                                if (reloadedRegistrant.GroupMemberId.HasValue && reloadedRegistrant.GroupMemberId.Value != groupMember.Id)
                                {
                                    groupMemberService.Delete(reloadedRegistrant.GroupMember);
                                    newRockContext.SaveChanges();
                                    registrantChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, string.Format("Registrant to previous person in {0} group", reloadedRegistrant.Registration.Group.Name));
                                }

                                // Record this to the Person's and Registrants Notes and History...

                                reloadedRegistrant.GroupMemberId = groupMember.Id;
                            }
                        }
                        if (reloadedRegistrant.Registration.FirstName.IsNotNullOrWhiteSpace() && reloadedRegistrant.Registration.LastName.IsNotNullOrWhiteSpace())
                        {
                            reloadedRegistrant.Registration.SavePersonNotesAndHistory(reloadedRegistrant.Registration.FirstName, reloadedRegistrant.Registration.LastName, this.CurrentPersonAliasId, previousRegistrantPersonIds);
                        }
                        newRockContext.SaveChanges();
                    }
                }

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

            NavigateToRegistration();
        }
Exemple #2
0
        /// <summary>
        /// Saves the registration.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="hasPayment">if set to <c>true</c> [has payment].</param>
        /// <returns></returns>
        private Registration SaveRegistration( RockContext rockContext, bool hasPayment )
        {
            var registrationService = new RegistrationService( rockContext );
            var registrantService = new RegistrationRegistrantService( rockContext );
            var personService = new PersonService( rockContext );
            var groupMemberService = new GroupMemberService( rockContext );

            // variables to keep track of the family that new people should be added to
            int? singleFamilyId = null;
            var multipleFamilyGroupIds = new Dictionary<Guid, int>();

            var dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() );
            var dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() );
            var familyGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY );
            var adultRoleId = familyGroupType.Roles
                .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid() ) )
                .Select( r => r.Id )
                .FirstOrDefault();
            var childRoleId = familyGroupType.Roles
                .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid() ) )
                .Select( r => r.Id )
                .FirstOrDefault();

            var registration = new Registration();
            registrationService.Add( registration );
            registration.RegistrationInstanceId = RegistrationInstanceState.Id;
            registration.GroupId = GroupId;
            registration.FirstName = RegistrationState.FirstName;
            registration.LastName = RegistrationState.LastName;
            registration.ConfirmationEmail = RegistrationState.ConfirmationEmail;
            registration.DiscountCode = RegistrationState.DiscountCode;
            registration.DiscountAmount = RegistrationState.DiscountAmount;
            registration.DiscountPercentage = RegistrationState.DiscountPercentage;

            // If the 'your name' value equals the currently logged in person, use their person alias id
            if ( CurrentPerson != null &&
                ( CurrentPerson.NickName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ||
                    CurrentPerson.FirstName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ) &&
                CurrentPerson.LastName.Trim().Equals( registration.LastName.Trim(), StringComparison.OrdinalIgnoreCase ) )
            {
                registration.PersonAliasId = CurrentPerson.PrimaryAliasId;
            }
            else
            {
                // otherwise look for one and one-only match by name/email
                var personMatches = personService.GetByMatch( registration.FirstName, registration.LastName, registration.ConfirmationEmail );
                if ( personMatches.Count() == 1 )
                {
                    registration.PersonAliasId = personMatches.First().PrimaryAliasId;
                }
            }

            // If the registration includes a payment, make sure there's an actual person associated to registration
            if ( hasPayment && !registration.PersonAliasId.HasValue )
            {
                // If a match was not found, create a new person
                var person = new Person();
                person.FirstName = registration.FirstName;
                person.LastName = registration.LastName;
                person.IsEmailActive = true;
                person.Email = registration.ConfirmationEmail;
                person.EmailPreference = EmailPreference.EmailAllowed;
                person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id;
                if ( dvcConnectionStatus != null )
                {
                    person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                }
                if ( dvcRecordStatus != null )
                {
                    person.RecordStatusValueId = dvcRecordStatus.Id;
                }

                registration.PersonAliasId = SavePerson( rockContext, person, Guid.NewGuid(), null, null, adultRoleId, childRoleId, multipleFamilyGroupIds, singleFamilyId );
            }

            // Save the registration ( so we can get an id )
            rockContext.SaveChanges();

            // If the Registration Instance linkage specified a group, load it now
            Group group = null;
            if ( GroupId.HasValue )
            {
                group = new GroupService( rockContext ).Get( GroupId.Value );
            }

            // Get each registrant
            foreach ( var registrantInfo in RegistrationState.Registrants )
            {
                var changes = new List<string>();
                var familyChanges = new List<string>();

                Person person = null;

                // Try to find a matching person based on name and email address
                string firstName = registrantInfo.GetFirstName( RegistrationTemplate );
                string lastName = registrantInfo.GetLastName( RegistrationTemplate );
                string email = registrantInfo.GetEmail( RegistrationTemplate );
                var personMatches = personService.GetByMatch( firstName, lastName, email );
                if ( personMatches.Count() == 1 )
                {
                    person = personMatches.First();
                }

                if ( person == null )
                {
                    // If a match was not found, create a new person
                    person = new Person();
                    person.FirstName = firstName;
                    person.LastName = lastName;
                    person.IsEmailActive = true;
                    person.Email = email;
                    person.EmailPreference = EmailPreference.EmailAllowed;
                    person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id;
                    if ( dvcConnectionStatus != null )
                    {
                        person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                    }

                    if ( dvcRecordStatus != null )
                    {
                        person.RecordStatusValueId = dvcRecordStatus.Id;
                    }
                }

                int? campusId = null;
                Location location = null;

                // Set any of the template's person fields
                foreach ( var field in RegistrationTemplate.Forms
                    .SelectMany( f => f.Fields
                        .Where( t => t.FieldSource == RegistrationFieldSource.PersonField ) ) )
                {
                    // Find the registrant's value
                    var fieldValue = registrantInfo.FieldValues
                        .Where( f => f.Key == field.Id )
                        .Select( f => f.Value )
                        .FirstOrDefault();

                    if ( fieldValue != null )
                    {
                        switch ( field.PersonFieldType )
                        {
                            case RegistrationPersonFieldType.Campus:
                                {
                                    if ( fieldValue != null )
                                    {
                                        campusId = fieldValue.ToString().AsIntegerOrNull();
                                    }
                                    break;
                                }

                            case RegistrationPersonFieldType.Address:
                                {
                                    location = fieldValue.ToString().FromJsonOrNull<Location>();
                                    break;
                                }

                            case RegistrationPersonFieldType.Birthdate:
                                {
                                    var birthMonth = person.BirthMonth;
                                    var birthDay = person.BirthDay;
                                    var birthYear = person.BirthYear;

                                    person.SetBirthDate( fieldValue as DateTime? );

                                    History.EvaluateChange( changes, "Birth Month", birthMonth, person.BirthMonth );
                                    History.EvaluateChange( changes, "Birth Day", birthDay, person.BirthDay );
                                    History.EvaluateChange( changes, "Birth Year", birthYear, person.BirthYear );

                                    break;
                                }

                            case RegistrationPersonFieldType.Gender:
                                {
                                    var newGender = fieldValue.ToString().ConvertToEnumOrNull<Gender>() ?? Gender.Unknown;
                                    History.EvaluateChange( changes, "Gender", person.Gender, newGender );
                                    person.Gender = newGender;
                                    break;
                                }

                            case RegistrationPersonFieldType.MaritalStatus:
                                {
                                    if ( fieldValue != null  )
                                    {
                                        int? newMaritalStatusId = fieldValue.ToString().AsIntegerOrNull();
                                        History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) );
                                        person.MaritalStatusValueId = newMaritalStatusId;
                                    }
                                    break;
                                }

                            case RegistrationPersonFieldType.MobilePhone:
                                {
                                    SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid(), changes );
                                    break;
                                }

                            case RegistrationPersonFieldType.HomePhone:
                                {
                                    SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid(), changes );
                                    break;
                                }

                            case RegistrationPersonFieldType.WorkPhone:
                                {
                                    SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK.AsGuid(), changes );
                                    break;
                                }
                        }
                    }
                }

                // Save the person ( and family if needed )
                SavePerson( rockContext, person, registrantInfo.FamilyGuid, campusId, location, adultRoleId, childRoleId, multipleFamilyGroupIds, singleFamilyId );

                // Load the person's attributes
                person.LoadAttributes();

                // Set any of the template's person fields
                foreach ( var field in RegistrationTemplate.Forms
                    .SelectMany( f => f.Fields
                        .Where( t =>
                            t.FieldSource == RegistrationFieldSource.PersonAttribute &&
                            t.AttributeId.HasValue ) ) )
                {
                    // Find the registrant's value
                    var fieldValue = registrantInfo.FieldValues
                        .Where( f => f.Key == field.Id )
                        .Select( f => f.Value )
                        .FirstOrDefault();

                    if ( fieldValue != null )
                    {
                        var attribute = AttributeCache.Read( field.AttributeId.Value );
                        if ( attribute != null )
                        {
                            string originalValue = person.GetAttributeValue( attribute.Key );
                            string newValue = fieldValue.ToString();
                            person.SetAttributeValue( attribute.Key, fieldValue.ToString() );

                            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( changes, attribute.Name, formattedOriginalValue, formattedNewValue );
                            }
                        }
                    }
                }

                person.SaveAttributeValues( rockContext );

                GroupMember groupMember = null;

                // If the registration instance linkage specified a group to add registrant to, add them if there not already
                // part of that group
                if ( group != null )
                {
                    groupMember = group.Members.Where( m => m.PersonId == person.Id ).FirstOrDefault();
                    if ( groupMember == null && group.GroupType.DefaultGroupRoleId.HasValue )
                    {
                        groupMember = new GroupMember();
                        groupMemberService.Add( groupMember );
                        groupMember.GroupId = group.Id;
                        groupMember.PersonId = person.Id;

                        if ( RegistrationTemplate.GroupTypeId.HasValue &&
                            RegistrationTemplate.GroupTypeId == group.GroupTypeId &&
                            RegistrationTemplate.GroupMemberRoleId.HasValue )
                        {
                            groupMember.GroupRoleId = RegistrationTemplate.GroupMemberRoleId.Value;
                            groupMember.GroupMemberStatus = RegistrationTemplate.GroupMemberStatus;
                        }
                        else
                        {
                            groupMember.GroupRoleId = group.GroupType.DefaultGroupRoleId.Value;
                            groupMember.GroupMemberStatus = GroupMemberStatus.Active;
                        }
                    }

                    rockContext.SaveChanges();

                    // Set any of the template's group member attributes
                    groupMember.LoadAttributes();

                    foreach ( var field in RegistrationTemplate.Forms
                        .SelectMany( f => f.Fields
                            .Where( t =>
                                t.FieldSource == RegistrationFieldSource.GroupMemberAttribute &&
                                t.AttributeId.HasValue ) ) )
                    {
                        // Find the registrant's value
                        var fieldValue = registrantInfo.FieldValues
                            .Where( f => f.Key == field.Id )
                            .Select( f => f.Value )
                            .FirstOrDefault();

                        if ( fieldValue != null )
                        {
                            var attribute = AttributeCache.Read( field.AttributeId.Value );
                            if ( attribute != null )
                            {
                                groupMember.SetAttributeValue( attribute.Key, fieldValue.ToString() );
                            }
                        }
                    }

                    groupMember.SaveAttributeValues( rockContext );
                }

                var registrant = new RegistrationRegistrant();
                registrantService.Add( registrant );
                registrant.RegistrationId = registration.Id;
                registrant.PersonAliasId = person.PrimaryAliasId;
                registrant.Cost = registrantInfo.Cost;
                registrant.GroupMemberId = groupMember != null ? groupMember.Id : (int?)null;

                // Add or Update fees
                foreach ( var feeValue in registrantInfo.FeeValues.Where( f => f.Value != null ) )
                {
                    foreach ( var uiFee in feeValue.Value )
                    {
                        var fee = new RegistrationRegistrantFee();
                        registrant.Fees.Add( fee );
                        fee.RegistrationTemplateFeeId = feeValue.Key;
                        fee.Option = uiFee.Option;
                        fee.Quantity = uiFee.Quantity;
                        fee.Cost = uiFee.Cost;
                    }
                }

                rockContext.SaveChanges();

                // Set any of the templat's registrant attributes
                registrant.LoadAttributes();
                foreach ( var field in RegistrationTemplate.Forms
                    .SelectMany( f => f.Fields
                        .Where( t =>
                            t.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                            t.AttributeId.HasValue ) ) )
                {
                    // Find the registrant's value
                    var fieldValue = registrantInfo.FieldValues
                        .Where( f => f.Key == field.Id )
                        .Select( f => f.Value )
                        .FirstOrDefault();

                    if ( fieldValue != null )
                    {
                        var attribute = AttributeCache.Read( field.AttributeId.Value );
                        if ( attribute != null )
                        {
                            registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() );
                        }
                    }

                    registrant.SaveAttributeValues( rockContext );
                }
            }

            return registration;
        }
        /// <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();
        }
        /// <summary>
        /// Saves the registration.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="hasPayment">if set to <c>true</c> [has payment].</param>
        /// <returns></returns>
        private Registration SaveRegistration( RockContext rockContext, bool hasPayment )
        {
            var registrationService = new RegistrationService( rockContext );
            var registrantService = new RegistrationRegistrantService( rockContext );
            var registrantFeeService = new RegistrationRegistrantFeeService( rockContext );
            var personService = new PersonService( rockContext );
            var groupService = new GroupService( rockContext );

            // variables to keep track of the family that new people should be added to
            int? singleFamilyId = null;
            var multipleFamilyGroupIds = new Dictionary<Guid, int>();

            var dvcConnectionStatus = DefinedValueCache.Read( GetAttributeValue( "ConnectionStatus" ).AsGuid() );
            var dvcRecordStatus = DefinedValueCache.Read( GetAttributeValue( "RecordStatus" ).AsGuid() );
            var familyGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY );
            var adultRoleId = familyGroupType.Roles
                .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid() ) )
                .Select( r => r.Id )
                .FirstOrDefault();
            var childRoleId = familyGroupType.Roles
                .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid() ) )
                .Select( r => r.Id )
                .FirstOrDefault();

            bool newRegistration = false;
            Registration registration = null;
            Person registrar = null;
            var registrationChanges = new List<string>();

            if ( RegistrationState.RegistrationId.HasValue )
            {
                registration = registrationService.Get( RegistrationState.RegistrationId.Value );
            }

            if ( registration == null )
            {
                newRegistration = true;
                registration = new Registration();
                registrationService.Add( registration );
                registrationChanges.Add( "Created Registration" );
            }
            else
            {
                if ( registration.PersonAlias != null && registration.PersonAlias.Person != null )
                {
                    registrar = registration.PersonAlias.Person;
                }
            }

            registration.RegistrationInstanceId = RegistrationInstanceState.Id;

            // If the Registration Instance linkage specified a group, load it now
            Group group = null;
            if ( GroupId.HasValue )
            {
                group = new GroupService( rockContext ).Get( GroupId.Value );
                if ( group != null && ( !registration.GroupId.HasValue || registration.GroupId.Value != group.Id ) )
                {
                    registration.GroupId = group.Id;
                    History.EvaluateChange( registrationChanges, "Group", string.Empty, group.Name );
                }
            }

            bool newRegistrar = newRegistration ||
                registration.FirstName == null || !registration.FirstName.Equals( RegistrationState.FirstName, StringComparison.OrdinalIgnoreCase ) ||
                registration.LastName == null || !registration.LastName.Equals( RegistrationState.LastName, StringComparison.OrdinalIgnoreCase );

            History.EvaluateChange( registrationChanges, "First Name", registration.FirstName, RegistrationState.FirstName );
            registration.FirstName = RegistrationState.FirstName;

            History.EvaluateChange( registrationChanges, "Last Name", registration.LastName, RegistrationState.LastName );
            registration.LastName = RegistrationState.LastName;

            History.EvaluateChange( registrationChanges, "Confirmation Email", registration.ConfirmationEmail, RegistrationState.ConfirmationEmail );
            registration.ConfirmationEmail = RegistrationState.ConfirmationEmail;

            History.EvaluateChange( registrationChanges, "Discount Code", registration.DiscountCode, RegistrationState.DiscountCode );
            registration.DiscountCode = RegistrationState.DiscountCode;

            History.EvaluateChange( registrationChanges, "Discount Percentage", registration.DiscountPercentage, RegistrationState.DiscountPercentage );
            registration.DiscountPercentage = RegistrationState.DiscountPercentage;

            History.EvaluateChange( registrationChanges, "Discount Amount", registration.DiscountAmount, RegistrationState.DiscountAmount );
            registration.DiscountAmount = RegistrationState.DiscountAmount;

            if ( newRegistrar )
            {
                if ( CurrentPerson != null && CurrentPerson.NickName == null )
                {
                    CurrentPerson.NickName = CurrentPerson.FirstName;
                }

                // If the 'your name' value equals the currently logged in person, use their person alias id
                if ( CurrentPerson != null &&
                ( CurrentPerson.NickName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ||
                    CurrentPerson.FirstName.Trim().Equals( registration.FirstName.Trim(), StringComparison.OrdinalIgnoreCase ) ) &&
                CurrentPerson.LastName.Trim().Equals( registration.LastName.Trim(), StringComparison.OrdinalIgnoreCase ) )
                {
                    registrar = CurrentPerson;
                    registration.PersonAliasId = CurrentPerson.PrimaryAliasId;

                    // If email that logged in user used is different than their stored email address, update their stored value
                    if ( !string.IsNullOrWhiteSpace( registration.ConfirmationEmail ) &&
                        !registration.ConfirmationEmail.Trim().Equals( CurrentPerson.Email.Trim(), StringComparison.OrdinalIgnoreCase ) &&
                        ( !cbUpdateEmail.Visible || cbUpdateEmail.Checked ) )
                    {
                        var person = personService.Get( CurrentPerson.Id );
                        if ( person != null )
                        {
                            var personChanges = new List<string>();
                            History.EvaluateChange( personChanges, "Email", person.Email, registration.ConfirmationEmail );
                            person.Email = registration.ConfirmationEmail;

                            HistoryService.SaveChanges(
                                new RockContext(),
                                typeof( Person ),
                                Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                person.Id,
                                personChanges, true, CurrentPersonAliasId );
                        }
                    }
                }
                else
                {
                    // otherwise look for one and one-only match by name/email
                    var personMatches = personService.GetByMatch( registration.FirstName, registration.LastName, registration.ConfirmationEmail );
                    if ( personMatches.Count() == 1 )
                    {
                        registrar = personMatches.First();
                        registration.PersonAliasId = registrar.PrimaryAliasId;
                    }
                    else
                    {
                        registrar = null;
                        registration.PersonAlias = null;
                        registration.PersonAliasId = null;
                    }
                }
            }

            // Set the family guid for any other registrants that were selected to be in the same family
            if ( registrar != null )
            {
                var family = registrar.GetFamilies( rockContext ).FirstOrDefault();
                if ( family != null )
                {
                    multipleFamilyGroupIds.AddOrIgnore( RegistrationState.FamilyGuid, family.Id );
                    if ( !singleFamilyId.HasValue )
                    {
                        singleFamilyId = family.Id;
                    }
                }
            }

            // Make sure there's an actual person associated to registration
            if ( !registration.PersonAliasId.HasValue )
            {
                // If a match was not found, create a new person
                var person = new Person();
                person.FirstName = registration.FirstName;
                person.LastName = registration.LastName;
                person.IsEmailActive = true;
                person.Email = registration.ConfirmationEmail;
                person.EmailPreference = EmailPreference.EmailAllowed;
                person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id;
                if ( dvcConnectionStatus != null )
                {
                    person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                }
                if ( dvcRecordStatus != null )
                {
                    person.RecordStatusValueId = dvcRecordStatus.Id;
                }

                registrar = SavePerson( rockContext, person, RegistrationState.FamilyGuid, CampusId, null, adultRoleId, childRoleId, multipleFamilyGroupIds, ref singleFamilyId );
                registration.PersonAliasId = registrar != null ? registrar.PrimaryAliasId : (int?)null;

                History.EvaluateChange( registrationChanges, "Registrar", string.Empty, registrar.FullName );
            }
            else
            {
                if ( newRegistration )
                {
                    History.EvaluateChange( registrationChanges, "Registrar", string.Empty, registration.ToString() );
                }

            }

            // if this registration was marked as temporary (started from another page, then specified in the url), set IsTemporary to False now that we are done
            if ( registration.IsTemporary )
            {
                registration.IsTemporary = false;
            }

            // Save the registration ( so we can get an id )
            rockContext.SaveChanges();
            RegistrationState.RegistrationId = registration.Id;

            try
            {

                Task.Run( () =>
                    HistoryService.SaveChanges(
                        new RockContext(),
                        typeof( Registration ),
                        Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                        registration.Id,
                        registrationChanges, true, CurrentPersonAliasId )
                );

                // Get each registrant
                foreach ( var registrantInfo in RegistrationState.Registrants.ToList() )
                {
                    var registrantChanges = new List<string>();
                    var personChanges = new List<string>();
                    var familyChanges = new List<string>();

                    RegistrationRegistrant registrant = null;
                    Person person = null;

                    string firstName = registrantInfo.GetFirstName( RegistrationTemplate );
                    string lastName = registrantInfo.GetLastName( RegistrationTemplate );
                    string email = registrantInfo.GetEmail( RegistrationTemplate );

                    if ( registrantInfo.Id > 0 )
                    {
                        registrant = registration.Registrants.FirstOrDefault( r => r.Id == registrantInfo.Id );
                        if ( registrant != null )
                        {
                            person = registrant.Person;
                            if ( person != null && (
                                ( registrant.Person.FirstName.Equals( firstName, StringComparison.OrdinalIgnoreCase ) || registrant.Person.NickName.Equals( firstName, StringComparison.OrdinalIgnoreCase ) ) &&
                                registrant.Person.LastName.Equals( lastName, StringComparison.OrdinalIgnoreCase ) ) )
                            {
                                //
                            }
                            else
                            {
                                person = null;
                                registrant.PersonAlias = null;
                                registrant.PersonAliasId = null;
                            }
                        }
                    }

                    if ( person == null )
                    {
                        // Try to find a matching person based on name and email address
                        var personMatches = personService.GetByMatch( firstName, lastName, email );
                        if ( personMatches.Count() == 1 )
                        {
                            person = personMatches.First();
                        }

                        // Try to find a matching person based on name within same family as registrar
                        if ( person == null && registrar != null && registrantInfo.FamilyGuid == RegistrationState.FamilyGuid )
                        {
                            var familyMembers = registrar.GetFamilyMembers( true, rockContext )
                                .Where( m =>
                                    ( m.Person.FirstName == firstName || m.Person.NickName == firstName ) &&
                                    m.Person.LastName == lastName )
                                .Select( m => m.Person )
                                .ToList();

                            if ( familyMembers.Count() == 1 )
                            {
                                person = familyMembers.First();
                                if ( !string.IsNullOrWhiteSpace( email ) )
                                {
                                    person.Email = email;
                                }
                            }

                            if ( familyMembers.Count() > 1 && !string.IsNullOrWhiteSpace( email ) )
                            {
                                familyMembers = familyMembers
                                    .Where( m =>
                                        m.Email != null &&
                                        m.Email.Equals( email, StringComparison.OrdinalIgnoreCase ) )
                                    .ToList();
                                if ( familyMembers.Count() == 1 )
                                {
                                    person = familyMembers.First();
                                }
                            }
                        }
                    }

                    if ( person == null )
                    {
                        // If a match was not found, create a new person
                        person = new Person();
                        person.FirstName = firstName;
                        person.LastName = lastName;
                        person.IsEmailActive = true;
                        person.Email = email;
                        person.EmailPreference = EmailPreference.EmailAllowed;
                        person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id;
                        if ( dvcConnectionStatus != null )
                        {
                            person.ConnectionStatusValueId = dvcConnectionStatus.Id;
                        }

                        if ( dvcRecordStatus != null )
                        {
                            person.RecordStatusValueId = dvcRecordStatus.Id;
                        }
                    }

                    int? campusId = CampusId;
                    Location location = null;

                    // Set any of the template's person fields
                    foreach ( var field in RegistrationTemplate.Forms
                        .SelectMany( f => f.Fields
                            .Where( t => t.FieldSource == RegistrationFieldSource.PersonField ) ) )
                    {
                        // Find the registrant's value
                        var fieldValue = registrantInfo.FieldValues
                            .Where( f => f.Key == field.Id )
                            .Select( f => f.Value.FieldValue )
                            .FirstOrDefault();

                        if ( fieldValue != null )
                        {
                            switch ( field.PersonFieldType )
                            {
                                case RegistrationPersonFieldType.Campus:
                                    {
                                        if ( fieldValue != null )
                                        {
                                            campusId = fieldValue.ToString().AsIntegerOrNull();
                                        }
                                        break;
                                    }

                                case RegistrationPersonFieldType.Address:
                                    {
                                        location = fieldValue as Location;
                                        break;
                                    }

                                case RegistrationPersonFieldType.Birthdate:
                                    {
                                        var birthMonth = person.BirthMonth;
                                        var birthDay = person.BirthDay;
                                        var birthYear = person.BirthYear;

                                        person.SetBirthDate( fieldValue as DateTime? );

                                        History.EvaluateChange( personChanges, "Birth Month", birthMonth, person.BirthMonth );
                                        History.EvaluateChange( personChanges, "Birth Day", birthDay, person.BirthDay );
                                        History.EvaluateChange( personChanges, "Birth Year", birthYear, person.BirthYear );

                                        break;
                                    }

                                case RegistrationPersonFieldType.Grade:
                                    {
                                        var newGraduationYear = fieldValue.ToString().AsIntegerOrNull();
                                        History.EvaluateChange( personChanges, "Graduation Year", person.GraduationYear, newGraduationYear );
                                        person.GraduationYear = newGraduationYear;

                                        break;
                                    }

                                case RegistrationPersonFieldType.Gender:
                                    {
                                        var newGender = fieldValue.ToString().ConvertToEnumOrNull<Gender>() ?? Gender.Unknown;
                                        History.EvaluateChange( personChanges, "Gender", person.Gender, newGender );
                                        person.Gender = newGender;
                                        break;
                                    }

                                case RegistrationPersonFieldType.MaritalStatus:
                                    {
                                        if ( fieldValue != null )
                                        {
                                            int? newMaritalStatusId = fieldValue.ToString().AsIntegerOrNull();
                                            History.EvaluateChange( personChanges, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) );
                                            person.MaritalStatusValueId = newMaritalStatusId;
                                        }
                                        break;
                                    }

                                case RegistrationPersonFieldType.MobilePhone:
                                    {
                                        SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid(), personChanges );
                                        break;
                                    }

                                case RegistrationPersonFieldType.HomePhone:
                                    {
                                        SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid(), personChanges );
                                        break;
                                    }

                                case RegistrationPersonFieldType.WorkPhone:
                                    {
                                        SavePhone( fieldValue, person, Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK.AsGuid(), personChanges );
                                        break;
                                    }
                            }
                        }
                    }

                    // Save the person ( and family if needed )
                    SavePerson( rockContext, person, registrantInfo.FamilyGuid, campusId, location, adultRoleId, childRoleId, multipleFamilyGroupIds, ref singleFamilyId );

                    // Load the person's attributes
                    person.LoadAttributes();

                    // Set any of the template's person fields
                    foreach ( var field in RegistrationTemplate.Forms
                        .SelectMany( f => f.Fields
                            .Where( t =>
                                t.FieldSource == RegistrationFieldSource.PersonAttribute &&
                                t.AttributeId.HasValue ) ) )
                    {
                        // Find the registrant's value
                        var fieldValue = registrantInfo.FieldValues
                            .Where( f => f.Key == field.Id )
                            .Select( f => f.Value.FieldValue )
                            .FirstOrDefault();

                        if ( fieldValue != null )
                        {
                            var attribute = AttributeCache.Read( field.AttributeId.Value );
                            if ( attribute != null )
                            {
                                string originalValue = person.GetAttributeValue( attribute.Key );
                                string newValue = fieldValue.ToString();
                                person.SetAttributeValue( attribute.Key, fieldValue.ToString() );

                                // DateTime values must be stored in ISO8601 format as http://www.rockrms.com/Rock/Developer/BookContent/16/16#datetimeformatting
                                if ( attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE.AsGuid() ) ||
                                    attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE_TIME.AsGuid() ) )
                                {
                                    DateTime aDateTime;
                                    if ( DateTime.TryParse( newValue, out aDateTime ) )
                                    {
                                        newValue = aDateTime.ToString( "o" );
                                    }
                                }

                                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 );
                                    }

                                    Helper.SaveAttributeValue( person, attribute, newValue, rockContext );
                                    History.EvaluateChange( personChanges, attribute.Name, formattedOriginalValue, formattedNewValue );

                                }
                            }
                        }
                    }

                    string registrantName = person.FullName + ": ";

                    personChanges.ForEach( c => registrantChanges.Add( c ) );

                    if ( registrant == null )
                    {
                        registrant = new RegistrationRegistrant();
                        registrant.Guid = registrantInfo.Guid;
                        registrantService.Add( registrant );
                        registrant.RegistrationId = registration.Id;
                    }

                    registrant.PersonAliasId = person.PrimaryAliasId;
                    registrant.Cost = registrantInfo.Cost;

                    // Remove fees
                    // Remove/delete any registrant fees that are no longer in UI with quantity
                    foreach ( var dbFee in registrant.Fees.ToList() )
                    {
                        if ( !registrantInfo.FeeValues.Keys.Contains( dbFee.RegistrationTemplateFeeId ) ||
                            registrantInfo.FeeValues[dbFee.RegistrationTemplateFeeId] == null ||
                            !registrantInfo.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 or Update fees
                    foreach ( var uiFee in registrantInfo.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 = RegistrationTemplate.Fees.Where( f => f.Id == uiFee.Key ).FirstOrDefault();
                            }

                            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;
                        }
                    }

                    rockContext.SaveChanges();
                    registrantInfo.Id = registrant.Id;

                    // Set any of the templat's registrant attributes
                    registrant.LoadAttributes();
                    foreach ( var field in RegistrationTemplate.Forms
                        .SelectMany( f => f.Fields
                            .Where( t =>
                                t.FieldSource == RegistrationFieldSource.RegistrationAttribute &&
                                t.AttributeId.HasValue ) ) )
                    {
                        // Find the registrant's value
                        var fieldValue = registrantInfo.FieldValues
                            .Where( f => f.Key == field.Id )
                            .Select( f => f.Value.FieldValue )
                            .FirstOrDefault();

                        if ( fieldValue != null )
                        {
                            var attribute = AttributeCache.Read( field.AttributeId.Value );
                            if ( attribute != null )
                            {
                                string originalValue = registrant.GetAttributeValue( attribute.Key );
                                string newValue = fieldValue.ToString();
                                registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() );

                                // DateTime values must be stored in ISO8601 format as http://www.rockrms.com/Rock/Developer/BookContent/16/16#datetimeformatting
                                if ( attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE.AsGuid() ) ||
                                    attribute.FieldType.Guid.Equals( Rock.SystemGuid.FieldType.DATE_TIME.AsGuid() ) )
                                {
                                    DateTime aDateTime;
                                    if ( DateTime.TryParse( fieldValue.ToString(), out aDateTime ) )
                                    {
                                        newValue = aDateTime.ToString( "o" );
                                    }
                                }

                                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 );
                                    }

                                    Helper.SaveAttributeValue( registrant, attribute, newValue, rockContext );
                                    History.EvaluateChange( registrantChanges, attribute.Name, formattedOriginalValue, formattedNewValue );
                                }
                            }
                        }
                    }

                    Task.Run( () =>
                        HistoryService.SaveChanges(
                            new RockContext(),
                            typeof( Registration ),
                            Rock.SystemGuid.Category.HISTORY_EVENT_REGISTRATION.AsGuid(),
                            registration.Id,
                            registrantChanges,
                            "Registrant: " + person.FullName,
                            null, null, true, CurrentPersonAliasId )
                    );

                    // Clear this registran't family guid so it's not updated again
                    registrantInfo.FamilyGuid = Guid.Empty;

                }

                rockContext.SaveChanges();
            }

            catch ( Exception ex )
            {
                using ( var newRockContext = new RockContext() )
                {
                    if ( newRegistration )
                    {
                        var newRegistrationService = new RegistrationService( newRockContext );
                        var savedRegistration = new RegistrationService( newRockContext ).Get( registration.Id );
                        if ( savedRegistration != null )
                        {
                            HistoryService.DeleteChanges( newRockContext, typeof( Registration ), savedRegistration.Id );

                            newRegistrationService.Delete( savedRegistration );
                            newRockContext.SaveChanges();
                        }
                    }
                }

                throw ex;
            }

            return registration;
        }
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            // get the registration instance
            Registration registration = new RegistrationService(rockContext).Get(GetAttributeValue(action, "RegistrationId", true).AsInteger());

            if (registration == null)
            {
                errorMessages.Add("The Registration could not be determined or found!");
            }

            // determine the person/p that will be added to the registration instance
            List <Person> people = new List <Person>();
            string        registrantsAttributeValue = GetAttributeValue(action, "Registrants", true);
            var           personAliasGuid           = registrantsAttributeValue.AsGuidOrNull();

            if (personAliasGuid.HasValue)
            {
                var person = new PersonAliasService(rockContext).Queryable()
                             .Where(a => a.Guid.Equals(personAliasGuid.Value))
                             .Select(a => a.Person)
                             .FirstOrDefault();
                if (person != null)
                {
                    people.Add(person);
                }
            }
            if (!people.Any())
            {
                var personIdList = registrantsAttributeValue.SplitDelimitedValues().AsIntegerList();
                if (personIdList.Any())
                {
                    people = new PersonService(rockContext).Queryable()
                             .Where(p => personIdList.Contains(p.Id))
                             .ToList();
                }
            }
            if (!people.Any())
            {
                errorMessages.Add("The Registrant(s) could not be determined or found!");
            }

            // Add registrant(s)
            if (!errorMessages.Any())
            {
                var registrantService = new RegistrationRegistrantService(rockContext);
                foreach (var person in people)
                {
                    if (person.PrimaryAliasId.HasValue)
                    {
                        var registrant = new RegistrationRegistrant();
                        registrant.RegistrationId = registration.Id;
                        registrant.PersonAliasId  = person.PrimaryAliasId.Value;
                        registrantService.Add(registrant);
                    }
                }

                rockContext.SaveChanges();
            }

            errorMessages.ForEach(m => action.AddLogEntry(m, true));

            return(true);
        }
Exemple #6
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);
                }
                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();
        }
Exemple #7
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 registrantService = new RegistrationRegistrantService( rockContext );
                var registrantFeeService = new RegistrationRegistrantFeeService( rockContext );
                RegistrationRegistrant registrant = null;
                if ( RegistrantState.Id > 0 )
                {
                    registrant = registrantService.Get( RegistrantState.Id );
                }

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

                registrant.PersonAliasId = ppPerson.PersonAliasId.Value;
                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 ) )
                    {
                        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 );
                        }
                        dbFee.Quantity = uiFeeOption.Quantity;
                        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 ) ) )
                    {
                        // Find the registrant's value
                        var fieldValue = RegistrantState.FieldValues
                            .Where( f => f.Key == field.Id )
                            .Select( f => f.Value )
                            .FirstOrDefault();

                        if ( fieldValue != null )
                        {
                            var attribute = AttributeCache.Read( field.AttributeId.Value );
                            if ( attribute != null )
                            {
                                registrant.SetAttributeValue( attribute.Key, fieldValue.ToString() );
                            }
                        }

                        registrant.SaveAttributeValues( rockContext );
                    }
                } );

                NavigateToRegistration();
            }
        }