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