Example #1
0
        /// <summary>
        /// Maps the activity ministry data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapActivityMinistry(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();
            var newGroups     = new List <Group>();

            const string attendanceTypeName = "Attendance History";
            var          groupTypeHistory   = ImportedGroupTypes.FirstOrDefault(t => t.ForeignKey.Equals(attendanceTypeName));

            if (groupTypeHistory == null)
            {
                groupTypeHistory = AddGroupType(lookupContext, attendanceTypeName, string.Format("{0} imported {1}", attendanceTypeName, ImportDateTime), null,
                                                null, GroupTypeCheckinTemplateId, true, true, true, true, typeForeignKey: attendanceTypeName);
                ImportedGroupTypes.Add(groupTypeHistory);
            }

            const string groupsParentName     = "Archived Groups";
            var          archivedGroupsParent = ImportedGroups.FirstOrDefault(g => g.ForeignKey.Equals(groupsParentName.RemoveWhitespace()));

            if (archivedGroupsParent == null)
            {
                archivedGroupsParent = AddGroup(lookupContext, GeneralGroupTypeId, null, groupsParentName, true, null, ImportDateTime, groupsParentName.RemoveWhitespace(), true, ImportPersonAliasId);
                ImportedGroups.Add(archivedGroupsParent);
            }

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying ministry import ({0:N0} found, {1:N0} already exist).", totalRows, ImportedGroupTypes.Count));

            foreach (var row in tableData.OrderBy(r => r["Ministry_ID"] as int?).ThenBy(r => r["Activity_ID"] as int?))
            {
                // get the ministry data
                var ministryId     = row["Ministry_ID"] as int?;
                var activityId     = row["Activity_ID"] as int?;
                var ministryName   = row["Ministry_Name"] as string;
                var activityName   = row["Activity_Name"] as string;
                var ministryActive = row["Ministry_Active"] as string;
                var activityActive = row["Activity_Active"] as string;
                int?campusId       = null;

                if (ministryId.HasValue && !string.IsNullOrWhiteSpace(ministryName) && !ministryName.Equals("Delete", StringComparison.OrdinalIgnoreCase))
                {
                    // check for a ministry group campus context
                    if (ministryName.Any(n => ValidDelimiters.Contains(n)))
                    {
                        campusId = campusId ?? GetCampusId(ministryName);
                        if (campusId.HasValue)
                        {
                            // strip the campus from the ministry name to use for grouptype (use the original name on groups though)
                            ministryName = StripPrefix(ministryName, campusId);
                        }
                    }

                    // add the new grouptype if it doesn't exist
                    var currentGroupType = ImportedGroupTypes.FirstOrDefault(t => t.ForeignKey.Equals(ministryName));
                    if (currentGroupType == null)
                    {
                        // save immediately so we can use the grouptype for a group
                        currentGroupType = AddGroupType(lookupContext, ministryName, string.Format("{0} imported {1}", ministryName, ImportDateTime), groupTypeHistory.Id,
                                                        null, null, true, true, true, true, typeForeignKey: ministryName);
                        ImportedGroupTypes.Add(currentGroupType);
                    }

                    // create a campus level parent for the ministry group
                    var parentGroupId = archivedGroupsParent.Id;
                    if (campusId.HasValue)
                    {
                        var campus      = CampusList.FirstOrDefault(c => c.Id == campusId);
                        var campusGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey.Equals(campus.ShortCode) && g.ParentGroupId == parentGroupId);
                        if (campusGroup == null)
                        {
                            campusGroup = AddGroup(lookupContext, GeneralGroupTypeId, parentGroupId, campus.Name, true, campus.Id, ImportDateTime, campus.ShortCode, true, ImportPersonAliasId);
                            ImportedGroups.Add(campusGroup);
                        }

                        parentGroupId = campusGroup.Id;
                    }

                    // add a ministry group level if it doesn't exist
                    var ministryGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey.Equals(ministryId.ToString()));
                    if (ministryGroup == null)
                    {
                        // save immediately so we can use the group as a parent
                        ministryGroup = AddGroup(lookupContext, currentGroupType.Id, parentGroupId, ministryName, ministryActive.AsBoolean(), campusId, null, ministryId.ToString(), true, ImportPersonAliasId);
                        ImportedGroups.Add(ministryGroup);
                    }

                    // check for an activity group campus context
                    if (!string.IsNullOrWhiteSpace(activityName) && activityName.Any(n => ValidDelimiters.Contains(n)))
                    {
                        campusId = campusId ?? GetCampusId(activityName);
                        if (campusId.HasValue)
                        {
                            activityName = StripPrefix(activityName, campusId);
                        }
                    }

                    // add the child activity group if it doesn't exist
                    var activityGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey.Equals(activityId.ToString()));
                    if (activityGroup == null && activityId.HasValue && !string.IsNullOrWhiteSpace(activityName) && !activityName.Equals("Delete", StringComparison.OrdinalIgnoreCase))
                    {
                        // don't save immediately, we'll batch add later
                        activityGroup = AddGroup(lookupContext, currentGroupType.Id, ministryGroup.Id, activityName, activityActive.AsBoolean(), campusId, null, activityId.ToString(), false, ImportPersonAliasId);
                        newGroups.Add(activityGroup);
                    }

                    completedItems++;

                    if (completedItems % percentage < 1)
                    {
                        var percentComplete = completedItems / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} ministries imported ({1}% complete).", completedItems, percentComplete));
                    }

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveGroups(newGroups);
                        ReportPartialProgress();
                        ImportedGroups.AddRange(newGroups);

                        // Reset lists and context
                        lookupContext = new RockContext();
                        newGroups.Clear();
                    }
                }
            }

            if (newGroups.Any())
            {
                SaveGroups(newGroups);
                ImportedGroups.AddRange(newGroups);
            }

            lookupContext.Dispose();
            ReportProgress(100, string.Format("Finished ministry import: {0:N0} ministries imported.", completedItems));
        }
Example #2
0
        /// <summary>
        /// Maps the people attributes to date/text attributes.
        /// Also converts attribute comments to person notes.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapAttribute(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();
            var personService = new PersonService(lookupContext);

            var personAttributes       = new AttributeService(lookupContext).GetByEntityTypeId(PersonEntityTypeId).Include("Categories").AsNoTracking().ToList();
            var importedAttributeCount = lookupContext.AttributeValues.Count(v => v.Attribute.EntityTypeId == PersonEntityTypeId && v.ForeignKey != null);
            var baptizedHereAttribute  = personAttributes.FirstOrDefault(a => a.Key.Equals("BaptizedHere", StringComparison.InvariantCultureIgnoreCase));
            var newBenevolences        = new List <BenevolenceRequest>();
            var peopleToUpdate         = new Dictionary <int, Person>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying attribute import ({totalRows:N0} found, {importedAttributeCount:N0} already exist).");

            foreach (var row in tableData.OrderBy(r => r["Attribute_Name"]).ThenByDescending(r => r["Start_Date"] != null).ThenBy(r => r["Start_Date"]).ThenBy(r => r["End_Date"]).Where(r => r != null))
            {
                // add the new attribute
                var attributeGroupName = row["Attribute_Group_Name"] as string;
                var attributeName      = row["Attribute_Name"] as string;
                var attributeDate      = row["Start_Date"] as DateTime?;
                attributeDate = attributeDate ?? row["End_Date"] as DateTime?;
                var attributeComment = row["Comment"] as string;
                var attributeCreator = row["Staff_Individual_ID"] as int?;
                int?campusId         = null;

                if (attributeGroupName.IsNullOrWhiteSpace() && attributeName.IsNullOrWhiteSpace())
                {
                    continue;
                }

                // strip attribute group name (will become a category)
                if (attributeGroupName.Any(n => ValidDelimiters.Contains(n)))
                {
                    campusId = campusId ?? GetCampusId(attributeGroupName);
                    if (campusId.HasValue)
                    {
                        attributeGroupName = StripPrefix(attributeGroupName, campusId);
                    }
                }

                // strip attribute name
                if (attributeName.Any(n => ValidDelimiters.Contains(n)))
                {
                    campusId = campusId ?? GetCampusId(attributeName);
                    if (campusId.HasValue)
                    {
                        attributeName = StripPrefix(attributeName, campusId);
                    }
                }

                var personBaptizedHere     = false;
                var isBenevolenceAttribute = false;
                if (attributeName.StartsWith("Baptism", StringComparison.CurrentCultureIgnoreCase))
                {   // match the core Baptism attribute
                    attributeName      = "Baptism Date";
                    personBaptizedHere = attributeCreator.HasValue;
                }
                else if (attributeName.StartsWith("Benevolence", StringComparison.CurrentCultureIgnoreCase))
                {   // set a flag to create benevolence items
                    isBenevolenceAttribute = true;
                    attributeName          = attributeName.Replace("Benevolence", string.Empty).Trim();
                }
                else if (string.IsNullOrWhiteSpace(attributeName))
                {
                    attributeName = attributeGroupName;
                }

                Attribute primaryAttribute = null, campusAttribute = null;
                // don't create custom attributes for benevolence items
                if (!isBenevolenceAttribute)
                {
                    // create attributes if they don't exist
                    var attributeKey = attributeName.RemoveSpecialCharacters();
                    primaryAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals(attributeKey, StringComparison.CurrentCultureIgnoreCase));
                    if (primaryAttribute == null)
                    {
                        primaryAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, $"{attributeKey} imported {ImportDateTime}",
                                                              attributeGroupName, attributeName, attributeKey, attributeDate.HasValue ? DateFieldTypeId : TextFieldTypeId, importPersonAliasId: ImportPersonAliasId
                                                              );

                        personAttributes.Add(primaryAttribute);
                    }
                    // attribute already exists, add the new category
                    else if (!primaryAttribute.Categories.Any(c => c.Name.Equals(attributeGroupName)))
                    {
                        var attributeCategory = GetCategory(lookupContext, AttributeEntityTypeId, null, attributeGroupName, false, "EntityTypeId", PersonEntityTypeId.ToString());
                        primaryAttribute.Categories.Add(attributeCategory);
                    }

                    // only create a campus attribute if there was a campus prefix
                    campusAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals($"{attributeKey}Campus", StringComparison.CurrentCultureIgnoreCase));
                    if (campusAttribute == null && campusId.HasValue)
                    {
                        campusAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, $"{attributeKey}Campus imported {ImportDateTime}",
                                                             attributeGroupName, $"{attributeName} Campus", $"{attributeKey}Campus", CampusFieldTypeId
                                                             );

                        personAttributes.Add(campusAttribute);
                    }
                }

                // make sure we have a valid person to assign to
                var individualId   = row["Individual_Id"] as int?;
                var matchingPerson = GetPersonKeys(individualId, null, includeVisitors: false);
                if (matchingPerson != null)
                {
                    var person = !peopleToUpdate.ContainsKey(matchingPerson.PersonId)
                        ? personService.Queryable(includeDeceased: true).FirstOrDefault(p => p.Id == matchingPerson.PersonId)
                        : peopleToUpdate[matchingPerson.PersonId];

                    if (person != null)
                    {
                        int?creatorAliasId = null;
                        var noteCreator    = GetPersonKeys(attributeCreator);
                        if (noteCreator != null)
                        {
                            creatorAliasId = noteCreator.PersonAliasId;
                        }

                        if (!isBenevolenceAttribute)
                        {
                            // could have multiple attributes assigned to this person, don't overwrite previous
                            if (person.Attributes == null || person.AttributeValues == null)
                            {
                                person.Attributes      = new Dictionary <string, AttributeCache>();
                                person.AttributeValues = new Dictionary <string, AttributeValueCache>();
                            }

                            var attributeValue = attributeDate.HasValue ? attributeDate.Value.ToString("yyyy-MM-dd") : attributeComment;
                            if (string.IsNullOrWhiteSpace(attributeValue))
                            {
                                // add today's date so that the attribute at least gets a value
                                attributeValue = RockDateTime.Now.ToString("yyyy-MM-dd");
                            }

                            AddEntityAttributeValue(lookupContext, primaryAttribute, person, attributeValue);

                            if (personBaptizedHere)
                            {
                                AddEntityAttributeValue(lookupContext, baptizedHereAttribute, person, "Yes");
                            }

                            // Add the campus attribute value
                            if (campusAttribute != null && campusId.HasValue)
                            {
                                var campus = CampusList.FirstOrDefault(c => c.Id.Equals(campusId));
                                AddEntityAttributeValue(lookupContext, campusAttribute, person, campus.Guid.ToString());
                            }

                            // convert the attribute comment to a person note
                            if (!string.IsNullOrWhiteSpace(attributeComment))
                            {
                                // add the note to the person
                                AddEntityNote(lookupContext, PersonEntityTypeId, person.Id, attributeName, attributeComment, false, false,
                                              attributeGroupName, null, true, attributeDate, $"Imported {ImportDateTime}", creatorAliasId);
                            }
                        }
                        // benevolences require a date
                        else if (attributeDate.HasValue)
                        {
                            var requestText = !string.IsNullOrWhiteSpace(attributeComment) ? attributeComment : "N/A";
                            var benevolence = new BenevolenceRequest
                            {
                                CampusId                 = campusId,
                                RequestDateTime          = attributeDate.Value,
                                FirstName                = person.FirstName,
                                LastName                 = person.LastName,
                                Email                    = person.Email,
                                RequestedByPersonAliasId = person.PrimaryAliasId,
                                ConnectionStatusValueId  = person.ConnectionStatusValueId,
                                CaseWorkerPersonAliasId  = creatorAliasId,
                                RequestStatusValueId     = ParseBenevolenceStatus(attributeName),
                                RequestText              = requestText,
                                CreatedDateTime          = attributeDate.Value,
                                ModifiedDateTime         = attributeDate.Value,
                                CreatedByPersonAliasId   = creatorAliasId,
                                ModifiedByPersonAliasId  = ImportPersonAliasId,
                                ForeignKey               = $"Benevolence imported {ImportDateTime}"
                            };

                            newBenevolences.Add(benevolence);
                        }

                        // store the person lookup for this batch
                        if (!peopleToUpdate.ContainsKey(matchingPerson.PersonId))
                        {
                            peopleToUpdate.Add(matchingPerson.PersonId, person);
                        }
                        else
                        {
                            peopleToUpdate[matchingPerson.PersonId] = person;
                        }
                    }
                }

                completedItems++;
                if (completedItems % percentage < 1)
                {
                    var percentComplete = completedItems / percentage;
                    ReportProgress(percentComplete, $"{completedItems:N0} attributes imported ({percentComplete}% complete).");
                }

                if (completedItems % ReportingNumber < 1)
                {
                    SaveAttributes(peopleToUpdate);
                    SaveBenevolenceRequests(newBenevolences);

                    // reset so context doesn't bloat
                    lookupContext.Dispose();
                    lookupContext = new RockContext();
                    personService = new PersonService(lookupContext);
                    peopleToUpdate.Clear();
                    newBenevolences.Clear();
                    ReportPartialProgress();
                }
            }

            SaveAttributes(peopleToUpdate);
            SaveBenevolenceRequests(newBenevolences);

            ReportProgress(100, $"Finished attribute import: {completedItems:N0} attributes imported.");
        }