/// <summary> /// Loads the Person Previous Name data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadPersonPreviousName(CSVInstance csvData) { var lookupContext = new RockContext(); var importedPersonPreviousNames = new PersonPreviousNameService(lookupContext).Queryable().Count(p => p.ForeignKey != null); var personPreviousNames = new List <PersonPreviousName>(); var completedItems = 0; ReportProgress(0, string.Format("Verifying person previous name import ({0:N0} already imported).", importedPersonPreviousNames)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var previousPersonNameId = row[PreviousLastNameId] as string; var previousPersonName = row[PreviousLastName] as string; var previousPersonId = row[PreviousLastNamePersonId] as string; var personAliasKey = previousPersonId; var previousNamePersonKeys = GetPersonKeys(personAliasKey); if (previousNamePersonKeys != null) { var previousPersonAliasId = previousNamePersonKeys.PersonAliasId; var previousName = AddPersonPreviousName(lookupContext, previousPersonName, previousPersonAliasId, previousPersonNameId, false); if (previousName.Id == 0) { personPreviousNames.Add(previousName); } } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} person previous names processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SavePersonPreviousNames(personPreviousNames); ReportPartialProgress(); personPreviousNames.Clear(); } } if (personPreviousNames.Any()) { SavePersonPreviousNames(personPreviousNames); } ReportProgress(100, string.Format("Finished person previous name import: {0:N0} previous names processed.", completedItems)); return(completedItems); }
/// <summary> /// Loads the Entity Attribute data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadEntityAttributeValues(CSVInstance csvData) { var lookupContext = new RockContext(); var importedAttributeValues = new AttributeValueService(lookupContext).Queryable().Count(a => a.ForeignKey != null); var entityTypes = EntityTypeCache.All().Where(e => e.IsEntity && e.IsSecured).ToList(); var attributeService = new AttributeService(lookupContext); var attributeValues = new List <AttributeValue>(); var completedItems = 0; var addedItems = 0; int? entityTypeId = null; var prevEntityTypeName = string.Empty; var prevAttributeForeignKey = string.Empty; var prevRockKey = string.Empty; Attribute attribute = null; Type contextModelType = null; System.Data.Entity.DbContext contextDbContext = null; IService contextService = null; IHasAttributes entity = null; var prevAttributeValueEntityId = string.Empty; ReportProgress(0, string.Format("Verifying attribute value import ({0:N0} already imported).", importedAttributeValues)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var entityTypeName = row[AttributeEntityTypeName]; var attributeForeignKey = row[AttributeId]; var rockKey = row[AttributeRockKey]; var attributeValueForeignKey = row[AttributeValueId]; var attributeValueEntityId = row[AttributeValueEntityId]; var attributeValue = row[AttributeValue]; if (!string.IsNullOrWhiteSpace(entityTypeName) && !string.IsNullOrWhiteSpace(attributeValueEntityId) && !string.IsNullOrWhiteSpace(attributeValue) && (!string.IsNullOrEmpty(attributeForeignKey) || !string.IsNullOrEmpty(rockKey))) { var findNewEntity = false; if (!entityTypeId.HasValue || !prevEntityTypeName.Equals(entityTypeName, StringComparison.OrdinalIgnoreCase)) { entityTypeId = entityTypes.FirstOrDefault(et => et.Name.Equals(entityTypeName)).Id; prevEntityTypeName = entityTypeName; findNewEntity = true; contextModelType = entityTypes.FirstOrDefault(et => et.Name.Equals(entityTypeName)).GetEntityType(); contextDbContext = Reflection.GetDbContextForEntityType(contextModelType); if (contextDbContext != null) { contextService = Reflection.GetServiceForEntityType(contextModelType, contextDbContext); } } if (entityTypeId.HasValue && contextService != null) { if (!string.IsNullOrWhiteSpace(attributeForeignKey) && !prevAttributeForeignKey.Equals(attributeForeignKey, StringComparison.OrdinalIgnoreCase)) { attribute = attributeService.GetByEntityTypeId(entityTypeId).FirstOrDefault(a => a.ForeignKey == attributeForeignKey); prevAttributeForeignKey = attributeForeignKey; prevRockKey = string.Empty; } else if (string.IsNullOrWhiteSpace(attributeForeignKey)) { // if no FK provided force attribute to null so the rockKey is tested attribute = null; } if (attribute == null && !string.IsNullOrWhiteSpace(rockKey) && !prevRockKey.Equals(rockKey, StringComparison.OrdinalIgnoreCase)) { attribute = attributeService.GetByEntityTypeId(entityTypeId).FirstOrDefault(a => a.Key == rockKey); prevRockKey = rockKey; prevAttributeForeignKey = string.Empty; } if (attribute != null) { // set the fk if it wasn't for some reason if (string.IsNullOrWhiteSpace(attribute.ForeignKey) && !string.IsNullOrWhiteSpace(attributeForeignKey)) { var updatedAttributeRockContext = new RockContext(); var updatedAttributeService = new AttributeService(updatedAttributeRockContext); var updatedAttribute = updatedAttributeService.GetByEntityTypeId(entityTypeId).FirstOrDefault(a => a.Id == attribute.Id); updatedAttribute.ForeignKey = attributeForeignKey; updatedAttribute.ForeignId = attributeForeignKey.AsIntegerOrNull(); updatedAttributeRockContext.SaveChanges(DisableAuditing); } if (entity == null || (findNewEntity || !prevAttributeValueEntityId.Equals(attributeValueEntityId, StringComparison.OrdinalIgnoreCase))) { MethodInfo qryMethod = contextService.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(contextService, new object[] { }) as IQueryable <IEntity>; var entityResult = entityQry.Where(e => e.ForeignKey.Equals(attributeValueEntityId, StringComparison.OrdinalIgnoreCase)); entity = entityResult.FirstOrDefault() as IHasAttributes; prevAttributeValueEntityId = attributeValueEntityId; } if (entity != null) { var av = CreateEntityAttributeValue(lookupContext, attribute, entity, attributeValue, attributeValueForeignKey); if (av != null && !attributeValues.Where(e => e.EntityId == av.EntityId).Where(a => a.AttributeId == av.AttributeId).Any()) { attributeValues.Add(av); addedItems++; } } } } } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} attribute values processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SaveAttributeValues(lookupContext, attributeValues); attributeValues.Clear(); lookupContext.Dispose(); lookupContext = new RockContext(); attributeService = new AttributeService(lookupContext); ReportPartialProgress(); } } if (attributeValues.Any()) { SaveAttributeValues(lookupContext, attributeValues); } ReportProgress(100, string.Format("Finished attribute value import: {0:N0} attribute values imported.", addedItems)); return(completedItems); }
/// <summary> /// Loads the Phone Number data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadPhoneNumber(CSVInstance csvData) { var lookupContext = new RockContext(); var importedPhoneNumbers = new PhoneNumberService(lookupContext).Queryable().Count(n => n.ForeignKey != null); var phoneTypeValues = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_PHONE_TYPE), lookupContext).DefinedValues; var phoneNumberList = new List <PhoneNumber>(); var skippedPhoneNumbers = new Dictionary <string, string>(); var completedItems = 0; ReportProgress(0, string.Format("Verifying phone number import ({0:N0} already imported).", importedPhoneNumbers)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var personKey = row[PhonePersonId] as string; var phoneType = row[PhoneType] as string; var phoneNumber = row[Phone] as string; var phoneKey = row[PhoneId] as string; var personKeys = GetPersonKeys(personKey); // create user-defined phone type if it doesn't exist var phoneTypeId = phoneTypeValues.Where(dv => dv.Value.Equals(phoneType, StringComparison.OrdinalIgnoreCase)) .Select(dv => ( int? )dv.Id).FirstOrDefault(); if (!phoneTypeId.HasValue) { var newPhoneType = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.PERSON_PHONE_TYPE, phoneType); if (newPhoneType != null) { phoneTypeValues.Add(newPhoneType); phoneTypeId = newPhoneType.Id; } } if (personKeys != null && personKeys.PersonId > 0 && !string.IsNullOrWhiteSpace(phoneNumber)) { var isMessagingEnabled = ( bool )ParseBoolOrDefault(row[PhoneIsMessagingEnabled], false); var isUnlisted = ( bool )ParseBoolOrDefault(row[PhoneIsUnlisted], false); var phoneId = phoneKey.AsType <int?>(); var extension = string.Empty; var countryCode = PhoneNumber.DefaultCountryCode(); var normalizedNumber = string.Empty; var countryIndex = phoneNumber.IndexOf('+'); var extensionIndex = phoneNumber.LastIndexOf('x') > 0 ? phoneNumber.LastIndexOf('x') : phoneNumber.Length; if (countryIndex >= 0 && phoneNumber.Length > (countryIndex + 3)) { countryCode = phoneNumber.Substring(countryIndex, countryIndex + 3).AsNumeric(); normalizedNumber = phoneNumber.Substring(countryIndex + 3, extensionIndex - 3).AsNumeric().TrimStart(new Char[] { '0' }); extension = phoneNumber.Substring(extensionIndex); } else if (extensionIndex > 0) { normalizedNumber = phoneNumber.Substring(0, extensionIndex).AsNumeric(); extension = phoneNumber.Substring(extensionIndex).AsNumeric(); } else { normalizedNumber = phoneNumber.AsNumeric(); } if (!string.IsNullOrWhiteSpace(normalizedNumber)) { var currentNumber = new PhoneNumber(); currentNumber.PersonId = personKeys.PersonId; currentNumber.CountryCode = countryCode; currentNumber.CreatedByPersonAliasId = ImportPersonAliasId; currentNumber.Extension = extension.Left(20); currentNumber.Number = normalizedNumber.TrimStart(new char[] { '0' }).Left(20); currentNumber.NumberFormatted = PhoneNumber.FormattedNumber(currentNumber.CountryCode, currentNumber.Number); currentNumber.NumberTypeValueId = phoneTypeId; if (phoneType.Equals("Mobile", StringComparison.OrdinalIgnoreCase)) { currentNumber.IsMessagingEnabled = isMessagingEnabled; } currentNumber.IsUnlisted = isUnlisted; phoneNumberList.Add(currentNumber); completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} phone numbers processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SavePhoneNumbers(phoneNumberList); ReportPartialProgress(); phoneNumberList.Clear(); } } } else { if (!skippedPhoneNumbers.ContainsKey(phoneKey)) { skippedPhoneNumbers.Add(phoneKey, phoneType); } } } if (phoneNumberList.Any()) { SavePhoneNumbers(phoneNumberList); } if (skippedPhoneNumbers.Any()) { ReportProgress(0, "The following phone numbers could not be imported and were skipped:"); foreach (var key in skippedPhoneNumbers) { ReportProgress(0, string.Format("{0} phone type for Foreign ID {1}.", key.Value, key)); } } ReportProgress(100, string.Format("Finished phone number import: {0:N0} phone numbers imported.", completedItems)); return(completedItems); }
/// <summary> /// Loads the family data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadFamily(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var locationService = new LocationService(lookupContext); var newGroupLocations = new Dictionary <GroupLocation, string>(); var currentFamilyGroup = new Group(); var newFamilyList = new List <Group>(); var updatedFamilyList = new List <Group>(); var dateFormats = new[] { "yyyy-MM-dd", "MM/dd/yyyy", "MM/dd/yy" }; var currentFamilyKey = string.Empty; var completed = 0; ReportProgress(0, $"Starting family import ({ImportedFamilies.Count():N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowFamilyKey = row[FamilyId]; var rowFamilyId = rowFamilyKey.AsType <int?>(); var rowFamilyName = row[FamilyName]; if (rowFamilyKey != null && rowFamilyKey != currentFamilyGroup.ForeignKey) { currentFamilyGroup = ImportedFamilies.FirstOrDefault(g => g.ForeignKey == rowFamilyKey); if (currentFamilyGroup == null) { currentFamilyGroup = new Group { ForeignKey = rowFamilyKey, ForeignId = rowFamilyId, CreatedByPersonAliasId = ImportPersonAliasId, GroupTypeId = FamilyGroupTypeId }; newFamilyList.Add(currentFamilyGroup); } else if (!lookupContext.ChangeTracker.Entries <Group>().Any(g => g.Entity.ForeignKey == rowFamilyKey || (g.Entity.ForeignKey == null && g.Entity.ForeignId == rowFamilyId))) { // track changes if not currently tracking lookupContext.Groups.Attach(currentFamilyGroup); } currentFamilyGroup.Name = row[FamilyName]; // Set the family campus var campusName = row[Campus]; if (!string.IsNullOrWhiteSpace(campusName)) { var familyCampus = CampusList.FirstOrDefault(c => c.Name.Equals(campusName, StringComparison.OrdinalIgnoreCase) || c.ShortCode.Equals(campusName, StringComparison.OrdinalIgnoreCase)); if (familyCampus == null) { familyCampus = new Campus { IsSystem = false, Name = campusName, ShortCode = campusName.RemoveWhitespace(), IsActive = true }; lookupContext.Campuses.Add(familyCampus); lookupContext.SaveChanges(DisableAuditing); CampusList.Add(familyCampus); } currentFamilyGroup.CampusId = familyCampus.Id; lookupContext.SaveChanges(DisableAuditing); } // Add the family addresses since they exist in this file var famAddress = row[Address]; var famAddress2 = row[Address2]; var famCity = row[City]; var famState = row[State]; var famZip = row[Zip]; var famCountry = row[Country]; var primaryAddress = locationService.Get(famAddress.Left(100), famAddress2.Left(100), famCity, famState, famZip, famCountry, verifyLocation: false); if (primaryAddress != null && currentFamilyGroup.GroupLocations.Count == 0) { var primaryLocation = new GroupLocation { LocationId = primaryAddress.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = HomeLocationTypeId }; newGroupLocations.Add(primaryLocation, rowFamilyKey); } var famSecondAddress = row[SecondaryAddress]; var famSecondAddress2 = row[SecondaryAddress2]; var famSecondCity = row[SecondaryCity]; var famSecondState = row[SecondaryState]; var famSecondZip = row[SecondaryZip]; var famSecondCountry = row[SecondaryCountry]; var secondaryAddress = locationService.Get(famSecondAddress.Left(100), famSecondAddress2.Left(100), famSecondCity, famSecondState, famSecondZip, famSecondCountry, verifyLocation: false); if (secondaryAddress != null && currentFamilyGroup.GroupLocations.Count < 2) { var secondaryLocation = new GroupLocation { LocationId = secondaryAddress.Id, IsMailingLocation = true, IsMappedLocation = false, GroupLocationTypeValueId = PreviousLocationTypeId }; newGroupLocations.Add(secondaryLocation, rowFamilyKey); } DateTime createdDateValue; if (DateTime.TryParseExact(row[CreatedDate], dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out createdDateValue)) { currentFamilyGroup.CreatedDateTime = createdDateValue; currentFamilyGroup.ModifiedDateTime = ImportDateTime; } else { currentFamilyGroup.CreatedDateTime = ImportDateTime; currentFamilyGroup.ModifiedDateTime = ImportDateTime; } completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} families imported."); } if (completed % ReportingNumber < 1) { SaveFamilies(newFamilyList, newGroupLocations); ReportPartialProgress(); // Reset lookup context lookupContext.SaveChanges(); lookupContext.Dispose(); lookupContext = new RockContext(); locationService = new LocationService(lookupContext); newFamilyList.Clear(); newGroupLocations.Clear(); } } } // Check to see if any rows didn't get saved to the database if (newGroupLocations.Any()) { SaveFamilies(newFamilyList, newGroupLocations); } lookupContext.SaveChanges(); DetachAllInContext(lookupContext); lookupContext.Dispose(); ReportProgress(0, $"Finished family import: {completed:N0} families added or updated."); return(completed); }
/// <summary> /// Loads the named location data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadNamedLocation(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var locationTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.LOCATION_TYPE), lookupContext).DefinedValues; int numImportedNamedLocations = ImportedLocations.Count(c => c.Name != null); var newNamedLocationList = new List <Location>(); int completed = 0; ReportProgress(0, string.Format("Starting named location import ({0:N0} already exist).", numImportedNamedLocations)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { string rowNamedLocationName = row[NamedLocationName]; string rowNamedLocationKey = row[NamedLocationId]; // Check that this location isn't already in our data bool locationExists = false; if (ImportedLocations.Count() > 0) { locationExists = ImportedLocations.Any(l => l.ForeignKey.Equals(rowNamedLocationKey)); } // Check if this was an existing location that needs foreign id added if (!locationExists) { var location = new LocationService(lookupContext).Queryable().FirstOrDefault(l => (l.ForeignKey == null || l.ForeignKey.Trim() == "") && l.Name.Equals(rowNamedLocationName, StringComparison.OrdinalIgnoreCase)); if (location != null) { location.ForeignKey = rowNamedLocationKey; location.ForeignId = rowNamedLocationKey.AsIntegerOrNull(); location.ForeignGuid = rowNamedLocationKey.AsGuidOrNull(); lookupContext.SaveChanges(); locationExists = true; ImportedLocations.Add(location); completed++; } } if (!string.IsNullOrWhiteSpace(rowNamedLocationKey) && !locationExists) { string rowNamedLocationCreatedDate = row[NamedLocationCreatedDate]; string rowNamedLocationType = row[NamedLocationType]; string rowNamedLocationParent = row[NamedLocationParent]; string rowNamedLocationSoftRoomThreshold = row[NamedLocationSoftRoomThreshold]; string rowNamedLocationFirmRoomThreshold = row[NamedLocationFirmRoomThreshold]; int? rowSoftThreshold = rowNamedLocationSoftRoomThreshold.AsType <int?>(); int? rowFirmThreshold = rowNamedLocationFirmRoomThreshold.AsType <int?>(); int? rowNamedLocationId = rowNamedLocationKey.AsType <int?>(); Location newLocation = new Location(); newLocation.Name = rowNamedLocationName; newLocation.CreatedDateTime = ParseDateOrDefault(rowNamedLocationCreatedDate, ImportDateTime); newLocation.ModifiedDateTime = ImportDateTime; newLocation.CreatedByPersonAliasId = ImportPersonAliasId; newLocation.ModifiedByPersonAliasId = ImportPersonAliasId; newLocation.ForeignKey = rowNamedLocationKey; newLocation.ForeignId = rowNamedLocationId; if (rowSoftThreshold != null && rowSoftThreshold > 0) { newLocation.SoftRoomThreshold = rowSoftThreshold; } if (rowFirmThreshold != null && rowFirmThreshold > 0) { newLocation.FirmRoomThreshold = rowFirmThreshold; } if (!string.IsNullOrWhiteSpace(rowNamedLocationType)) { var locationTypeId = locationTypes.Where(v => v.Value.Equals(rowNamedLocationType) || v.Id.Equals(rowNamedLocationType) || v.Guid.ToString().ToLower().Equals(rowNamedLocationType.ToLower())) .Select(v => ( int? )v.Id).FirstOrDefault(); newLocation.LocationTypeValueId = locationTypeId; } if (!string.IsNullOrWhiteSpace(rowNamedLocationParent)) { int?parentLocationId = ImportedLocations.FirstOrDefault(l => l.ForeignKey.Equals(rowNamedLocationParent) || (l.Name != null && l.Name.Equals(rowNamedLocationParent))).Id; newLocation.ParentLocationId = parentLocationId; } newNamedLocationList.Add(newLocation); // // Save Every Loop // SaveNamedLocation(newNamedLocationList); newNamedLocationList.Clear(); // // Keep the user informed as to what is going on and save in batches. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} groups imported.", completed)); } if (completed % ReportingNumber < 1) { ReportPartialProgress(); } } } // // Check to see if any rows didn't get saved to the database // if (newNamedLocationList.Any()) { SaveNamedLocation(newNamedLocationList); } lookupContext.SaveChanges(); DetachAllInContext(lookupContext); lookupContext.Dispose(); ReportProgress(0, string.Format("Finished named location import: {0:N0} named locations added or updated.", completed)); return(completed); }
/// <summary> /// Loads the ContentChannelItem data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadContentChannelItem(CSVInstance csvData) { var lookupContext = new RockContext(); var contentChannelItemService = new ContentChannelItemService(lookupContext); var contentChannelService = new ContentChannelService(lookupContext); var contentChannelTypeService = new ContentChannelTypeService(lookupContext); // Look for custom attributes in the Content Channel file var allFields = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList(); var customAttributes = allFields .Where(f => f.index > ItemParentId) .ToDictionary(f => f.index, f => f.node.Name); // Set the supported date formats var dateFormats = new[] { "yyyy-MM-dd", "MM/dd/yyyy", "MM/dd/yy", "M/d/yyyy", "M/dd/yyyy", "M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", "M/d/yyyy h:mm", "M/d/yyyy h:mm", "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm", "yyyy-MM-dd HH:mm:ss" }; var importedChannelIds = new List <int>(); var completed = 0; var importedCount = 0; var alreadyImportedCount = contentChannelItemService.Queryable().AsNoTracking().Count(i => i.ForeignKey != null); ReportProgress(0, $"Starting Content Channel Item import ({alreadyImportedCount:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowContentChannelName = row[ContentChannelName]; var rowContentChannelItemTitle = row[ItemTitle]; var rowContentChannelItemContent = row[ItemContent]; var rowContentChannelItemId = row[ItemId]; var rowContentChannelItemParentId = row[ItemParentId]; var rowChannelItemId = rowContentChannelItemId.AsType <int?>(); ContentChannel contentChannel = null; if (contentChannelService.Queryable().AsNoTracking().FirstOrDefault(t => t.Name.ToLower() == rowContentChannelName.ToLower()) != null) { contentChannel = contentChannelService.Queryable().AsNoTracking().FirstOrDefault(c => c.Name.ToLower() == rowContentChannelName.ToLower()); } // // Verify the Content Channel exists. // if (contentChannel.Id < 1) { throw new System.Collections.Generic.KeyNotFoundException($"Content Channel {rowContentChannelName} not found", null); } // // Get content channel type // var contentChannelTypeId = contentChannelService.Queryable().AsNoTracking().FirstOrDefault(c => c.Id == contentChannel.Id).ContentChannelTypeId; // // Check that this Content Channel Item doesn't already exist. // var exists = false; if (alreadyImportedCount > 0) { exists = contentChannelItemService.Queryable().AsNoTracking().Any(i => i.ForeignKey == rowContentChannelItemId); } if (!exists) { // // Create and populate the new Content Channel. // var contentChannelItem = new ContentChannelItem { Title = rowContentChannelItemTitle, Status = ContentChannelItemStatus.Approved, Content = rowContentChannelItemContent, ForeignKey = rowContentChannelItemId, ForeignId = rowChannelItemId, ContentChannelId = contentChannel.Id, ContentChannelTypeId = contentChannelTypeId }; DateTime startDateValue; if (DateTime.TryParseExact(row[ItemStart], dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDateValue)) { contentChannelItem.StartDateTime = startDateValue; } DateTime expireDateValue; if (DateTime.TryParseExact(row[ItemExpire], dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out expireDateValue) && expireDateValue != System.DateTime.MinValue) { contentChannelItem.ExpireDateTime = expireDateValue; } if (contentChannel.RequiresApproval) { contentChannelItem.Status = ContentChannelItemStatus.Approved; contentChannelItem.ApprovedDateTime = ImportDateTime; contentChannelItem.ApprovedByPersonAliasId = ImportPersonAliasId; } // Save changes for context lookupContext.WrapTransaction(() => { lookupContext.ContentChannelItems.Add(contentChannelItem); lookupContext.SaveChanges(DisableAuditing); }); // // Look for Parent Id and create appropriate objects. // if (!string.IsNullOrWhiteSpace(rowContentChannelItemParentId)) { var parentFound = false; parentFound = contentChannelItemService.Queryable().AsNoTracking().Any(i => i.ForeignKey == rowContentChannelItemParentId); if (parentFound) { var parentItem = contentChannelItemService.Queryable().FirstOrDefault(i => i.ForeignKey == rowContentChannelItemParentId); var service = new ContentChannelItemAssociationService(lookupContext); var order = service.Queryable().AsNoTracking() .Where(a => a.ContentChannelItemId == parentItem.Id) .Select(a => ( int? )a.Order) .DefaultIfEmpty() .Max(); var assoc = new ContentChannelItemAssociation(); assoc.ContentChannelItemId = parentItem.Id; assoc.ChildContentChannelItemId = contentChannelItem.Id; assoc.Order = order.HasValue ? order.Value + 1 : 0; service.Add(assoc); lookupContext.SaveChanges(DisableAuditing); } } // // Process Attributes for Content Channel Items // if (customAttributes.Any()) { // create content channel item attributes, but only if not already processed in this csv file if (!importedChannelIds.Contains(contentChannel.Id)) { // add current content channel id to list so we don't process multiple times importedChannelIds.Add(contentChannel.Id); // create content channel item attributes foreach (var newAttributePair in customAttributes) { var pairs = newAttributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; var fieldTypeId = TextFieldTypeId; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } var definedValueForeignId = definedValueForeignKey.AsType <int?>(); // // Translate the provided attribute type into one we know about. // fieldTypeId = GetAttributeFieldType(attributeTypeString); if (string.IsNullOrEmpty(attributeName)) { LogException($"Content Channel {contentChannelItem.ContentChannel.Name}", $"Content Channel {contentChannelItem.ContentChannel.Name} Item Attribute Name cannot be blank '{newAttributePair.Value}'."); } else { // // First try to find the existing attribute, if not found then add a new one. // var fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = $"Bulldozer_ContentChannelItem_{contentChannel.Name.RemoveWhitespace()}_{categoryName.RemoveWhitespace()}_{attributeName.RemoveWhitespace()}".Left(100); } else { fk = attributeForeignKey; } AddEntityAttribute(lookupContext, contentChannelItem.TypeId, "ContentChannelId", contentChannelItem.ContentChannelId.ToString(), fk, categoryName, attributeName, string.Empty, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); } } // end add attributes } // end test for first run // // Add any Content Channel Item attribute values // foreach (var attributePair in customAttributes) { var newValue = row[attributePair.Key]; if (!string.IsNullOrWhiteSpace(newValue)) { var pairs = attributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } if (!string.IsNullOrEmpty(attributeName)) { string fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = $"Bulldozer_ContentChannelItem_{contentChannel.Name.RemoveWhitespace()}_{categoryName.RemoveWhitespace()}_{attributeName.RemoveWhitespace()}".Left(100); } else { fk = attributeForeignKey; } var attribute = FindEntityAttribute(lookupContext, categoryName, attributeName, contentChannelItem.TypeId, fk); AddEntityAttributeValue(lookupContext, attribute, contentChannelItem, newValue, null, true); } } } // end attribute value processing } // end custom attribute processing importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} Content Channel records processed, {importedCount:N0} imported."); } if (completed % ReportingNumber < 1) { lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables contentChannelService = new ContentChannelService(lookupContext); } } // // Save any other changes to existing items. // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, $"Finished Content Channel Item import: {importedCount:N0} records added."); return(completed); }
/// <summary> /// Loads the family data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadMetrics(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var metricService = new MetricService(lookupContext); var metricCategoryService = new MetricCategoryService(lookupContext); var categoryService = new CategoryService(lookupContext); var metricSourceTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.METRIC_SOURCE_TYPE)).DefinedValues; var metricManualSource = metricSourceTypes.FirstOrDefault(m => m.Guid == new Guid(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_MANUAL)); var scheduleService = new ScheduleService(lookupContext); var scheduleMetrics = scheduleService.Queryable().AsNoTracking() .Where(s => s.Category.Guid == new Guid(Rock.SystemGuid.Category.SCHEDULE_SERVICE_TIMES)).ToList(); var scheduleCategoryId = categoryService.Queryable().AsNoTracking() .Where(c => c.Guid == new Guid(Rock.SystemGuid.Category.SCHEDULE_SERVICE_TIMES)).FirstOrDefault().Id; var metricEntityTypeId = EntityTypeCache.Get <MetricCategory>(false, lookupContext).Id; var campusEntityTypeId = EntityTypeCache.Get <Campus>(false, lookupContext).Id; var scheduleEntityTypeId = EntityTypeCache.Get <Schedule>(false, lookupContext).Id; var allMetrics = metricService.Queryable().AsNoTracking().ToList(); var metricCategories = categoryService.Queryable().AsNoTracking() .Where(c => c.EntityType.Guid == new Guid(Rock.SystemGuid.EntityType.METRICCATEGORY)).ToList(); var defaultMetricCategory = metricCategories.FirstOrDefault(c => c.Name == "Metrics"); if (defaultMetricCategory == null) { defaultMetricCategory = new Category(); defaultMetricCategory.Name = "Metrics"; defaultMetricCategory.IsSystem = false; defaultMetricCategory.EntityTypeId = metricEntityTypeId; defaultMetricCategory.EntityTypeQualifierColumn = string.Empty; defaultMetricCategory.EntityTypeQualifierValue = string.Empty; defaultMetricCategory.IconCssClass = string.Empty; defaultMetricCategory.Description = string.Empty; lookupContext.Categories.Add(defaultMetricCategory); lookupContext.SaveChanges(); metricCategories.Add(defaultMetricCategory); } var metricValues = new List <MetricValue>(); Metric currentMetric = null; int completed = 0; ReportProgress(0, string.Format("Starting metrics import ({0:N0} already exist).", 0)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { string metricCampus = row[MetricCampus]; string metricName = row[MetricName]; string metricCategoryString = row[MetricCategory]; string metricNote = row[MetricNote]; if (!string.IsNullOrEmpty(metricName)) { decimal? value = row[MetricValue].AsDecimalOrNull(); DateTime?valueDate = row[MetricService].AsDateTime(); var metricCategoryId = defaultMetricCategory.Id; // create the category if it doesn't exist Category newMetricCategory = null; if (!string.IsNullOrEmpty(metricCategoryString)) { newMetricCategory = metricCategories.FirstOrDefault(c => c.Name == metricCategoryString); if (newMetricCategory == null) { newMetricCategory = new Category(); newMetricCategory.Name = metricCategoryString; newMetricCategory.IsSystem = false; newMetricCategory.EntityTypeId = metricEntityTypeId; newMetricCategory.EntityTypeQualifierColumn = string.Empty; newMetricCategory.EntityTypeQualifierValue = string.Empty; newMetricCategory.IconCssClass = string.Empty; newMetricCategory.Description = string.Empty; lookupContext.Categories.Add(newMetricCategory); lookupContext.SaveChanges(); metricCategories.Add(newMetricCategory); } metricCategoryId = newMetricCategory.Id; } // create metric if it doesn't exist currentMetric = allMetrics.FirstOrDefault(m => m.Title == metricName && m.MetricCategories.Any(c => c.CategoryId == metricCategoryId)); if (currentMetric == null) { currentMetric = new Metric(); currentMetric.Title = metricName; currentMetric.IsSystem = false; currentMetric.IsCumulative = false; currentMetric.SourceSql = string.Empty; currentMetric.Subtitle = string.Empty; currentMetric.Description = string.Empty; currentMetric.IconCssClass = string.Empty; currentMetric.SourceValueTypeId = metricManualSource.Id; currentMetric.CreatedByPersonAliasId = ImportPersonAliasId; currentMetric.CreatedDateTime = ImportDateTime; currentMetric.ForeignKey = string.Format("Metric imported {0}", ImportDateTime); currentMetric.MetricPartitions = new List <MetricPartition>(); currentMetric.MetricPartitions.Add(new MetricPartition { Label = "Campus", EntityTypeId = campusEntityTypeId, Metric = currentMetric, Order = 0 }); currentMetric.MetricPartitions.Add(new MetricPartition { Label = "Service", EntityTypeId = scheduleEntityTypeId, Metric = currentMetric, Order = 1 }); metricService.Add(currentMetric); lookupContext.SaveChanges(); if (currentMetric.MetricCategories == null || !currentMetric.MetricCategories.Any(a => a.CategoryId == metricCategoryId)) { metricCategoryService.Add(new MetricCategory { CategoryId = metricCategoryId, MetricId = currentMetric.Id }); lookupContext.SaveChanges(); } allMetrics.Add(currentMetric); } // create values for this metric var metricValue = new MetricValue(); metricValue.MetricValueType = MetricValueType.Measure; metricValue.CreatedByPersonAliasId = ImportPersonAliasId; metricValue.CreatedDateTime = ImportDateTime; metricValue.MetricValueDateTime = valueDate.Value.Date; metricValue.MetricId = currentMetric.Id; metricValue.Note = string.Empty; metricValue.XValue = string.Empty; metricValue.YValue = value; metricValue.ForeignKey = string.Format("Metric Value imported {0}", ImportDateTime); metricValue.Note = metricNote; if (!string.IsNullOrWhiteSpace(metricCampus)) { var campus = CampusList.Where(c => c.Name.Equals(metricCampus, StringComparison.OrdinalIgnoreCase) || c.ShortCode.Equals(metricCampus, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (campus == null) { var newCampus = new Campus(); newCampus.IsSystem = false; newCampus.Name = metricCampus; newCampus.ShortCode = metricCampus.RemoveWhitespace(); newCampus.IsActive = true; lookupContext.Campuses.Add(newCampus); lookupContext.SaveChanges(DisableAuditing); CampusList.Add(newCampus); campus = newCampus; } if (campus != null) { var metricPartitionCampusId = currentMetric.MetricPartitions.FirstOrDefault(p => p.Label == "Campus").Id; metricValue.MetricValuePartitions.Add(new MetricValuePartition { MetricPartitionId = metricPartitionCampusId, EntityId = campus.Id }); } } if (valueDate.HasValue) { var metricPartitionScheduleId = currentMetric.MetricPartitions.FirstOrDefault(p => p.Label == "Service").Id; var date = ( DateTime )valueDate; var scheduleName = date.DayOfWeek.ToString(); if (date.TimeOfDay.TotalSeconds > 0) { scheduleName = scheduleName + string.Format(" {0}", date.ToString("hh:mm")) + string.Format("{0}", date.ToString("tt").ToLower()); } if (!scheduleMetrics.Any(s => s.Name == scheduleName)) { Schedule newSchedule = new Schedule(); newSchedule.Name = scheduleName; newSchedule.CategoryId = scheduleCategoryId; newSchedule.CreatedByPersonAliasId = ImportPersonAliasId; newSchedule.CreatedDateTime = ImportDateTime; newSchedule.ForeignKey = string.Format("Metric Schedule imported {0}", ImportDateTime); scheduleMetrics.Add(newSchedule); lookupContext.Schedules.Add(newSchedule); lookupContext.SaveChanges(); } var scheduleId = scheduleMetrics.FirstOrDefault(s => s.Name == scheduleName).Id; metricValue.MetricValuePartitions.Add(new MetricValuePartition { MetricPartitionId = metricPartitionScheduleId, EntityId = scheduleId }); } metricValues.Add(metricValue); completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} metrics imported.", completed)); } if (completed % ReportingNumber < 1) { SaveMetrics(metricValues); ReportPartialProgress(); metricValues.Clear(); } } } // Check to see if any rows didn't get saved to the database if (metricValues.Any()) { SaveMetrics(metricValues); } ReportProgress(0, string.Format("Finished metrics import: {0:N0} metrics added or updated.", completed)); return(completed); }
/// <summary> /// Loads the group type data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadGroupType(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var newGroupTypeList = new List <GroupType>(); var purposeTypeValues = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.GROUPTYPE_PURPOSE), lookupContext).DefinedValues; var locationMeetingId = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_MEETING_LOCATION), lookupContext).Id; var numImportedGroupTypes = ImportedGroupTypes.Count(); var completed = 0; ReportProgress(0, $"Starting group type import ({numImportedGroupTypes:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowGroupTypeKey = row[GroupTypeId]; var groupTypeForeignId = rowGroupTypeKey.AsType <int?>(); // Check that this group type isn't already in our data var groupTypeExists = false; if (numImportedGroupTypes > 0) { groupTypeExists = ImportedGroupTypes.Any(t => t.ForeignKey == rowGroupTypeKey); } if (!groupTypeExists) { var rowGroupTypeName = row[GroupTypeName].Left(100); var newGroupType = new GroupType { // set required properties (terms set by default) IsSystem = false, Name = rowGroupTypeName, Order = 1000 + completed, // set optional properties CreatedDateTime = ParseDateOrDefault(row[GroupTypeCreatedDate], ImportDateTime), ModifiedDateTime = ImportDateTime, CreatedByPersonAliasId = ImportPersonAliasId, ModifiedByPersonAliasId = ImportPersonAliasId, ForeignKey = rowGroupTypeKey, ForeignId = groupTypeForeignId }; // set meeting location var definedValueService = new DefinedValueService(lookupContext); newGroupType.LocationTypes = new List <GroupTypeLocationType>(); newGroupType.LocationTypes.Clear(); var meetingLocationType = definedValueService.Get(locationMeetingId); if (meetingLocationType != null) { newGroupType.LocationTypes.Add(new GroupTypeLocationType { LocationTypeValueId = meetingLocationType.Id }); } // set provided optional properties newGroupType.TakesAttendance = ( bool )ParseBoolOrDefault(row[GroupTypeTakesAttendance], false); newGroupType.AttendanceCountsAsWeekendService = ( bool )ParseBoolOrDefault(row[GroupTypeWeekendService], false); newGroupType.ShowInGroupList = ( bool )ParseBoolOrDefault(row[GroupTypeShowInGroupList], false); newGroupType.ShowInNavigation = ( bool )ParseBoolOrDefault(row[GroupTypeShowInNav], false); // set schedule var allowGroupScheduleWeekly = ( bool )ParseBoolOrDefault(row[GroupTypeWeeklySchedule], false); if (allowGroupScheduleWeekly) { newGroupType.AllowedScheduleTypes = ScheduleType.Weekly; } var rowGroupTypePurpose = row[GroupTypePurpose]; if (!string.IsNullOrWhiteSpace(rowGroupTypePurpose)) { var purposeId = purposeTypeValues.Where(v => v.Value.Equals(rowGroupTypePurpose) || v.Id.Equals(rowGroupTypePurpose) || v.Guid.ToString().ToLower().Equals(rowGroupTypePurpose.ToLower())) .Select(v => ( int? )v.Id).FirstOrDefault(); newGroupType.GroupTypePurposeValueId = purposeId; } var inheritedGroupType = GroupTypeCache.Get(LoadGroupTypeId(lookupContext, row[GroupTypeInheritedGroupType])); if (inheritedGroupType.Id != GroupTypeCache.Get(new Guid("8400497B-C52F-40AE-A529-3FCCB9587101"), lookupContext).Id) { newGroupType.InheritedGroupTypeId = inheritedGroupType.Id; } // add default role of member var defaultRoleGuid = Guid.NewGuid(); var memberRole = new GroupTypeRole { Guid = defaultRoleGuid, Name = "Member" }; newGroupType.Roles.Add(memberRole); // save changes each loop newGroupTypeList.Add(newGroupType); lookupContext.WrapTransaction(() => { lookupContext.GroupTypes.AddRange(newGroupTypeList); lookupContext.SaveChanges(DisableAuditing); }); // Set Parent Group Type var rowGroupTypeParentId = row[GroupTypeParentId]; if (!string.IsNullOrWhiteSpace(rowGroupTypeParentId)) { var parentGroupType = ImportedGroupTypes.FirstOrDefault(t => t.ForeignKey.Equals(rowGroupTypeParentId)); var parentGroupTypeList = new List <GroupType>(); parentGroupTypeList.Add(parentGroupType); newGroupType.ParentGroupTypes = parentGroupTypeList; } // Set Self Reference bool selfRef; TryParseBool(row[GroupTypeSelfReference], out selfRef); if (selfRef) { var selfReferenceList = new List <GroupType>(); selfReferenceList.Add(newGroupType); newGroupType.ChildGroupTypes = selfReferenceList; } // set default role newGroupType.DefaultGroupRole = newGroupType.Roles.FirstOrDefault(); // save changes lookupContext.SaveChanges(); // add these new groups to the global list ImportedGroupTypes.AddRange(newGroupTypeList); newGroupTypeList.Clear(); // // Keep the user informed as to what is going on and save in batches. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} groups imported."); } if (completed % ReportingNumber < 1) { ReportPartialProgress(); } } } ReportProgress(0, $"Finished group type import: {completed:N0} group types added or updated."); return(completed); }
/// <summary> /// Loads the Notes data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadNote(CSVInstance csvData) { var lookupContext = new RockContext(); var importedNotes = new NoteService(lookupContext).Queryable().Count(n => n.ForeignKey != null); var entityTypes = EntityTypeCache.All().Where(e => e.IsEntity && e.IsSecured).ToList(); var noteList = new List <Note>(); var skippedNotes = new Dictionary <string, string>(); var completedItems = 0; ReportProgress(0, string.Format("Verifying note import ({0:N0} already imported).", importedNotes)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var noteType = row[NoteType] as string; var entityTypeName = row[EntityTypeName] as string; var entityForeignKey = row[EntityForeignId]; var noteCaption = row[NoteCaption] as string; var noteText = row[NoteText] as string; var createdDate = row[NoteDate].AsDateTime(); var createdByKey = row[CreatedById]; var rowIsAlert = row[IsAlert]; var rowIsPrivate = row[IsPrivate]; var isAlert = ( bool )ParseBoolOrDefault(rowIsAlert, false); var isPrivate = ( bool )ParseBoolOrDefault(rowIsPrivate, false); int?noteTypeId = null; int?noteEntityId = null; var entityType = entityTypes.FirstOrDefault(et => et.Name.Equals(entityTypeName)); if (entityType != null) { var entityTypeInstance = entityType.GetEntityType(); if (entityTypeInstance == typeof(Person)) { // this is a person, reference the local keys that are already cached var personKeys = GetPersonKeys(entityForeignKey); if (personKeys != null) { noteEntityId = personKeys.PersonId; } noteTypeId = noteType.StartsWith("General", StringComparison.OrdinalIgnoreCase) ? ( int? )PersonalNoteTypeId : null; } else { // activate service type and query the foreign id for this entity type var entityService = Reflection.GetServiceForEntityType(entityTypeInstance, lookupContext); var entityQueryable = entityService.GetType().GetMethod("Queryable", new Type[] { }); // Note: reflection-invoked service can only return IEnumerable or primitive object types noteEntityId = ((IQueryable <IEntity>)entityQueryable.Invoke(entityService, new object[] { })) .Where(q => entityForeignKey == q.ForeignKey) .Select(q => q.Id) .FirstOrDefault(); } if (noteEntityId > 0 && !string.IsNullOrWhiteSpace(noteText)) { var creatorKeys = GetPersonKeys(createdByKey); var creatorAliasId = creatorKeys != null ? ( int? )creatorKeys.PersonAliasId : null; var note = AddEntityNote(lookupContext, entityType.Id, ( int )noteEntityId, noteCaption, noteText, isAlert, isPrivate, noteType, noteTypeId, false, createdDate, string.Format("Note imported {0}", ImportDateTime), creatorAliasId); noteList.Add(note); completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} notes processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SaveNotes(noteList); ReportPartialProgress(); noteList.Clear(); } } } else { skippedNotes.Add(entityForeignKey, noteType); } } if (noteList.Any()) { SaveNotes(noteList); } if (skippedNotes.Any()) { ReportProgress(0, "The following notes could not be imported and were skipped:"); foreach (var key in skippedNotes) { ReportProgress(0, string.Format("{0} note for Foreign ID {1}.", key.Value, key)); } } ReportProgress(100, string.Format("Finished note import: {0:N0} notes imported.", completedItems)); return(completedItems); }
/// <summary> /// Loads the Benevolence Requests data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadBenevolenceRequest(CSVInstance csvData) { var lookupContext = new RockContext(); var benevolenceRequestService = new BenevolenceRequestService(lookupContext); var importedBenevolenceRequests = benevolenceRequestService.Queryable().Count(p => p.ForeignKey != null); var requestStatusDTGuid = Rock.SystemGuid.DefinedType.BENEVOLENCE_REQUEST_STATUS.AsGuid(); var requestStatusPendingDVId = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.BENEVOLENCE_PENDING), lookupContext).Id; var homePhoneTypeDVId = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME), lookupContext).Id; var mobilePhoneTypeDVId = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE), lookupContext).Id; var workPhoneTypeDVId = DefinedValueCache.Get(new Guid(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK), lookupContext).Id; var benevolenceRequestList = new List <BenevolenceRequest>(); var completedItems = 0; var addedItems = 0; ReportProgress(0, string.Format("Verifying benevolence request import ({0:N0} already imported).", importedBenevolenceRequests)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var benevolenceRequestText = row[BenevolenceRequestText]; var benevolenceRequestDate = row[BenevolenceRequestDate]; var benevolenceRequestId = row[BenevolenceRequestId]; var benevolenceRequestFirstName = row[BenevolenceRequestFirstName]; var benevolenceRequestLastName = row[BenevolenceRequestLastName]; var benevolenceRequestEmail = row[BenevolenceRequestEmail]; var benevolenceRequestCreatedById = row[BenevolenceRequestCreatedById]; var benevolenceRequestCreatedDate = row[BenevolenceRequestCreatedDate]; var benevolenceRequestRequestedById = row[BenevolenceRequestRequestedById]; var benevolenceRequestCaseWorkerId = row[BenevolenceRequestCaseWorkerId]; var benevolenceRequestCellPhone = row[BenevolenceRequestCellPhone]; var benevolenceRequestHomePhone = row[BenevolenceRequestHomePhone]; var benevolenceRequestWorkPhone = row[BenevolenceRequestWorkPhone]; var benevolenceRequestGovernmentId = row[BenevolenceRequestGovernmentId]; var benevolenceRequestProvidedNextSteps = row[BenevolenceRequestProvidedNextSteps]; var benevolenceRequestStatus = row[BenevolenceRequestStatus]; var benevolenceRequestResultSummary = row[BenevolenceRequestResultSummary]; var benevolenceRequestAddress = row[BenevolenceRequestAddress]; var benevolenceRequestAddress2 = row[BenevolenceRequestAddress2]; var benevolenceRequestCity = row[BenevolenceRequestCity]; var benevolenceRequestState = row[BenevolenceRequestState]; var benevolenceRequestZip = row[BenevolenceRequestZip]; var benevolenceRequestCountry = row[BenevolenceRequestCountry]; // // Verify we have the minimum required information for a valid BenevolenceRequest in the csv file. // if (string.IsNullOrWhiteSpace(benevolenceRequestText) || (string.IsNullOrWhiteSpace(benevolenceRequestRequestedById) && (string.IsNullOrWhiteSpace(benevolenceRequestFirstName) || string.IsNullOrWhiteSpace(benevolenceRequestLastName)))) { ReportProgress(0, $"Benevolence Request {benevolenceRequestId} is missing information. See exception log for details."); LogException("InvalidBenevolenceRequest", string.Format("RequestId: {0} - BenevolenceRequestText and either BenevolenceRequestRequestedById or both BenevolenceRequestFirstName and BenevolenceRequestLastName are required. Benevolence Request {0} was not imported.", benevolenceRequestId)); completedItems++; continue; } // // Check that this Benevolence Request doesn't already exist. // var exists = false; if (importedBenevolenceRequests > 0) { exists = benevolenceRequestService.Queryable().AsNoTracking().Any(r => r.ForeignKey == benevolenceRequestId); } if (!exists) { var email = string.Empty; if (benevolenceRequestEmail.IsEmail()) { email = benevolenceRequestEmail; } int?requestedByAliasId = null; var requestedByPersonKeys = GetPersonKeys(benevolenceRequestRequestedById); if (requestedByPersonKeys != null) { requestedByAliasId = requestedByPersonKeys.PersonAliasId; } int?createdByAliasId = null; var createdByPersonKeys = GetPersonKeys(benevolenceRequestCreatedById); if (createdByPersonKeys != null) { createdByAliasId = createdByPersonKeys.PersonAliasId; } int?caseWorkerAliasId = null; var caseWorkerPersonKeys = GetPersonKeys(benevolenceRequestCaseWorkerId); if (caseWorkerPersonKeys != null) { caseWorkerAliasId = caseWorkerPersonKeys.PersonAliasId; } var requestDate = ( DateTime )ParseDateOrDefault(benevolenceRequestDate, Bulldozer.BulldozerComponent.ImportDateTime); var dateCreated = ( DateTime )ParseDateOrDefault(benevolenceRequestCreatedDate, Bulldozer.BulldozerComponent.ImportDateTime); var benevolenceRequest = new BenevolenceRequest { RequestedByPersonAliasId = requestedByAliasId, FirstName = benevolenceRequestFirstName, LastName = benevolenceRequestLastName, Email = email, RequestText = benevolenceRequestText, RequestDateTime = requestDate, CreatedDateTime = dateCreated, CreatedByPersonAliasId = createdByAliasId, ResultSummary = benevolenceRequestResultSummary, CaseWorkerPersonAliasId = caseWorkerAliasId, ForeignKey = benevolenceRequestId, ForeignId = benevolenceRequestId.AsType <int?>() }; // Handle request Status if (!string.IsNullOrWhiteSpace(benevolenceRequestStatus)) { var statusDV = FindDefinedValueByTypeAndName(lookupContext, requestStatusDTGuid, benevolenceRequestStatus); if (statusDV == null) { statusDV = AddDefinedValue(new RockContext(), requestStatusDTGuid.ToString(), benevolenceRequestStatus); } benevolenceRequest.RequestStatusValueId = statusDV.Id; } else { // set default status to pending benevolenceRequest.RequestStatusValueId = requestStatusPendingDVId; } // Check for requester person and use its info instead if (requestedByAliasId.HasValue && requestedByAliasId.Value > 0) { Person requester = null; var requesterPersonAlias = new PersonAliasService(lookupContext).Queryable() .AsNoTracking() .FirstOrDefault(pa => pa.Id == requestedByAliasId.Value); if (requesterPersonAlias != null && requesterPersonAlias.PersonId > 0) { requester = requesterPersonAlias.Person; } if (requester != null) { if (!string.IsNullOrWhiteSpace(requester.NickName)) { benevolenceRequest.FirstName = requester.NickName; } else if (!string.IsNullOrWhiteSpace(requester.FirstName)) { benevolenceRequest.FirstName = requester.FirstName; } if (!string.IsNullOrWhiteSpace(requester.LastName)) { benevolenceRequest.LastName = requester.LastName; } if (!string.IsNullOrWhiteSpace(requester.Email)) { benevolenceRequest.Email = requester.Email; } if (requester.PrimaryCampusId.HasValue) { benevolenceRequest.CampusId = requester.PrimaryCampusId; } if (requester.PhoneNumbers.Any(n => n.NumberTypeValueId.Value == homePhoneTypeDVId)) { benevolenceRequest.HomePhoneNumber = requester.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId.Value == homePhoneTypeDVId).NumberFormatted; } if (requester.PhoneNumbers.Any(n => n.NumberTypeValueId.Value == mobilePhoneTypeDVId)) { benevolenceRequest.CellPhoneNumber = requester.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId.Value == mobilePhoneTypeDVId).NumberFormatted; } if (requester.PhoneNumbers.Any(n => n.NumberTypeValueId.Value == workPhoneTypeDVId)) { benevolenceRequest.WorkPhoneNumber = requester.PhoneNumbers.FirstOrDefault(n => n.NumberTypeValueId.Value == workPhoneTypeDVId).NumberFormatted; } var requesterAddressLocation = requester.GetHomeLocation(); if (requesterAddressLocation != null) { benevolenceRequest.LocationId = requesterAddressLocation.Id; } } else { benevolenceRequestRequestedById = null; } } if (string.IsNullOrWhiteSpace(benevolenceRequestRequestedById)) { // Handle Address var requestAddress = new LocationService(lookupContext).Get(benevolenceRequestAddress.Left(100), benevolenceRequestAddress2.Left(100), benevolenceRequestCity, benevolenceRequestState, benevolenceRequestZip, benevolenceRequestCountry, verifyLocation: false); if (requestAddress != null) { benevolenceRequest.LocationId = requestAddress.Id; } } benevolenceRequestList.Add(benevolenceRequest); addedItems++; } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} benevolence requests processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SaveBenevolenceRequests(benevolenceRequestList); ReportPartialProgress(); benevolenceRequestList.Clear(); } } if (benevolenceRequestList.Any()) { SaveBenevolenceRequests(benevolenceRequestList); } ReportProgress(100, string.Format("Finished benevolence request import: {0:N0} benevolence requests processed, {1:N0} imported.", completedItems, addedItems)); return(completedItems); }
/// <summary> /// Loads the BenevolenceResult data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadBenevolenceResult(CSVInstance csvData) { var lookupContext = new RockContext(); var benevolenceResultService = new BenevolenceResultService(lookupContext); var benevolenceRequestService = new BenevolenceRequestService(lookupContext); var resultTypeDTGuid = Rock.SystemGuid.DefinedType.BENEVOLENCE_RESULT_TYPE.AsGuid(); var benevolenceResultList = new List <BenevolenceResult>(); var importedRequestIds = new List <int>(); var completed = 0; var importedCount = 0; var alreadyImportedCount = benevolenceResultService.Queryable().AsNoTracking().Count(i => i.ForeignKey != null); ReportProgress(0, $"Starting Benevolence Result import ({alreadyImportedCount:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var benevolenceResultRequestId = row[BenevolenceResultRequestId]; var benevolenceResultType = row[BenevolenceResultType]; var benevolenceResultId = row[BenevolenceResultId]; var benevolenceResultAmount = row[BenevolenceResultAmount]; var benevolenceResultSummary = row[BenevolenceResultSummary]; var benevolenceResultCreatedById = row[BenevolenceResultCreatedById]; var benevolenceResultCreatedDate = row[BenevolenceResultCreatedDate]; // // Verify the Benevolence Result has a Result Type provided in the csv file. // if (string.IsNullOrWhiteSpace(benevolenceResultType)) { ReportProgress(0, $"Benevolence Result {benevolenceResultId} has no BenevolenceResultType value provided. Skipping Benevolence Result {benevolenceResultId}."); LogException("InvalidBenevolenceResult", string.Format("ResultId: {0} - Missing BenevolenceResultType value. Benevolence Result {0} was not imported.", benevolenceResultId)); completed++; continue; } BenevolenceRequest benevolenceRequest = null; if (benevolenceRequestService.Queryable().AsNoTracking().Any(r => r.ForeignKey == benevolenceResultRequestId)) { benevolenceRequest = benevolenceRequestService.Queryable().AsNoTracking().FirstOrDefault(r => r.ForeignKey == benevolenceResultRequestId); } // // Verify the Benevolence Request exists. // if (benevolenceRequest == null || benevolenceRequest.Id < 1) { ReportProgress(0, $"Benevolence Request {benevolenceResultRequestId} not found. Skipping Benevolence Result {benevolenceResultId}."); LogException("InvalidBenevolenceResult", string.Format("ResultId: {0} - BenevolenceResultRequestId {1} does not exist in imported Benevolence Requests. Benevolence Result {0} was not imported.", benevolenceResultId, benevolenceResultRequestId)); completed++; continue; } // // Check that this Benevolence Result doesn't already exist. // var exists = false; if (alreadyImportedCount > 0) { exists = benevolenceResultService.Queryable().AsNoTracking().Any(r => r.ForeignKey == benevolenceResultId); } if (!exists) { // Handle Result Type var resultTypeDV = FindDefinedValueByTypeAndName(lookupContext, resultTypeDTGuid, benevolenceResultType); if (resultTypeDV == null) { resultTypeDV = AddDefinedValue(new RockContext(), resultTypeDTGuid.ToString(), benevolenceResultType); } // Format created date var resultCreatedDate = ( DateTime )ParseDateOrDefault(benevolenceResultCreatedDate, Bulldozer.BulldozerComponent.ImportDateTime); // Handle created by int?createdByAliasId = null; var createdByPersonKeys = GetPersonKeys(benevolenceResultCreatedById); if (createdByPersonKeys != null) { createdByAliasId = createdByPersonKeys.PersonAliasId; } // // Create and populate the new Benevolence Result. // var benevolenceResult = new BenevolenceResult { BenevolenceRequestId = benevolenceRequest.Id, ResultSummary = benevolenceResultSummary, ResultTypeValueId = resultTypeDV.Id, Amount = benevolenceResultAmount.AsType <decimal?>(), ForeignKey = benevolenceResultId, ForeignId = benevolenceResultId.AsType <int?>(), CreatedDateTime = resultCreatedDate, CreatedByPersonAliasId = createdByAliasId, }; benevolenceResultList.Add(benevolenceResult); importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} Benevolence Request records processed, {importedCount:N0} imported."); } if (completed % ReportingNumber < 1) { SaveBenevolenceResults(benevolenceResultList); ReportPartialProgress(); benevolenceResultList.Clear(); // Clear out variables benevolenceRequestService = new BenevolenceRequestService(lookupContext); } } if (benevolenceResultList.Any()) { SaveBenevolenceResults(benevolenceResultList); } ReportProgress(0, $"Finished Benevolence Result import: {importedCount:N0} records added."); return(completed); }
/// <summary> /// Loads the individual data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadIndividuals(CSVInstance csvData) { var lookupContext = new RockContext(); // Marital statuses: Married, Single, Separated, etc var maritalStatusTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_MARITAL_STATUS), lookupContext).DefinedValues; // Connection statuses: Member, Visitor, Attendee, etc var connectionStatusTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_CONNECTION_STATUS), lookupContext).DefinedValues; // Suffix types: Dr., Jr., II, etc var suffixTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_SUFFIX), lookupContext).DefinedValues; // Title types: Mr., Mrs. Dr., etc var titleTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_TITLE), lookupContext).DefinedValues; // Group roles: Owner, Adult, Child, others var familyRoles = GroupTypeCache.Get(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY), lookupContext).Roles; // Phone types: Home, Work, Mobile var numberTypeValues = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_PHONE_TYPE), lookupContext).DefinedValues; // School Person attribute var schoolAttribute = FindEntityAttribute(lookupContext, "Education", "School", PersonEntityTypeId); // Visit info category var visitInfoCategory = new CategoryService(lookupContext).GetByEntityTypeId(PersonAttributeCategoryEntityTypeId) .FirstOrDefault(c => c.Name == "Visit Information"); // Look for custom attributes in the Individual file var allFields = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList(); var customAttributes = allFields .Where(f => f.index > SecurityNote) .ToDictionary(f => f.index, f => f.node.Name); var personAttributes = new List <Rock.Model.Attribute>(); // Add any attributes if they don't already exist if (customAttributes.Any()) { foreach (var newAttributePair in customAttributes) { var pairs = newAttributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; var fieldTypeId = TextFieldTypeId; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } var definedValueForeignId = definedValueForeignKey.AsType <int?>(); // // Translate the provided attribute type into one we know about. // fieldTypeId = GetAttributeFieldType(attributeTypeString); if (string.IsNullOrEmpty(attributeName)) { LogException("Individual", string.Format("Individual Attribute Name cannot be blank '{0}'.", newAttributePair.Value)); } else { // // First try to find the existing attribute, if not found then add a new one. // var attribute = FindEntityAttribute(lookupContext, categoryName, attributeName, PersonEntityTypeId, attributeForeignKey); if (attribute == null) { var fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = string.Format("Bulldozer_{0}_{1}", categoryName.RemoveWhitespace(), attributeName.RemoveWhitespace()).Left(100); } else { fk = attributeForeignKey; } attribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, fk, categoryName, attributeName, string.Empty, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); } personAttributes.Add(attribute); } } } var currentFamilyGroup = new Group(); var newFamilyList = new List <Group>(); var newVisitorList = new List <Group>(); var newNoteList = new List <Note>(); var completed = 0; var newFamilies = 0; var newPeople = 0; ReportProgress(0, string.Format("Starting Individual import ({0:N0} already exist).", ImportedPeopleKeys.Count)); string[] row; row = csvData.Database.FirstOrDefault(); while (row != null) { int?groupRoleId = null; var isFamilyRelationship = true; var rowFamilyName = row[FamilyName]; var rowFamilyKey = row[FamilyId]; var rowPersonKey = row[PersonId]; var rowFamilyId = rowFamilyKey.AsType <int?>(); var rowPersonId = rowPersonKey.AsType <int?>(); // Check that this person isn't already in our data var personKeys = GetPersonKeys(rowPersonKey); if (personKeys == null) { #region person create var person = new Person { ForeignKey = rowPersonKey, ForeignId = rowPersonId, SystemNote = string.Format("Imported via Bulldozer on {0}", ImportDateTime), RecordTypeValueId = PersonRecordTypeId, CreatedByPersonAliasId = ImportPersonAliasId }; var firstName = row[FirstName].Left(50); var nickName = row[NickName].Left(50); person.FirstName = firstName; person.NickName = string.IsNullOrWhiteSpace(nickName) ? firstName : nickName; person.MiddleName = row[MiddleName].Left(50); person.LastName = row[LastName].Left(50); var createdDateValue = ParseDateOrDefault(row[CreatedDate], null); if (createdDateValue.HasValue) { person.CreatedDateTime = createdDateValue; person.ModifiedDateTime = ImportDateTime; } else { person.CreatedDateTime = ImportDateTime; person.ModifiedDateTime = ImportDateTime; } var birthDate = ParseDateOrDefault(row[DateOfBirth], null); if (birthDate.HasValue) { person.BirthDay = (( DateTime )birthDate).Day; person.BirthMonth = (( DateTime )birthDate).Month; person.BirthYear = (( DateTime )birthDate).Year; } var graduationDate = ParseDateOrDefault(row[GraduationDate], null); if (graduationDate.HasValue) { person.GraduationYear = (( DateTime )graduationDate).Year; } var anniversary = ParseDateOrDefault(row[Anniversary], null); if (anniversary.HasValue) { person.AnniversaryDate = anniversary; } var gender = row[Gender]; if (gender != null) { switch (gender.Trim().ToLower()) { case "m": case "male": person.Gender = Rock.Model.Gender.Male; break; case "f": case "female": person.Gender = Rock.Model.Gender.Female; break; default: person.Gender = Rock.Model.Gender.Unknown; break; } } var prefix = row[Prefix]; if (!string.IsNullOrWhiteSpace(prefix)) { prefix = prefix.RemoveSpecialCharacters(); person.TitleValueId = titleTypes.Where(s => prefix.Equals(s.Value.RemoveSpecialCharacters(), StringComparison.CurrentCultureIgnoreCase)) .Select(s => ( int? )s.Id).FirstOrDefault(); if (!person.TitleValueId.HasValue) { var newTitle = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.PERSON_TITLE, prefix); if (newTitle != null) { titleTypes.Add(newTitle); person.TitleValueId = newTitle.Id; } } } var suffix = row[Suffix]; if (!string.IsNullOrWhiteSpace(suffix)) { suffix = suffix.RemoveSpecialCharacters(); person.SuffixValueId = suffixTypes.Where(s => suffix.Equals(s.Value.RemoveSpecialCharacters(), StringComparison.CurrentCultureIgnoreCase)) .Select(s => ( int? )s.Id).FirstOrDefault(); if (!person.SuffixValueId.HasValue) { var newSuffix = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.PERSON_SUFFIX, suffix); if (newSuffix != null) { suffixTypes.Add(newSuffix); person.SuffixValueId = newSuffix.Id; } } } var maritalStatus = row[MaritalStatus]; if (!string.IsNullOrWhiteSpace(maritalStatus)) { maritalStatus = maritalStatus.RemoveSpecialCharacters(); person.MaritalStatusValueId = maritalStatusTypes.Where(s => maritalStatus.Equals(s.Value.RemoveSpecialCharacters(), StringComparison.CurrentCultureIgnoreCase)) .Select(dv => ( int? )dv.Id).FirstOrDefault(); if (!person.MaritalStatusValueId.HasValue) { var newMaritalStatus = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.PERSON_MARITAL_STATUS, maritalStatus); if (newMaritalStatus != null) { maritalStatusTypes.Add(newMaritalStatus); person.MaritalStatusValueId = newMaritalStatus.Id; } } } if (person.MaritalStatusValueId == null) { person.MaritalStatusValueId = maritalStatusTypes.Where(dv => dv.Value.Equals("Unknown", StringComparison.CurrentCultureIgnoreCase)) .Select(dv => ( int? )dv.Id).FirstOrDefault(); } var familyRole = row[FamilyRole]; if (!string.IsNullOrWhiteSpace(familyRole)) { familyRole = familyRole.RemoveSpecialCharacters().Trim(); groupRoleId = familyRoles.Where(dv => string.Equals(dv.Name, familyRole, StringComparison.CurrentCultureIgnoreCase)) .Select(dv => ( int? )dv.Id).FirstOrDefault(); if (!groupRoleId.HasValue) { AddGroupRole(lookupContext, Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY, familyRole); familyRoles = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY).Roles; groupRoleId = familyRoles.Where(dv => dv.Name == familyRole) .Select(dv => ( int? )dv.Id).FirstOrDefault(); } if (familyRole.Equals("Visitor", StringComparison.CurrentCultureIgnoreCase)) { isFamilyRelationship = false; } } if (groupRoleId == null) { groupRoleId = FamilyAdultRoleId; } var recordStatus = row[RecordStatus]; if (!string.IsNullOrWhiteSpace(recordStatus)) { switch (recordStatus.Trim().ToLower()) { case "active": person.RecordStatusValueId = ActivePersonRecordStatusId; break; case "inactive": person.RecordStatusValueId = InactivePersonRecordStatusId; break; default: person.RecordStatusValueId = PendingPersonRecordStatusId; break; } } else { person.RecordStatusValueId = ActivePersonRecordStatusId; } var connectionStatus = row[ConnectionStatus]; if (!string.IsNullOrWhiteSpace(connectionStatus)) { if (connectionStatus.Equals("Member", StringComparison.CurrentCultureIgnoreCase)) { person.ConnectionStatusValueId = MemberConnectionStatusId; } else if (connectionStatus.Equals("Visitor", StringComparison.CurrentCultureIgnoreCase)) { person.ConnectionStatusValueId = VisitorConnectionStatusId; } else if (connectionStatus.Equals("Business", StringComparison.CurrentCultureIgnoreCase)) { person.RecordTypeValueId = BusinessRecordTypeId; } else if (connectionStatus.Equals("Inactive", StringComparison.CurrentCultureIgnoreCase)) { person.RecordStatusValueId = InactivePersonRecordStatusId; } else { // create user-defined connection type if it doesn't exist person.ConnectionStatusValueId = connectionStatusTypes.Where(dv => dv.Value.Equals(connectionStatus, StringComparison.CurrentCultureIgnoreCase)) .Select(dv => ( int? )dv.Id).FirstOrDefault(); if (!person.ConnectionStatusValueId.HasValue) { var newConnectionStatus = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.PERSON_CONNECTION_STATUS, connectionStatus); if (newConnectionStatus != null) { connectionStatusTypes.Add(newConnectionStatus); person.ConnectionStatusValueId = newConnectionStatus.Id; } } } } else { person.ConnectionStatusValueId = VisitorConnectionStatusId; } var isDeceasedValue = row[IsDeceased]; if (!string.IsNullOrWhiteSpace(isDeceasedValue)) { switch (isDeceasedValue.Trim().ToLower()) { case "y": case "yes": case "true": person.IsDeceased = true; person.RecordStatusReasonValueId = DeceasedPersonRecordReasonId; person.RecordStatusValueId = InactivePersonRecordStatusId; break; default: person.IsDeceased = false; break; } } var personNumbers = new Dictionary <string, string>(); personNumbers.Add("Home", row[HomePhone]); personNumbers.Add("Mobile", row[MobilePhone]); personNumbers.Add("Work", row[WorkPhone]); var smsAllowed = row[AllowSMS]; foreach (var numberPair in personNumbers.Where(n => !string.IsNullOrWhiteSpace(n.Value) && n.Value.AsNumeric().AsType <Int64>() > 0)) { var extension = string.Empty; var countryCode = PhoneNumber.DefaultCountryCode(); var normalizedNumber = string.Empty; var countryIndex = numberPair.Value.IndexOf('+'); var extensionIndex = numberPair.Value.LastIndexOf('x') > 0 ? numberPair.Value.LastIndexOf('x') : numberPair.Value.Length; if (countryIndex >= 0 && numberPair.Value.Length > (countryIndex + 3)) { countryCode = numberPair.Value.Substring(countryIndex, countryIndex + 3).AsNumeric(); normalizedNumber = numberPair.Value.Substring(countryIndex + 3, extensionIndex - 3).AsNumeric().TrimStart(new Char[] { '0' }); extension = numberPair.Value.Substring(extensionIndex); } else if (extensionIndex > 0) { normalizedNumber = numberPair.Value.Substring(0, extensionIndex).AsNumeric(); extension = numberPair.Value.Substring(extensionIndex).AsNumeric(); } else { normalizedNumber = numberPair.Value.AsNumeric(); } if (!string.IsNullOrWhiteSpace(normalizedNumber)) { var currentNumber = new PhoneNumber(); currentNumber.CountryCode = countryCode; currentNumber.CreatedByPersonAliasId = ImportPersonAliasId; currentNumber.Extension = extension.Left(20); currentNumber.Number = normalizedNumber.TrimStart(new char[] { '0' }).Left(20); currentNumber.NumberFormatted = PhoneNumber.FormattedNumber(currentNumber.CountryCode, currentNumber.Number); currentNumber.NumberTypeValueId = numberTypeValues.Where(v => v.Value.Equals(numberPair.Key, StringComparison.CurrentCultureIgnoreCase)) .Select(v => ( int? )v.Id).FirstOrDefault(); if (numberPair.Key == "Mobile") { switch (smsAllowed.Trim().ToLower()) { case "y": case "yes": case "active": case "true": currentNumber.IsMessagingEnabled = true; break; default: currentNumber.IsMessagingEnabled = false; break; } } person.PhoneNumbers.Add(currentNumber); } } // Map Person attributes person.Attributes = new Dictionary <string, AttributeCache>(); person.AttributeValues = new Dictionary <string, AttributeValueCache>(); bool isEmailActive; switch (row[IsEmailActive].Trim().ToLower()) { case "n": case "no": case "inactive": case "false": isEmailActive = false; break; default: isEmailActive = true; break; } EmailPreference emailPreference; switch (row[AllowBulkEmail].Trim().ToLower()) { case "n": case "no": case "inactive": case "false": emailPreference = EmailPreference.NoMassEmails; break; default: emailPreference = EmailPreference.EmailAllowed; break; } person.EmailPreference = emailPreference; var primaryEmail = row[Email].Trim().Left(75); if (!string.IsNullOrWhiteSpace(primaryEmail)) { if (primaryEmail.IsEmail()) { person.Email = primaryEmail; person.IsEmailActive = isEmailActive; } else { LogException("InvalidPrimaryEmail", string.Format("PersonId: {0} - Email: {1}", rowPersonKey, primaryEmail)); } } var schoolName = row[School]; if (!string.IsNullOrWhiteSpace(schoolName)) { AddEntityAttributeValue(lookupContext, schoolAttribute, person, schoolName, null, true); } // // Add any Individual attribute values // foreach (var attributePair in customAttributes) { var newValue = row[attributePair.Key]; if (!string.IsNullOrWhiteSpace(newValue)) { var pairs = attributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } // look up the local copy of this attribute if (!string.IsNullOrEmpty(attributeName)) { var attributeQueryable = personAttributes.AsQueryable() .Where(a => a.EntityTypeId == PersonEntityTypeId && a.Name.Equals(attributeName, StringComparison.CurrentCultureIgnoreCase)); if (!string.IsNullOrEmpty(attributeForeignKey)) { attributeQueryable = attributeQueryable.Where(a => a.ForeignKey.Equals(attributeForeignKey, StringComparison.CurrentCultureIgnoreCase)); } if (!string.IsNullOrEmpty(categoryName)) { attributeQueryable = attributeQueryable.Where(a => a.Categories.Any(c => c.Name.Equals(categoryName, StringComparison.CurrentCultureIgnoreCase))); } else { attributeQueryable = attributeQueryable.Where(a => !a.Categories.Any()); } var attribute = attributeQueryable.FirstOrDefault(); if (attribute == null) { attribute = FindEntityAttribute(lookupContext, categoryName, attributeName, PersonEntityTypeId, attributeForeignKey); personAttributes.Add(attribute); } AddEntityAttributeValue(lookupContext, attribute, person, newValue, null, true); } } } // Add notes to timeline var notePairs = new Dictionary <string, string>(); notePairs.Add("General", row[GeneralNote]); notePairs.Add("Medical", row[MedicalNote]); notePairs.Add("Security", row[SecurityNote]); foreach (var notePair in notePairs.Where(n => !string.IsNullOrWhiteSpace(n.Value))) { var splitNotePair = notePair.Value.Split('^'); foreach (string noteValue in splitNotePair) { var newNote = new Note { NoteTypeId = PersonalNoteTypeId, CreatedByPersonAliasId = ImportPersonAliasId, CreatedDateTime = ImportDateTime, Text = noteValue, ForeignKey = rowPersonKey, ForeignId = rowPersonId, Caption = string.Format("{0} Note", notePair.Key) }; if (noteValue.StartsWith("[ALERT]", StringComparison.CurrentCultureIgnoreCase)) { newNote.IsAlert = true; } if (notePair.Key.Equals("Security")) { // Pastoral note type id var securityNoteType = new NoteTypeService(lookupContext).Get(PersonEntityTypeId, "Secure Note", true); if (securityNoteType != null) { newNote.NoteTypeId = securityNoteType.Id; } } if (notePair.Key.Equals("Medical")) { newNote.IsAlert = true; } newNoteList.Add(newNote); } } #endregion person create var groupMember = new GroupMember { Person = person, GroupRoleId = ( int )groupRoleId, CreatedDateTime = ImportDateTime, ModifiedDateTime = ImportDateTime, CreatedByPersonAliasId = ImportPersonAliasId, GroupMemberStatus = GroupMemberStatus.Active }; if (rowFamilyKey != currentFamilyGroup.ForeignKey) { // person not part of the previous family, see if that family exists or create a new one currentFamilyGroup = ImportedFamilies.FirstOrDefault(g => g.ForeignKey == rowFamilyKey); if (currentFamilyGroup == null) { currentFamilyGroup = CreateFamilyGroup(row[FamilyName], rowFamilyKey); newFamilyList.Add(currentFamilyGroup); newFamilies++; } else { lookupContext.Groups.Attach(currentFamilyGroup); } currentFamilyGroup.Members.Add(groupMember); } else { // person is part of this family group, check if they're a visitor if (isFamilyRelationship || currentFamilyGroup.Members.Count() < 1) { currentFamilyGroup.Members.Add(groupMember); } else { var visitorFamily = CreateFamilyGroup(person.LastName + " Family", rowFamilyKey); visitorFamily.Members.Add(groupMember); newFamilyList.Add(visitorFamily); newVisitorList.Add(visitorFamily); newFamilies++; } } // look ahead 1 row var rowNextFamilyKey = "-1"; if ((row = csvData.Database.FirstOrDefault()) != null) { rowNextFamilyKey = row[FamilyId]; } newPeople++; completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} people processed.", completed)); } if (newPeople >= ReportingNumber && rowNextFamilyKey != currentFamilyGroup.ForeignKey) { SaveIndividuals(newFamilyList, newVisitorList, newNoteList); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables currentFamilyGroup = new Group(); newFamilyList.Clear(); newVisitorList.Clear(); newNoteList.Clear(); newPeople = 0; } } else { row = csvData.Database.FirstOrDefault(); } } // Save any changes to new families if (newFamilyList.Any()) { SaveIndividuals(newFamilyList, newVisitorList, newNoteList); } // Save any changes to existing families lookupContext.SaveChanges(); DetachAllInContext(lookupContext); lookupContext.Dispose(); ReportProgress(0, string.Format("Finished individual import: {0:N0} families and {1:N0} people added.", newFamilies, completed)); return(completed); }
/// <summary> /// Loads the ConnectionRequests. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadConnectionRequest(CSVInstance csvData) { var lookupContext = new RockContext(); var connectionTypes = new ConnectionTypeService(lookupContext).Queryable().ToList(); var activityTypes = new ConnectionActivityTypeService(lookupContext).Queryable().ToList(); var opportunities = new ConnectionOpportunityService(lookupContext).Queryable().ToList(); var statuses = new ConnectionStatusService(lookupContext).Queryable().ToList(); var requests = new ConnectionRequestService(lookupContext).Queryable().ToList(); var newRequests = new List <ConnectionRequest>(); var newActivities = new List <ConnectionRequestActivity>(); var completedItems = 0; ReportProgress(0, string.Format("Verifying connection request import ({0:N0} already imported).", requests.Count(n => n.ForeignKey != null))); ConnectionType connectionType = null; ConnectionOpportunity opportunity = null; string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var oForeignKey = row[OpportunityForeignKey] as string; var oName = row[OpportunityName] as string; var cType = row[ConnectionType] as string; var oDescription = row[OpportunityDescription] as string; var oActive = row[OpportunityActive].AsBoolean(); var oCreatedDate = row[OpportunityCreated].AsDateTime(); var oModifiedDate = row[OpportunityModified].AsDateTime(); var rForeignKey = row[RequestForeignKey] as string; var rPersonId = row[RequestPersonId].AsIntegerOrNull(); var rConnectorId = row[RequestConnectorId].AsIntegerOrNull(); var rCreatedDate = row[RequestCreated].AsDateTime(); var rModifiedDate = row[RequestModified].AsDateTime(); var rStatus = row[RequestStatus] as string; var rState = row[RequestState].AsIntegerOrNull(); var rComments = row[RequestComments] as string; var rFollowUp = row[RequestFollowUp].AsDateTime(); var aType = row[ActivityType] as string; var aNote = row[ActivityNote] as string; var aCreatedDate = row[ActivityDate].AsDateTime(); var aConnectorId = row[ActivityConnectorId].AsIntegerOrNull(); // lookup or reuse connection type if (connectionType == null || !connectionType.Name.Equals(cType, StringComparison.OrdinalIgnoreCase)) { connectionType = connectionTypes.FirstOrDefault(t => t.Name.Equals(cType, StringComparison.OrdinalIgnoreCase)); } if (connectionType == null) { connectionType = AddConnectionType(lookupContext, cType); connectionTypes.Add(connectionType); } if (connectionType != null && !string.IsNullOrWhiteSpace(oName) && GetPersonKeys(rPersonId) != null) { // lookup, reuse, or create connection opportunity if (opportunity == null || !opportunity.ForeignKey.Equals(oForeignKey, StringComparison.OrdinalIgnoreCase)) { opportunity = opportunities.FirstOrDefault(o => (o.ForeignKey != null && o.ForeignKey.Equals(oForeignKey, StringComparison.OrdinalIgnoreCase)) || o.Name.Equals(oName, StringComparison.OrdinalIgnoreCase)); } if (opportunity == null) { opportunity = AddConnectionOpportunity(lookupContext, connectionType.Id, oCreatedDate, oName, oDescription, oActive, oForeignKey); opportunities.Add(opportunity); } else if (opportunity.ForeignKey == null) { opportunity.ForeignKey = oForeignKey; opportunity.ForeignId = oForeignKey.AsIntegerOrNull(); lookupContext.SaveChanges(); } // lookup, reuse, or create connection request var requestStatus = statuses.FirstOrDefault(s => s.Name.Equals(rStatus, StringComparison.OrdinalIgnoreCase) && s.ConnectionTypeId.HasValue && s.ConnectionTypeId.Value == connectionType.Id); if (requestStatus == null) { requestStatus = AddConnectionStatus(lookupContext, rStatus, connectionType.Id); statuses.Add(requestStatus); } var requestor = GetPersonKeys(rPersonId); var requestConnector = rConnectorId.HasValue ? GetPersonKeys(rConnectorId) : null; var request = requests.FirstOrDefault(r => r.ForeignKey != null && r.ForeignKey.Equals(rForeignKey, StringComparison.OrdinalIgnoreCase)) ?? newRequests.FirstOrDefault(r => r.ForeignKey != null && r.ForeignKey.Equals(rForeignKey, StringComparison.OrdinalIgnoreCase)); if (request == null && requestor != null && requestStatus != null) { request = AddConnectionRequest(opportunity, rForeignKey, rCreatedDate, rModifiedDate, requestStatus.Id, ( ConnectionState )rState, rComments, rFollowUp, requestor.PersonAliasId, requestConnector?.PersonAliasId); newRequests.Add(request); } // create activity if (!string.IsNullOrWhiteSpace(aType)) { var activityConnector = aConnectorId.HasValue ? GetPersonKeys(aConnectorId) : null; var activityType = activityTypes.FirstOrDefault(t => t.Name.Equals(aType, StringComparison.OrdinalIgnoreCase)); if (request != null && activityType != null) { var activity = AddConnectionActivity(opportunity.Id, aNote, aCreatedDate, activityConnector?.PersonAliasId, activityType.Id, rForeignKey); if (request.Id > 0) { activity.ConnectionRequestId = request.Id; newActivities.Add(activity); } else { request.ConnectionRequestActivities.Add(activity); } } } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} requests processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SaveConnectionRequests(newRequests, newActivities); ReportPartialProgress(); requests.AddRange(newRequests); newRequests.Clear(); newActivities.Clear(); } } } if (newRequests.Count > 0 || newActivities.Count > 0) { SaveConnectionRequests(newRequests, newActivities); } ReportProgress(100, string.Format("Finished connection request import: {0:N0} requests imported.", completedItems)); return(completedItems); }
/// <summary> /// Loads the Content Channel data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadContentChannel(CSVInstance csvData) { var lookupContext = new RockContext(); var contentChannelService = new ContentChannelService(lookupContext); var contentChannelTypeService = new ContentChannelTypeService(lookupContext); var groupService = new GroupService(lookupContext); // Look for custom attributes in the Content Channel file var allFields = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList(); var customAttributes = allFields .Where(f => f.index > ContentChannelParentId) .ToDictionary(f => f.index, f => f.node.Name); var completed = 0; var importedCount = 0; var alreadyImportedCount = contentChannelService.Queryable().AsNoTracking().Count(c => c.ForeignKey != null); ReportProgress(0, $"Starting Content Channel import ({alreadyImportedCount:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowContentChannelName = row[ContentChannelName]; var rowContentChannelTypeName = row[ContentChannelTypeName]; var rowContentChannelDescription = row[ContentChannelDescription]; var rowContentChannelId = row[ContentChannelId]; var rowContentChannelRequiresApproval = row[ContentChannelRequiresApproval]; var rowContentChannelParentId = row[ContentChannelParentId]; var rowChannelId = rowContentChannelId.AsType <int?>(); var requiresApproval = ( bool )ParseBoolOrDefault(rowContentChannelRequiresApproval, false); var contentChannelTypeId = 0; if (contentChannelTypeService.Queryable().AsNoTracking().FirstOrDefault(t => t.Name.ToLower() == rowContentChannelTypeName.ToLower()) != null) { contentChannelTypeId = contentChannelTypeService.Queryable().AsNoTracking().FirstOrDefault(t => t.Name.ToLower() == rowContentChannelTypeName.ToLower()).Id; } // // Verify the Content Channel Type Exists // if (contentChannelTypeId < 1) { var newConentChannelType = new ContentChannelType { Name = rowContentChannelTypeName, DateRangeType = ContentChannelDateType.DateRange, IncludeTime = true, DisablePriority = true, CreatedDateTime = ImportDateTime }; lookupContext.ContentChannelTypes.Add(newConentChannelType); lookupContext.SaveChanges(DisableAuditing); contentChannelTypeId = lookupContext.ContentChannelTypes.FirstOrDefault(t => t.Name == rowContentChannelTypeName).Id; } // // Check that this Content Channel doesn't already exist. // var exists = false; if (alreadyImportedCount > 0) { exists = contentChannelService.Queryable().AsNoTracking().Any(c => c.ForeignKey == rowContentChannelId); } if (!exists) { // // Create and populate the new Content Channel. // var contentChannel = new ContentChannel { Name = rowContentChannelName, Description = rowContentChannelDescription, ContentChannelTypeId = contentChannelTypeId, ForeignKey = rowContentChannelId, ForeignId = rowChannelId, ContentControlType = ContentControlType.HtmlEditor, RequiresApproval = requiresApproval }; // // Look for Parent Id and create appropriate objects. // if (!string.IsNullOrWhiteSpace(rowContentChannelParentId)) { var ParentChannels = new List <ContentChannel>(); var parentChannel = contentChannelService.Queryable().FirstOrDefault(p => p.ForeignKey == rowContentChannelParentId); if (parentChannel.ForeignKey == rowContentChannelParentId) { ParentChannels.Add(parentChannel); contentChannel.ParentContentChannels = ParentChannels; } } // Save changes for context lookupContext.WrapTransaction(() => { lookupContext.ContentChannels.Add(contentChannel); lookupContext.SaveChanges(DisableAuditing); }); // Set security if needed if (contentChannel.RequiresApproval) { var rockAdmins = groupService.Get(Rock.SystemGuid.Group.GROUP_ADMINISTRATORS.AsGuid()); contentChannel.AllowSecurityRole(Authorization.APPROVE, rockAdmins, lookupContext); var communicationAdmins = groupService.Get(Rock.SystemGuid.Group.GROUP_COMMUNICATION_ADMINISTRATORS.AsGuid()); contentChannel.AllowSecurityRole(Authorization.APPROVE, communicationAdmins, lookupContext); // Save security changes lookupContext.WrapTransaction(() => { lookupContext.SaveChanges(DisableAuditing); }); } // // Process Attributes for Content Channels // if (customAttributes.Any()) { // create content channel attributes foreach (var newAttributePair in customAttributes) { var pairs = newAttributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; var fieldTypeId = TextFieldTypeId; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } var definedValueForeignId = definedValueForeignKey.AsType <int?>(); // // Translate the provided attribute type into one we know about. // fieldTypeId = GetAttributeFieldType(attributeTypeString); if (string.IsNullOrEmpty(attributeName)) { LogException("Content Channel Type", $"Content Channel Type Channel Attribute Name cannot be blank '{newAttributePair.Value}'."); } else { var fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = $"Bulldozer_ContentChannelType_{contentChannelTypeId}_{categoryName.RemoveWhitespace()}_{attributeName.RemoveWhitespace()}".Left(100); } else { fk = attributeForeignKey; } AddEntityAttribute(lookupContext, contentChannel.TypeId, "ContentChannelTypeId", contentChannelTypeId.ToString(), fk, categoryName, attributeName, string.Empty, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); } } // // Add any Content Channel attribute values // foreach (var attributePair in customAttributes) { var newValue = row[attributePair.Key]; if (!string.IsNullOrWhiteSpace(newValue)) { var pairs = attributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } if (!string.IsNullOrEmpty(attributeName)) { string fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = $"Bulldozer_ContentChannelType_{contentChannelTypeId}_{categoryName.RemoveWhitespace()}_{attributeName.RemoveWhitespace()}".Left(100); } else { fk = attributeForeignKey; } var attribute = FindEntityAttribute(lookupContext, categoryName, attributeName, contentChannel.TypeId, fk); AddEntityAttributeValue(lookupContext, attribute, contentChannel, newValue, null, true); } } } } importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} Content Channel records processed, {importedCount:N0} imported."); } if (completed % ReportingNumber < 1) { lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables contentChannelService = new ContentChannelService(lookupContext); } } // // Save any other changes to existing items. // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, $"Finished Content Channel import: {importedCount:N0} records added."); return(completed); }
/// <summary> /// Loads the Entity Attribute data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadEntityAttributes(CSVInstance csvData) { var lookupContext = new RockContext(); var importedAttributes = new AttributeService(lookupContext).Queryable().Count(a => a.ForeignKey != null); var entityTypes = EntityTypeCache.All().Where(e => e.IsEntity && e.IsSecured).ToList(); var completedItems = 0; var addedItems = 0; ReportProgress(0, string.Format("Verifying attribute import ({0:N0} already imported).", importedAttributes)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var entityTypeName = row[AttributeEntityTypeName]; var attributeForeignKey = row[AttributeId]; var rockKey = row[AttributeRockKey]; var attributeName = row[AttributeName]; var categoryName = row[AttributeCategoryName]; var attributeTypeString = row[AttributeType]; var definedValueForeignKey = row[AttributeDefinedTypeId]; var entityTypeQualifierName = row[AttributeEntityTypeQualifierName]; var entityTypeQualifierValue = row[AttributeEntityTypeQualifierValue]; if (!string.IsNullOrWhiteSpace(entityTypeQualifierName) && !string.IsNullOrWhiteSpace(entityTypeQualifierValue)) { entityTypeQualifierValue = GetEntityTypeQualifierValue(entityTypeQualifierName, entityTypeQualifierValue, lookupContext); } if (string.IsNullOrEmpty(attributeName)) { LogException("Attribute", string.Format("Entity Attribute Name cannot be blank for {0} {1}", entityTypeName, attributeForeignKey)); } else { var entityTypeId = entityTypes.FirstOrDefault(et => et.Name.Equals(entityTypeName)).Id; var definedValueForeignId = definedValueForeignKey.AsType <int?>(); var fieldTypeId = TextFieldTypeId; fieldTypeId = GetAttributeFieldType(attributeTypeString); var fk = string.Empty; if (string.IsNullOrWhiteSpace(attributeForeignKey)) { fk = string.Format("Bulldozer_{0}_{1}", categoryName.RemoveWhitespace(), attributeName.RemoveWhitespace()).Left(100); } else { fk = attributeForeignKey; } var attribute = FindEntityAttribute(lookupContext, categoryName, attributeName, entityTypeId, attributeForeignKey, rockKey); if (attribute == null) { attribute = AddEntityAttribute(lookupContext, entityTypeId, entityTypeQualifierName, entityTypeQualifierValue, fk, categoryName, attributeName, rockKey, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); addedItems++; } else if (string.IsNullOrWhiteSpace(attribute.ForeignKey)) { attribute = AddEntityAttribute(lookupContext, entityTypeId, entityTypeQualifierName, entityTypeQualifierValue, fk, categoryName, attributeName, rockKey, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); addedItems++; } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} attributes processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { ReportPartialProgress(); } } } ReportProgress(100, string.Format("Finished attribute import: {0:N0} attributes imported.", addedItems)); return(completedItems); }
/// <summary> /// Loads the attendance data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadAttendance(CSVInstance csvData) { var lookupContext = new RockContext(); var groupService = new GroupService(lookupContext); var locationService = new LocationService(lookupContext); var attendanceService = new AttendanceService(lookupContext); var currentGroup = new Group(); int?currentGroupId = null; var location = new Location(); int?locationId = null; int?campusId = null; var newAttendanceList = new List <Attendance>(); var newOccurrences = new List <AttendanceOccurrence>(); var existingOccurrences = new AttendanceOccurrenceService(lookupContext).Queryable().AsNoTracking() .Select(o => new { o.Id, o.GroupId, o.LocationId, o.ScheduleId, o.OccurrenceDate }).ToDictionary(k => $"{k.GroupId}|{k.LocationId}|{k.ScheduleId}|{k.OccurrenceDate}", v => v.Id); var archivedScheduleName = "Archived Attendance"; var archivedSchedule = new ScheduleService(lookupContext).Queryable() .FirstOrDefault(s => s.Name.Equals(archivedScheduleName)); if (archivedSchedule == null) { archivedSchedule = AddNamedSchedule(lookupContext, archivedScheduleName, null, null, null, ImportDateTime, archivedScheduleName.RemoveSpecialCharacters(), true, ImportPersonAliasId); } var completed = 0; var importedCount = 0; var alreadyImportedCount = attendanceService.Queryable().AsNoTracking().Count(a => a.ForeignKey != null); ReportProgress(0, string.Format("Starting attendance import ({0:N0} already exist).", alreadyImportedCount)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowAttendanceKey = row[AttendanceId]; var rowGroupKey = row[AttendanceGroupId]; var rowPersonKey = row[AttendancePersonId]; var rowDate = row[AttendanceDate]; var rowCreatedDate = row[AttendanceCreatedDate]; var rowAttended = row[AttendanceAttended]; var rowLocationKey = row[AttendanceLocationId]; var rowAttendanceId = rowAttendanceKey.AsType <int?>(); // // Find this person in the database. // var personKeys = GetPersonKeys(rowPersonKey); if (personKeys == null || personKeys.PersonId == 0) { ReportProgress(0, string.Format("Person key {0} not found", rowPersonKey)); } // // Check that this attendance record doesn't already exist. // var attendanceExists = false; if (ImportedGroups.Count > 0 && rowGroupKey != currentGroup?.ForeignKey) { currentGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey == rowGroupKey); currentGroupId = currentGroup?.Id; } // // If we have a valid matching location, set the location and campus. // if (!string.IsNullOrEmpty(rowLocationKey)) { location = locationService.Queryable().FirstOrDefault(l => l.ForeignKey == rowLocationKey); locationId = location.Id; campusId = location.CampusId; } if (alreadyImportedCount > 0) { attendanceExists = attendanceService.Queryable().AsNoTracking().Any(a => a.ForeignKey == rowAttendanceKey); } if (!attendanceExists && (personKeys != null && personKeys.PersonId != 0)) { // // Create and populate the new attendance record. // var attendance = new Attendance { PersonAliasId = personKeys.PersonAliasId, ForeignKey = rowAttendanceKey, ForeignId = rowAttendanceId, DidAttend = ParseBoolOrDefault(rowAttended, true), StartDateTime = ( DateTime )ParseDateOrDefault(rowDate, ImportDateTime), CreatedDateTime = ParseDateOrDefault(rowCreatedDate, ImportDateTime), ModifiedDateTime = ImportDateTime, CreatedByPersonAliasId = ImportPersonAliasId, ModifiedByPersonAliasId = ImportPersonAliasId, CampusId = campusId }; var startDateString = (( DateTime )ParseDateOrDefault(rowDate, ImportDateTime)).Date; // occurrence is required for attendance int?occurrenceId = existingOccurrences.GetValueOrNull($"{currentGroupId}|{locationId}|{archivedSchedule.Id}|{startDateString}"); if (occurrenceId.HasValue) { attendance.OccurrenceId = occurrenceId.Value; } else { var newOccurrence = AddOccurrence(null, ( DateTime )ParseDateOrDefault(rowDate, ImportDateTime), currentGroupId, archivedSchedule.Id, locationId, true); if (newOccurrence != null) { attendance.OccurrenceId = newOccurrence.Id; existingOccurrences.Add($"{currentGroupId}|{locationId}|{archivedSchedule.Id}|{startDateString}", newOccurrence.Id); } } // // Add the attendance record for delayed saving. // newAttendanceList.Add(attendance); importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} attendance records processed, {1:N0} imported.", completed, importedCount)); } if (completed % ReportingNumber < 1) { SaveAttendance(newAttendanceList); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables currentGroup = new Group(); newAttendanceList.Clear(); groupService = new GroupService(lookupContext); locationService = new LocationService(lookupContext); attendanceService = new AttendanceService(lookupContext); } } // // Save any final changes to new groups // if (newAttendanceList.Any()) { SaveAttendance(newAttendanceList); } // // Save any changes to existing groups // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, string.Format("Finished attendance import: {0:N0} records added.", importedCount)); return(completed); }
/// <summary> /// Loads the group data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadGroup(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var locationService = new LocationService(lookupContext); var groupTypeService = new GroupTypeService(lookupContext); var topicTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.SMALL_GROUP_TOPIC), lookupContext).DefinedValues; var numImportedGroups = ImportedGroups.Count(); var newGroupLocations = new Dictionary <GroupLocation, string>(); var currentGroup = new Group(); // Look for custom attributes in the Individual file var allFields = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList(); var customAttributes = allFields .Where(f => f.index > GroupCapacity) .ToDictionary(f => f.index, f => f.node.Name); var groupAttributes = new AttributeService(lookupContext).GetByEntityTypeId(new Group().TypeId).ToList(); var completed = 0; ReportProgress(0, $"Starting group import ({numImportedGroups:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowGroupKey = row[GroupId]; // // Determine if we are still working with the same group or not. // if (rowGroupKey != null && rowGroupKey != currentGroup.ForeignKey) { currentGroup = LoadGroupBasic(lookupContext, rowGroupKey, row[GroupName], row[GroupCreatedDate], row[GroupType], row[GroupParentGroupId], row[GroupActive], row[GroupDescription]); // // Set the group campus // var campusName = row[GroupCampus]; if (!string.IsNullOrWhiteSpace(campusName)) { var groupCampus = CampusList.FirstOrDefault(c => c.Name.Equals(campusName, StringComparison.InvariantCultureIgnoreCase) || c.ShortCode.Equals(campusName, StringComparison.InvariantCultureIgnoreCase)); if (groupCampus == null) { groupCampus = new Campus { IsSystem = false, Name = campusName, ShortCode = campusName.RemoveWhitespace(), IsActive = true }; lookupContext.Campuses.Add(groupCampus); lookupContext.SaveChanges(DisableAuditing); CampusList.Add(groupCampus); } currentGroup.CampusId = groupCampus.Id; } // // If the group type has one or more location types defined then import the // primary address as the first location type. // var groupType = groupTypeService.Get(currentGroup.GroupTypeId); if (groupType.LocationTypes.Count > 0 && (!string.IsNullOrWhiteSpace(row[GroupAddress]) || !string.IsNullOrWhiteSpace(row[GroupNamedLocation])) && currentGroup.GroupLocations.Count == 0) { var primaryLocationTypeId = groupType.LocationTypes.ToList()[0].LocationTypeValueId; var grpAddress = row[GroupAddress]; var grpAddress2 = row[GroupAddress2]; var grpCity = row[GroupCity]; var grpState = row[GroupState]; var grpZip = row[GroupZip]; var grpCountry = row[GroupCountry]; var namedLocation = row[GroupNamedLocation]; if (string.IsNullOrWhiteSpace(namedLocation)) { var primaryAddress = locationService.Get(grpAddress, grpAddress2, grpCity, grpState, grpZip, grpCountry, verifyLocation: false); if (primaryAddress != null) { var primaryLocation = new GroupLocation { LocationId = primaryAddress.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = primaryLocationTypeId }; newGroupLocations.Add(primaryLocation, rowGroupKey); } } else { var primaryAddress = locationService.Queryable().FirstOrDefault(l => l.Name.Equals(namedLocation) || l.ForeignKey.Equals(namedLocation)); if (primaryAddress != null) { var primaryLocation = new GroupLocation { LocationId = primaryAddress.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = primaryLocationTypeId }; newGroupLocations.Add(primaryLocation, rowGroupKey); } else { LogException("Group Import", string.Format("The named location {0} was not found and will not be mapped.", namedLocation)); } } } // // If the group type has two or more location types defined then import the // secondary address as the group type's second location type. // if (groupType.LocationTypes.Count > 1 && !string.IsNullOrWhiteSpace(row[GroupSecondaryAddress]) && currentGroup.GroupLocations.Count < 2) { var secondaryLocationTypeId = groupType.LocationTypes.ToList()[1].LocationTypeValueId; var grpSecondAddress = row[GroupSecondaryAddress]; var grpSecondAddress2 = row[GroupSecondaryAddress2]; var grpSecondCity = row[GroupSecondaryCity]; var grpSecondState = row[GroupSecondaryState]; var grpSecondZip = row[GroupSecondaryZip]; var grpSecondCountry = row[GroupSecondaryCountry]; var secondaryAddress = locationService.Get(grpSecondAddress, grpSecondAddress2, grpSecondCity, grpSecondState, grpSecondZip, grpSecondCountry, verifyLocation: false); if (secondaryAddress != null) { var secondaryLocation = new GroupLocation { LocationId = secondaryAddress.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = secondaryLocationTypeId }; newGroupLocations.Add(secondaryLocation, rowGroupKey); } } // // Set the group's sorting order. // var groupOrder = 9999; int.TryParse(row[GroupOrder], out groupOrder); currentGroup.Order = groupOrder; // // Set the group's capacity // var capacity = row[GroupCapacity].AsIntegerOrNull(); if (capacity.HasValue) { currentGroup.GroupCapacity = capacity; if (groupType.GroupCapacityRule == GroupCapacityRule.None) { groupType.GroupCapacityRule = GroupCapacityRule.Hard; } } // // Set the group's schedule // if (!string.IsNullOrWhiteSpace(row[GroupDayOfWeek])) { DayOfWeek dayEnum; if (Enum.TryParse(row[GroupDayOfWeek], true, out dayEnum)) { if (groupType.AllowedScheduleTypes != ScheduleType.Weekly) { groupType.AllowedScheduleTypes = ScheduleType.Weekly; } var day = dayEnum; var time = row[GroupTime].AsDateTime(); currentGroup.ScheduleId = AddNamedSchedule(lookupContext, string.Empty, string.Empty, day, time, null, rowGroupKey).Id; } } // // Assign Attributes // if (customAttributes.Any()) { lookupContext.SaveChanges(); foreach (var attributePair in customAttributes) { var pairs = attributePair.Value.Split('^'); var categoryName = string.Empty; var attributeName = string.Empty; var attributeTypeString = string.Empty; var attributeForeignKey = string.Empty; var definedValueForeignKey = string.Empty; var fieldTypeId = TextFieldTypeId; if (pairs.Length == 1) { attributeName = pairs[0]; } else if (pairs.Length == 2) { attributeName = pairs[0]; attributeTypeString = pairs[1]; } else if (pairs.Length >= 3) { categoryName = pairs[1]; attributeName = pairs[2]; if (pairs.Length >= 4) { attributeTypeString = pairs[3]; } if (pairs.Length >= 5) { attributeForeignKey = pairs[4]; } if (pairs.Length >= 6) { definedValueForeignKey = pairs[5]; } } var definedValueForeignId = definedValueForeignKey.AsType <int?>(); // // Translate the provided attribute type into one we know about. // fieldTypeId = GetAttributeFieldType(attributeTypeString); Rock.Model.Attribute currentAttribute = null; if (string.IsNullOrEmpty(attributeName)) { LogException("Group Attribute", string.Format("Group Attribute Name cannot be blank '{0}'.", attributePair.Value)); } else { if (string.IsNullOrWhiteSpace(attributeForeignKey)) { attributeForeignKey = string.Format("Bulldozer_{0}_{1}_{2}", groupType.Id, categoryName.RemoveWhitespace(), attributeName.RemoveWhitespace()).Left(100); } currentAttribute = groupAttributes.FirstOrDefault(a => a.Name.Equals(attributeName, StringComparison.OrdinalIgnoreCase) && a.FieldTypeId == fieldTypeId && a.EntityTypeId == currentGroup.TypeId && a.EntityTypeQualifierValue == groupType.Id.ToString() ); if (currentAttribute == null) { currentAttribute = AddEntityAttribute(lookupContext, currentGroup.TypeId, "GroupTypeId", groupType.Id.ToString(), attributeForeignKey, categoryName, attributeName, string.Empty, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString); groupAttributes.Add(currentAttribute); } var attributeValue = row[attributePair.Key]; if (!string.IsNullOrEmpty(attributeValue)) { AddEntityAttributeValue(lookupContext, currentAttribute, currentGroup, row[attributePair.Key], null, true); } } } } // // Changes to groups need to be saved right away since one group // will reference another group. // lookupContext.SaveChanges(); // // Keep the user informed as to what is going on and save in batches. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} groups imported."); } if (completed % ReportingNumber < 1) { SaveGroupLocations(newGroupLocations); ReportPartialProgress(); // Reset lookup context lookupContext.SaveChanges(); lookupContext = new RockContext(); locationService = new LocationService(lookupContext); groupTypeService = new GroupTypeService(lookupContext); newGroupLocations.Clear(); } } } // // Check to see if any rows didn't get saved to the database // if (newGroupLocations.Any()) { SaveGroupLocations(newGroupLocations); } lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, $"Finished group import: {completed:N0} groups added or updated."); return(completed); }
/// <summary> /// Loads the group membership data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadRelationshipGroupMember( CSVInstance csvData ) { AddMissingRelationshipGroups(); var lookupContext = new RockContext(); var groupTypeRoleService = new GroupTypeRoleService( lookupContext ); var groupMemberService = new GroupMemberService( lookupContext ); var newMemberList = new List<GroupMember>(); int completed = 0; int imported = 0; ReportProgress( 0, "Starting relationship import." ); var knownRelationshipGroupType = CachedTypes.KnownRelationshipGroupType; if ( knownRelationshipGroupType != null ) { var relationshipGroupTypeRoles = groupTypeRoleService .Queryable().AsNoTracking() .Where( r => r.GroupTypeId == knownRelationshipGroupType.Id ) .ToDictionary( r => r.Name, r => r.Id ); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ( ( row = csvData.Database.FirstOrDefault() ) != null ) { string rowGroupMemberKey = row[GroupMemberId]; string rowGroupKey = row[GroupMemberGroupId]; string rowPersonKey = row[GroupMemberPersonId]; string rowCreatedDate = row[GroupMemberCreatedDate]; string rowMemberRole = row[GroupMemberRole]; string rowMemberActive = row[GroupMemberActive]; int? rowGroupMemberId = rowGroupMemberKey.AsType<int?>(); // // Find Owner // var ownerKeys = GetPersonKeys( rowGroupKey ); if ( ownerKeys == null || ownerKeys.PersonId == 0 ) { LogException( "InvalidGroupKey", string.Format( "Owner person key {0} not found", rowGroupKey ) ); ReportProgress( 0, string.Format( "Owner person key {0} not found", rowGroupKey ) ); } // // Find this person in the database. // var personKeys = GetPersonKeys( rowPersonKey ); if ( personKeys == null || personKeys.PersonId == 0 ) { LogException( "InvalidPersonKey", string.Format( "Person key {0} not found", rowPersonKey ) ); ReportProgress( 0, string.Format( "Person key {0} not found", rowPersonKey ) ); } if ( ownerKeys != null && ownerKeys.PersonId != 0 ) { var knownRelationshipGroup = new GroupMemberService( lookupContext ).Queryable( true ) .AsNoTracking() .Where( m => m.PersonId == ownerKeys.PersonId && m.GroupRoleId == CachedTypes.KnownRelationshipOwnerRoleId && m.Group.GroupTypeId == knownRelationshipGroupType.Id ) .Select( m => m.Group ) .FirstOrDefault(); if ( knownRelationshipGroup != null && knownRelationshipGroup.Id > 0 ) { if ( personKeys != null && personKeys.PersonId != 0 ) { GroupMember groupMember = new GroupMember(); groupMember.PersonId = personKeys.PersonId; groupMember.GroupId = knownRelationshipGroup.Id; groupMember.CreatedDateTime = ParseDateOrDefault( rowCreatedDate, ImportDateTime ); groupMember.ModifiedDateTime = ImportDateTime; groupMember.CreatedByPersonAliasId = ImportPersonAliasId; groupMember.ForeignKey = rowGroupMemberKey; groupMember.ForeignId = rowGroupMemberId; groupMember.GroupMemberStatus = GetGroupMemberStatus( rowMemberActive ); // // Find and set the group role id. // if ( !string.IsNullOrEmpty( rowMemberRole ) ) { if ( relationshipGroupTypeRoles.ContainsKey( rowMemberRole ) ) { groupMember.GroupRoleId = relationshipGroupTypeRoles[rowMemberRole]; } else { var newRoleId = AddGroupRole( lookupContext, knownRelationshipGroupType.Guid.ToString(), rowMemberRole ); relationshipGroupTypeRoles.Add( rowMemberRole, newRoleId ); groupMember.GroupRoleId = newRoleId; } } else { if ( knownRelationshipGroupType.DefaultGroupRoleId != null ) { groupMember.GroupRoleId = ( int ) knownRelationshipGroupType.DefaultGroupRoleId; } else { groupMember.GroupRoleId = knownRelationshipGroupType.Roles.First().Id; } } // // Add member to the group. // knownRelationshipGroup.Members.Add( groupMember ); newMemberList.Add( groupMember ); imported++; } else { LogException( "InvalidPersonKey", string.Format( "Person with Foreign Id {0} not found", rowPersonKey ) ); } } else { LogException( "InvalidGroupKey", string.Format( "Relationship Group with Owner Person Foreign Id {0} not found", rowGroupKey ) ); } } else { LogException( "InvalidGroupKey", string.Format( "Relationship Group Owner with Person Foreign Id {0} not found", rowGroupKey ) ); } // // Notify user of our status. // completed++; if ( completed % ( ReportingNumber * 10 ) < 1 ) { ReportProgress( 0, string.Format( "{0:N0} rows processed, {1:N0} relationships imported.", completed, imported ) ); } if ( completed % ReportingNumber < 1 ) { SaveGroupMembers( newMemberList ); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables newMemberList.Clear(); } } } else { ReportProgress( 0, "Known Relationship Group Type Missing!" ); } // // Save any final changes to new groups // if ( newMemberList.Any() ) { SaveGroupMembers( newMemberList ); } // // Save any changes to existing groups // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress( 0, string.Format( "Finished relationship import: {0:N0} relationships added.", imported ) ); return completed; }
/// <summary> /// Loads the polygon group data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadGroupPolygon(CSVInstance csvData) { // Required variables var lookupContext = new RockContext(); var numImportedGroups = ImportedGroups.Count(); var newGroupLocations = new Dictionary <GroupLocation, string>(); var currentGroup = new Group(); var coordinateString = string.Empty; var startCoordinate = string.Empty; var endCoordinate = string.Empty; var geographicAreaTypeId = DefinedValueCache.Get("44990C3F-C45B-EDA3-4B65-A238A581A26F").Id; var completed = 0; ReportProgress(0, $"Starting polygon group import ({numImportedGroups:N0} already exist)."); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var rowGroupKey = row[GroupId]; var rowGroupId = rowGroupKey.AsType <int?>(); var rowLat = row[Latitude]; var rowLong = row[Longitude]; // // Determine if we are still working with the same group or not. // if (!string.IsNullOrWhiteSpace(rowGroupKey) && rowGroupKey != currentGroup.ForeignKey) { if (!string.IsNullOrWhiteSpace(coordinateString)) { if (startCoordinate != endCoordinate) { coordinateString = $"{coordinateString}|{startCoordinate}"; } var coords = coordinateString.Split('|'); if (coords.Length > 3) { var polygon = CreatePolygonLocation(coordinateString, row[GroupCreatedDate], rowGroupKey, rowGroupId); if (polygon != null) { var geographicArea = new GroupLocation { LocationId = polygon.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = geographicAreaTypeId, GroupId = currentGroup.Id }; newGroupLocations.Add(geographicArea, currentGroup.ForeignKey); } } } currentGroup = LoadGroupBasic(lookupContext, rowGroupKey, row[GroupName], row[GroupCreatedDate], row[GroupType], row[GroupParentGroupId], row[GroupActive]); // reset coordinateString coordinateString = string.Empty; if (!string.IsNullOrWhiteSpace(rowLat) && !string.IsNullOrWhiteSpace(rowLong) && rowLat.AsType <double>() != 0 && rowLong.AsType <double>() != 0) { coordinateString = $"{rowLat},{rowLong}"; startCoordinate = $"{rowLat},{rowLong}"; } // // Set the group campus // var campusName = row[GroupCampus]; if (!string.IsNullOrWhiteSpace(campusName)) { var groupCampus = CampusList.FirstOrDefault(c => c.Name.Equals(campusName, StringComparison.InvariantCultureIgnoreCase) || c.ShortCode.Equals(campusName, StringComparison.InvariantCultureIgnoreCase)); if (groupCampus == null) { groupCampus = new Campus { IsSystem = false, Name = campusName, ShortCode = campusName.RemoveWhitespace(), IsActive = true }; lookupContext.Campuses.Add(groupCampus); lookupContext.SaveChanges(DisableAuditing); CampusList.Add(groupCampus); } currentGroup.CampusId = groupCampus.Id; } // // Set the group's sorting order. // var groupOrder = 9999; int.TryParse(row[GroupOrder], out groupOrder); currentGroup.Order = groupOrder; // // Changes to groups need to be saved right away since one group // will reference another group. // lookupContext.SaveChanges(); completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, $"{completed:N0} groups imported."); } if (completed % ReportingNumber < 1) { ReportPartialProgress(); } } else if (rowGroupKey == currentGroup.ForeignKey && (!string.IsNullOrWhiteSpace(rowLat) && !string.IsNullOrWhiteSpace(rowLong) && rowLat.AsType <double>() != 0 && rowLong.AsType <double>() != 0)) { coordinateString = $"{coordinateString}|{rowLat},{rowLong}"; endCoordinate = $"{rowLat},{rowLong}"; } } if (!string.IsNullOrWhiteSpace(coordinateString)) { if (startCoordinate != endCoordinate) { coordinateString = coordinateString + $"|{startCoordinate}"; } var coords = coordinateString.Split('|'); if (coords.Length > 3) { var polygon = CreatePolygonLocation(coordinateString, currentGroup.CreatedDateTime.ToString(), currentGroup.ForeignKey, currentGroup.ForeignId); if (polygon != null) { var geographicArea = new GroupLocation { LocationId = polygon.Id, IsMailingLocation = true, IsMappedLocation = true, GroupLocationTypeValueId = geographicAreaTypeId, GroupId = currentGroup.Id }; newGroupLocations.Add(geographicArea, currentGroup.ForeignKey); } } } // // Save rows to the database // ReportProgress(0, $"Saving {newGroupLocations.Count} polygons."); if (newGroupLocations.Any()) { SaveGroupLocations(newGroupLocations); } lookupContext.SaveChanges(); DetachAllInContext(lookupContext); lookupContext.Dispose(); ReportProgress(0, $"Finished polygon group import: {completed:N0} groups added or updated."); return(completed); }
/// <summary> /// Loads the group membership data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadGroupMember( CSVInstance csvData ) { var lookupContext = new RockContext(); var groupTypeRoleService = new GroupTypeRoleService( lookupContext ); var groupMemberService = new GroupMemberService( lookupContext ); Dictionary<string, int> importedMembers = groupMemberService.Queryable( true ).AsNoTracking() .Where( m => m.ForeignKey != null ) .ToDictionary( m => m.ForeignKey, m => m.Id ); var groupTypeRoles = new Dictionary<int?, Dictionary<string, int>>(); foreach ( var role in groupTypeRoleService.Queryable().AsNoTracking().GroupBy( r => r.GroupTypeId ) ) { groupTypeRoles.Add( role.Key, role.ToDictionary( r => r.Name, r => r.Id, StringComparer.OrdinalIgnoreCase ) ); } var currentGroup = new Group(); var newMemberList = new List<GroupMember>(); int completed = 0; int imported = 0; ReportProgress( 0, string.Format( "Starting group member import ({0:N0} already exist).", importedMembers.Count ) ); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ( ( row = csvData.Database.FirstOrDefault() ) != null ) { string rowGroupMemberKey = row[GroupMemberId]; string rowGroupKey = row[GroupMemberGroupId]; string rowPersonKey = row[GroupMemberPersonId]; string rowCreatedDate = row[GroupMemberCreatedDate]; string rowMemberRole = row[GroupMemberRole]; string rowMemberActive = row[GroupMemberActive]; int? rowGroupMemberId = rowGroupMemberKey.AsType<int?>(); // // Find this person in the database. // var personKeys = GetPersonKeys( rowPersonKey ); if ( personKeys == null || personKeys.PersonId == 0 ) { LogException( "InvalidPersonKey", string.Format( "Person key {0} not found", rowPersonKey ) ); ReportProgress( 0, string.Format( "Person key {0} not found", rowPersonKey ) ); } // // Check that this member isn't already in our data // bool memberExists = false; if ( importedMembers.Count > 0 ) { memberExists = importedMembers.ContainsKey( rowGroupMemberKey ); } if ( !memberExists && ( personKeys != null && personKeys.PersonId != 0 ) ) { if ( currentGroup == null || rowGroupKey != currentGroup.ForeignKey ) { currentGroup = ImportedGroups.FirstOrDefault( g => g.ForeignKey.Equals( rowGroupKey ) ); } if ( currentGroup != null ) { GroupMember groupMember = new GroupMember(); groupMember.PersonId = personKeys.PersonId; groupMember.GroupId = currentGroup.Id; groupMember.CreatedDateTime = ParseDateOrDefault( rowCreatedDate, ImportDateTime ); groupMember.ModifiedDateTime = ImportDateTime; groupMember.CreatedByPersonAliasId = ImportPersonAliasId; groupMember.ForeignKey = rowGroupMemberKey; groupMember.ForeignId = rowGroupMemberId; groupMember.GroupMemberStatus = GetGroupMemberStatus( rowMemberActive ); // // Find and set the group role id. // if ( !string.IsNullOrEmpty( rowMemberRole ) ) { var typeExists = groupTypeRoles.ContainsKey( currentGroup.GroupTypeId ); if ( typeExists && groupTypeRoles[currentGroup.GroupTypeId].ContainsKey( rowMemberRole ) ) { groupMember.GroupRoleId = groupTypeRoles[currentGroup.GroupTypeId][rowMemberRole]; } else { var newRoleId = AddGroupRole( lookupContext, currentGroup.GroupType.Guid.ToString(), rowMemberRole ); // check if adding an additional role for this grouptype or creating the first one if ( typeExists ) { groupTypeRoles[currentGroup.GroupType.Id].Add( rowMemberRole, newRoleId ); } else { groupTypeRoles.Add( currentGroup.GroupType.Id, new Dictionary<string, int> { { rowMemberRole, newRoleId } } ); } groupMember.GroupRoleId = newRoleId; } } else { if ( currentGroup.GroupType.DefaultGroupRoleId != null ) { groupMember.GroupRoleId = ( int ) currentGroup.GroupType.DefaultGroupRoleId; } else { groupMember.GroupRoleId = currentGroup.GroupType.Roles.First().Id; } } // // Add member to the group. // currentGroup.Members.Add( groupMember ); newMemberList.Add( groupMember ); imported++; } else { LogException( "InvalidGroupKey", string.Format( "Group key {0} not found", rowGroupKey ) ); } } // // Notify user of our status. // completed++; if ( completed % ( ReportingNumber * 10 ) < 1 ) { ReportProgress( 0, string.Format( "{0:N0} rows processed, {1:N0} members imported.", completed, imported ) ); } if ( completed % ReportingNumber < 1 ) { SaveGroupMembers( newMemberList ); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables currentGroup = new Group(); newMemberList.Clear(); } } // // Save any final changes to new groups // if ( newMemberList.Any() ) { SaveGroupMembers( newMemberList ); } // // Save any changes to existing groups // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress( 0, string.Format( "Finished group member import: {0:N0} members added.", imported ) ); return completed; }
/// <summary> /// Loads the UserLogin data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadUserLogin(CSVInstance csvData) { var lookupContext = new RockContext(); var userLoginService = new UserLoginService(lookupContext); var newUserLoginList = new List <UserLogin>(); var existingUserLoginList = new List <UserLogin>(); existingUserLoginList.AddRange(userLoginService.Queryable().AsNoTracking().Where(a => a.ForeignId == null)); int completed = 0; int importedCount = 0; int alreadyImportedCount = userLoginService.Queryable().AsNoTracking().Count(a => a.ForeignKey != null); ReportProgress(0, string.Format("Starting user login import ({0:N0} already exist).", alreadyImportedCount)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { string rowUserLoginId = row[UserLoginId]; string rowUserLoginPersonId = row[UserLoginPersonId]; string rowUserLoginUserName = row[UserLoginUserName]; string rowUserLoginPassword = row[UserLoginPassword]; string rowUserLoginDateCreated = row[UserLoginDateCreated]; string rowUserLoginAuthenticationType = row[UserLoginAuthenticationType]; string rowUserLoginIsConfirmed = row[UserLoginIsConfirmed]; int?rowLoginId = rowUserLoginId.AsType <int?>(); int authenticationTypeId = EntityTypeCache.Get(rowUserLoginAuthenticationType).Id; // // Find this person in the database. // var personKeys = GetPersonKeys(rowUserLoginPersonId); if (personKeys == null || personKeys.PersonId == 0) { throw new System.Collections.Generic.KeyNotFoundException(string.Format("Person key {0} not found", rowUserLoginPersonId), null); } // // Verify the authentication type exists. // if (authenticationTypeId < 1) { throw new System.Collections.Generic.KeyNotFoundException(string.Format("Authentication type {0} not found", rowUserLoginAuthenticationType), null); } // // Check that this user login record doesn't already exist. // bool exists = false; if (existingUserLoginList.Count > 0) { exists = userLoginService.Queryable().AsNoTracking().Any(a => a.UserName.ToLower() == rowUserLoginUserName.ToLower()); } if (exists == false && alreadyImportedCount > 0) { exists = userLoginService.Queryable().AsNoTracking().Any(a => a.ForeignKey == rowUserLoginId); } if (!exists) { // // Create and populate the new user login record. // UserLogin login = new UserLogin(); login.CreatedDateTime = ParseDateOrDefault(rowUserLoginDateCreated, DateTime.Now); login.CreatedByPersonAliasId = ImportPersonAliasId; login.EntityTypeId = authenticationTypeId; login.IsConfirmed = ParseBoolOrDefault(rowUserLoginIsConfirmed, true); login.UserName = rowUserLoginUserName; login.Password = rowUserLoginPassword; login.PersonId = personKeys.PersonId; login.ForeignKey = rowUserLoginId; login.ForeignId = rowLoginId; // // Force not confirmed if no password provided for database logins. // if (rowUserLoginAuthenticationType == "Rock.Security.Authentication.Database" && string.IsNullOrWhiteSpace(rowUserLoginPassword)) { login.IsConfirmed = false; } // // Add the record for delayed saving. // newUserLoginList.Add(login); importedCount++; } // // Notify user of our status. // completed++; if (completed % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} user login records processed, {1:N0} imported.", completed, importedCount)); } if (completed % ReportingNumber < 1) { SaveUserLogin(newUserLoginList); lookupContext.SaveChanges(); ReportPartialProgress(); // Clear out variables newUserLoginList.Clear(); userLoginService = new UserLoginService(lookupContext); } } // // Save any final changes to new records // if (newUserLoginList.Any()) { SaveUserLogin(newUserLoginList); } // // Save any other changes to existing items. // lookupContext.SaveChanges(); lookupContext.Dispose(); ReportProgress(0, string.Format("Finished user login import: {0:N0} records added.", importedCount)); return(completed); }
/// <summary> /// Loads the Prayer Requests data. /// </summary> /// <param name="csvData">The CSV data.</param> private int LoadPrayerRequest(CSVInstance csvData) { var lookupContext = new RockContext(); var importedPrayerRequests = new PrayerRequestService(lookupContext).Queryable().Count(p => p.ForeignKey != null); var prayerRequestList = new List <PrayerRequest>(); var completedItems = 0; var addedItems = 0; ReportProgress(0, string.Format("Verifying prayer request import ({0:N0} already imported).", importedPrayerRequests)); string[] row; // Uses a look-ahead enumerator: this call will move to the next record immediately while ((row = csvData.Database.FirstOrDefault()) != null) { var prayerRequestCategory = row[PrayerRequestCategory] as string; var prayerRequestText = row[PrayerRequestText] as string; var prayerRequestDate = row[PrayerRequestDate] as string; var prayerRequestId = row[PrayerRequestId] as string; var prayerRequestFirstName = row[PrayerRequestFirstName] as string; var prayerRequestLastName = row[PrayerRequestLastName] as string; var prayerRequestEmail = row[PrayerRequestEmail] as string; var prayerRequestExpireDate = row[PrayerRequestExpireDate] as string; var prayerRequestAllowComments = ParseBoolOrDefault(row[PrayerRequestAllowComments], true); var prayerRequestIsPublic = ParseBoolOrDefault(row[PrayerRequestIsPublic], true); var prayerRequestIsApproved = ParseBoolOrDefault(row[PrayerRequestIsApproved], true); var prayerRequestApprovedDate = row[PrayerRequestApprovedDate] as string; var prayerRequestApprovedById = row[PrayerRequestApprovedById] as string; var prayerRequestCreatedById = row[PrayerRequestCreatedById] as string; var prayerRequestRequestedById = row[PrayerRequestRequestedById] as string; var prayerRequestAnswerText = row[PrayerRequestAnswerText] as string; var prayerRequestCampusName = row[PrayerRequestCampus] as string; if (!string.IsNullOrWhiteSpace(prayerRequestText)) { var email = string.Empty; if (prayerRequestEmail.IsEmail()) { email = prayerRequestEmail; } int?approvedByAliasId = null; var approvedByPersonKeys = GetPersonKeys(prayerRequestApprovedById); if (approvedByPersonKeys != null) { approvedByAliasId = approvedByPersonKeys.PersonAliasId; } int?createdByAliasId = null; var createdByPersonKeys = GetPersonKeys(prayerRequestCreatedById); if (createdByPersonKeys != null) { createdByAliasId = createdByPersonKeys.PersonAliasId; } int?requestedByAliasId = null; var requestedByPersonKeys = GetPersonKeys(prayerRequestRequestedById); if (requestedByPersonKeys != null) { requestedByAliasId = requestedByPersonKeys.PersonAliasId; } var prayerRequest = AddPrayerRequest(lookupContext, prayerRequestCategory, prayerRequestText, prayerRequestDate, prayerRequestId, prayerRequestFirstName, prayerRequestLastName, email, prayerRequestExpireDate, prayerRequestAllowComments, prayerRequestIsPublic, prayerRequestIsApproved, prayerRequestApprovedDate, approvedByAliasId, createdByAliasId, requestedByAliasId, prayerRequestAnswerText, false); if (prayerRequest.Id == 0) { if (!string.IsNullOrWhiteSpace(prayerRequestCampusName)) { var campus = CampusList.FirstOrDefault(c => c.Name.Equals(prayerRequestCampusName, StringComparison.OrdinalIgnoreCase) || c.ShortCode.Equals(prayerRequestCampusName, StringComparison.OrdinalIgnoreCase)); if (campus == null) { campus = new Campus { IsSystem = false, Name = prayerRequestCampusName, ShortCode = prayerRequestCampusName.RemoveWhitespace(), IsActive = true }; lookupContext.Campuses.Add(campus); lookupContext.SaveChanges(DisableAuditing); CampusList.Add(campus); } prayerRequest.CampusId = campus.Id; } prayerRequestList.Add(prayerRequest); addedItems++; } completedItems++; if (completedItems % (ReportingNumber * 10) < 1) { ReportProgress(0, string.Format("{0:N0} prayer requests processed.", completedItems)); } if (completedItems % ReportingNumber < 1) { SavePrayerRequests(prayerRequestList); ReportPartialProgress(); prayerRequestList.Clear(); } } } if (prayerRequestList.Any()) { SavePrayerRequests(prayerRequestList); } ReportProgress(100, string.Format("Finished prayer request import: {0:N0} prayer requests processed, {1:N0} imported.", completedItems, addedItems)); return(completedItems); }