예제 #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));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <summary>
        /// Maps the contribution.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapContribution(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();

            var transactionTypeContributionId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid(), lookupContext).Id;

            var currencyTypes          = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE));
            var currencyTypeACH        = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH))).Id;
            var currencyTypeCash       = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH))).Id;
            var currencyTypeCheck      = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK))).Id;
            var currencyTypeCreditCard = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD))).Id;
            var currencyTypeNonCash    = currencyTypes.DefinedValues.Where(dv => dv.Value.Equals("Non-Cash")).Select(dv => ( int? )dv.Id).FirstOrDefault();

            if (currencyTypeNonCash == null)
            {
                var newTenderNonCash = new DefinedValue
                {
                    Value         = "Non-Cash",
                    Description   = "Non-Cash",
                    DefinedTypeId = currencyTypes.Id
                };

                lookupContext.DefinedValues.Add(newTenderNonCash);
                lookupContext.SaveChanges();

                currencyTypeNonCash = newTenderNonCash.Id;
            }

            var creditCardTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE)).DefinedValues;

            var refundReasons = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON), lookupContext).DefinedValues;

            var accountList = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();

            int?defaultBatchId = null;

            if (ImportedBatches.ContainsKey(0))
            {
                defaultBatchId = ImportedBatches[0];
            }

            // Get all imported contributions
            var importedContributions = new FinancialTransactionService(lookupContext).Queryable().AsNoTracking()
                                        .Where(c => c.ForeignId != null)
                                        .ToDictionary(t => ( int )t.ForeignId, t => ( int? )t.Id);

            // List for batching new contributions
            var newTransactions = new List <FinancialTransaction>();

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

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

            ReportProgress(0, $"Verifying contribution import ({totalRows:N0} found, {importedContributions.Count:N0} already exist).");
            foreach (var row in tableData.Where(r => r != null))
            {
                var individualId   = row["Individual_ID"] as int?;
                var householdId    = row["Household_ID"] as int?;
                var contributionId = row["ContributionID"] as int?;

                if (contributionId.HasValue && !importedContributions.ContainsKey(( int )contributionId))
                {
                    var transaction = new FinancialTransaction
                    {
                        CreatedByPersonAliasId  = ImportPersonAliasId,
                        ModifiedByPersonAliasId = ImportPersonAliasId,
                        TransactionTypeValueId  = transactionTypeContributionId,
                        ForeignKey = contributionId.ToString(),
                        ForeignId  = contributionId
                    };

                    int?giverAliasId = null;
                    var personKeys   = GetPersonKeys(individualId, householdId);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        giverAliasId = personKeys.PersonAliasId;
                        transaction.CreatedByPersonAliasId   = giverAliasId;
                        transaction.AuthorizedPersonAliasId  = giverAliasId;
                        transaction.ProcessedByPersonAliasId = giverAliasId;
                    }

                    var summary = row["Memo"] as string;
                    if (!string.IsNullOrWhiteSpace(summary))
                    {
                        transaction.Summary = summary;
                    }

                    var batchId = row["BatchID"] as int?;
                    if (batchId.HasValue && ImportedBatches.Any(b => b.Key.Equals(batchId)))
                    {
                        transaction.BatchId = ImportedBatches.FirstOrDefault(b => b.Key.Equals(batchId)).Value;
                    }
                    else
                    {
                        // use the default batch for any non-matching transactions
                        transaction.BatchId = defaultBatchId;
                    }

                    var receivedDate = row["Received_Date"] as DateTime?;
                    if (receivedDate.HasValue)
                    {
                        transaction.TransactionDateTime = receivedDate;
                        transaction.CreatedDateTime     = receivedDate;
                        transaction.ModifiedDateTime    = ImportDateTime;
                    }

                    var contributionFields = row.Columns.Select(c => c.Name).ToList();
                    var cardType           = contributionFields.Contains("Card_Type") ? row["Card_Type"] as string : string.Empty;
                    var cardLastFour       = contributionFields.Contains("Last_Four") ? row["Last_Four"] as string : string.Empty;
                    var contributionType   = contributionFields.Contains("Contribution_Type_Name") ? row["Contribution_Type_Name"] as string : string.Empty;

                    if (!string.IsNullOrWhiteSpace(contributionType))
                    {
                        // set default source to onsite, exceptions listed below
                        transaction.SourceTypeValueId = TransactionSourceTypeOnsiteId;

                        int?paymentCurrencyTypeId = null, creditCardTypeId = null;
                        switch (contributionType.ToLower())
                        {
                        case "cash":
                            paymentCurrencyTypeId = currencyTypeCash;
                            break;

                        case "check":
                            paymentCurrencyTypeId = currencyTypeCheck;
                            break;

                        case "ach":
                            paymentCurrencyTypeId         = currencyTypeACH;
                            transaction.SourceTypeValueId = TransactionSourceTypeWebsiteId;
                            break;

                        case "credit card":
                            paymentCurrencyTypeId         = currencyTypeCreditCard;
                            transaction.SourceTypeValueId = TransactionSourceTypeWebsiteId;

                            if (!string.IsNullOrWhiteSpace(cardType))
                            {
                                creditCardTypeId = creditCardTypes.Where(t => t.Value.Equals(cardType, StringComparison.OrdinalIgnoreCase))
                                                   .Select(t => ( int? )t.Id).FirstOrDefault();
                            }
                            break;

                        default:
                            paymentCurrencyTypeId = currencyTypeNonCash;
                            break;
                        }

                        var paymentDetail = new FinancialPaymentDetail
                        {
                            CreatedDateTime         = receivedDate,
                            CreatedByPersonAliasId  = giverAliasId,
                            ModifiedDateTime        = ImportDateTime,
                            ModifiedByPersonAliasId = giverAliasId,
                            CurrencyTypeValueId     = paymentCurrencyTypeId,
                            CreditCardTypeValueId   = creditCardTypeId,
                            AccountNumberMasked     = cardLastFour,
                            ForeignKey = contributionId.ToString(),
                            ForeignId  = contributionId
                        };

                        transaction.FinancialPaymentDetail = paymentDetail;
                    }

                    var checkNumber = row["Check_Number"] as string;
                    // if the check number is valid, put it in the transaction code
                    if (checkNumber.AsType <int?>().HasValue)
                    {
                        transaction.TransactionCode = checkNumber;
                    }
                    // check for SecureGive kiosk transactions
                    else if (!string.IsNullOrWhiteSpace(checkNumber) && checkNumber.StartsWith("SG"))
                    {
                        transaction.SourceTypeValueId = TransactionSourceTypeKioskId;
                    }

                    var fundName         = contributionFields.Contains("Fund_Name") ? row["Fund_Name"] as string : string.Empty;
                    var fundType         = contributionFields.Contains("Fund_type") ? row["Fund_type"] as string : string.Empty;
                    var subFund          = contributionFields.Contains("Sub_Fund_Name") ? row["Sub_Fund_Name"] as string : string.Empty;
                    var fundGLAccount    = contributionFields.Contains("Fund_GL_Account") ? row["Fund_GL_Account"] as string : string.Empty;
                    var subFundGLAccount = contributionFields.Contains("Sub_Fund_GL_Account") ? row["Sub_Fund_GL_Account"] as string : string.Empty;
                    var isFundActive     = contributionFields.Contains("Fund_Is_active") ? row["Fund_Is_active"] as string : null;
                    var statedValue      = row["Stated_Value"] as decimal?;
                    var amount           = row["Amount"] as decimal?;
                    if (!string.IsNullOrWhiteSpace(fundName) && amount.HasValue)
                    {
                        int transactionAccountId;
                        var parentAccount = accountList.FirstOrDefault(a => !a.CampusId.HasValue && a.Name.Equals(fundName.Truncate(50), StringComparison.OrdinalIgnoreCase));
                        if (parentAccount == null)
                        {
                            int?accountTypeDefinedTypeId = null;
                            if (!string.IsNullOrWhiteSpace(fundType))
                            {
                                accountTypeDefinedTypeId = LoadAccountTypeDefinedValue(lookupContext, fundType);
                            }
                            parentAccount = AddFinancialAccount(lookupContext, fundName, $"{fundName} imported {ImportDateTime}", fundGLAccount, null, null, isFundActive.AsBooleanOrNull(), receivedDate, fundName.RemoveSpecialCharacters(), accountTypeValueId: accountTypeDefinedTypeId);
                            accountList.Add(parentAccount);
                        }

                        if (!string.IsNullOrWhiteSpace(subFund))
                        {
                            int?campusFundId = null;
                            // assign a campus if the subfund is a campus fund
                            var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name, StringComparison.OrdinalIgnoreCase) || subFund.StartsWith(c.ShortCode, StringComparison.OrdinalIgnoreCase));
                            if (campusFund != null)
                            {
                                // use full campus name as the subfund
                                subFund      = campusFund.Name;
                                campusFundId = campusFund.Id;
                            }

                            // add info to easily find/assign this fund in the view
                            subFund = $"{subFund} {fundName}";

                            var childAccount = accountList.FirstOrDefault(c => c.ParentAccountId == parentAccount.Id && c.Name.Equals(subFund.Truncate(50), StringComparison.OrdinalIgnoreCase));
                            if (childAccount == null)
                            {
                                // create a child account with a campusId if it was set
                                childAccount = AddFinancialAccount(lookupContext, subFund, $"{subFund} imported {ImportDateTime}", subFundGLAccount, campusFundId, parentAccount.Id, isFundActive.AsBooleanOrNull(), receivedDate, subFund.RemoveSpecialCharacters(), accountTypeValueId: parentAccount.AccountTypeValueId);
                                accountList.Add(childAccount);
                            }

                            transactionAccountId = childAccount.Id;
                        }
                        else
                        {
                            transactionAccountId = parentAccount.Id;
                        }

                        if (amount == 0 && statedValue.HasValue && statedValue != 0)
                        {
                            amount = statedValue;
                        }

                        var transactionDetail = new FinancialTransactionDetail
                        {
                            Amount          = ( decimal )amount,
                            CreatedDateTime = receivedDate,
                            AccountId       = transactionAccountId
                        };

                        transaction.TransactionDetails.Add(transactionDetail);

                        if (amount < 0)
                        {
                            transaction.RefundDetails = new FinancialTransactionRefund();
                            transaction.RefundDetails.CreatedDateTime     = receivedDate;
                            transaction.RefundDetails.RefundReasonValueId = refundReasons.Where(dv => summary != null && dv.Value.Contains(summary))
                                                                            .Select(dv => ( int? )dv.Id).FirstOrDefault();
                            transaction.RefundDetails.RefundReasonSummary = summary;
                        }
                    }

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

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveContributions(newTransactions);
                        newTransactions.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newTransactions.Any())
            {
                SaveContributions(newTransactions);
            }

            ReportProgress(100, $"Finished contribution import: {completedItems:N0} contributions imported.");
        }
예제 #6
0
        /// <summary>
        /// Maps the contribution.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="selectedColumns">The selected columns.</param>
        private void MapContribution(IQueryable <Row> tableData, List <string> selectedColumns = null)
        {
            var lookupContext                 = new RockContext();
            int transactionEntityTypeId       = EntityTypeCache.Read("Rock.Model.FinancialTransaction").Id;
            var transactionTypeContributionId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION), lookupContext).Id;

            var currencyTypes          = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE));
            int currencyTypeACH        = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH))).Id;
            int currencyTypeCash       = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH))).Id;
            int currencyTypeCheck      = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK))).Id;
            int currencyTypeCreditCard = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD))).Id;
            int?currencyTypeNonCash    = currencyTypes.DefinedValues.Where(dv => dv.Value.Equals("Non-Cash")).Select(dv => (int?)dv.Id).FirstOrDefault();

            if (currencyTypeNonCash == null)
            {
                var newTenderNonCash = new DefinedValue();
                newTenderNonCash.Value         = "Non-Cash";
                newTenderNonCash.Description   = "Non-Cash";
                newTenderNonCash.DefinedTypeId = currencyTypes.Id;
                lookupContext.DefinedValues.Add(newTenderNonCash);
                lookupContext.SaveChanges();

                currencyTypeNonCash = newTenderNonCash.Id;
            }

            var creditCardTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE)).DefinedValues;

            int sourceTypeOnsite  = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_ONSITE_COLLECTION), lookupContext).Id;
            int sourceTypeWebsite = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE), lookupContext).Id;
            int sourceTypeKiosk   = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_KIOSK), lookupContext).Id;

            var refundReasons = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON), lookupContext).DefinedValues;

            var accountList = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();

            int?defaultBatchId = null;

            if (ImportedBatches.ContainsKey(0))
            {
                defaultBatchId = ImportedBatches[0];
            }

            // Get all imported contributions
            var importedContributions = new FinancialTransactionService(lookupContext).Queryable().AsNoTracking()
                                        .Where(c => c.ForeignId != null)
                                        .ToDictionary(t => (int)t.ForeignId, t => (int?)t.Id);

            // List for batching new contributions
            var newTransactions = new List <FinancialTransaction>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying contribution import ({0:N0} found, {1:N0} already exist).", totalRows, importedContributions.Count));
            foreach (var row in tableData.Where(r => r != null))
            {
                int?individualId   = row["Individual_ID"] as int?;
                int?householdId    = row["Household_ID"] as int?;
                int?contributionId = row["ContributionID"] as int?;

                if (contributionId != null && !importedContributions.ContainsKey((int)contributionId))
                {
                    var transaction = new FinancialTransaction();
                    transaction.CreatedByPersonAliasId  = ImportPersonAliasId;
                    transaction.ModifiedByPersonAliasId = ImportPersonAliasId;
                    transaction.TransactionTypeValueId  = transactionTypeContributionId;
                    transaction.ForeignKey = contributionId.ToString();
                    transaction.ForeignId  = contributionId;

                    int?giverAliasId = null;
                    var personKeys   = GetPersonKeys(individualId, householdId);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        giverAliasId = personKeys.PersonAliasId;
                        transaction.CreatedByPersonAliasId   = giverAliasId;
                        transaction.AuthorizedPersonAliasId  = giverAliasId;
                        transaction.ProcessedByPersonAliasId = giverAliasId;
                    }

                    string summary = row["Memo"] as string;
                    if (summary != null)
                    {
                        transaction.Summary = summary;
                    }

                    int?batchId = row["BatchID"] as int?;
                    if (batchId != null && ImportedBatches.Any(b => b.Key.Equals(batchId)))
                    {
                        transaction.BatchId = ImportedBatches.FirstOrDefault(b => b.Key.Equals(batchId)).Value;
                    }
                    else
                    {
                        // use the default batch for any non-matching transactions
                        transaction.BatchId = defaultBatchId;
                    }

                    DateTime?receivedDate = row["Received_Date"] as DateTime?;
                    if (receivedDate != null)
                    {
                        transaction.TransactionDateTime = receivedDate;
                        transaction.CreatedDateTime     = receivedDate;
                        transaction.ModifiedDateTime    = ImportDateTime;
                    }

                    string cardType         = row["Card_Type"] as string;
                    string cardLastFour     = row["Last_Four"] as string;
                    string contributionType = row["Contribution_Type_Name"].ToStringSafe().ToLower();
                    if (contributionType != null)
                    {
                        // set default source to onsite, exceptions listed below
                        transaction.SourceTypeValueId = sourceTypeOnsite;

                        int?paymentCurrencyTypeId = null, creditCardTypeId = null;

                        if (contributionType == "cash")
                        {
                            paymentCurrencyTypeId = currencyTypeCash;
                        }
                        else if (contributionType == "check")
                        {
                            paymentCurrencyTypeId = currencyTypeCheck;
                        }
                        else if (contributionType == "ach")
                        {
                            paymentCurrencyTypeId         = currencyTypeACH;
                            transaction.SourceTypeValueId = sourceTypeWebsite;
                        }
                        else if (contributionType == "credit card")
                        {
                            paymentCurrencyTypeId         = currencyTypeCreditCard;
                            transaction.SourceTypeValueId = sourceTypeWebsite;

                            if (cardType != null)
                            {
                                creditCardTypeId = creditCardTypes.Where(t => t.Value.Equals(cardType)).Select(t => (int?)t.Id).FirstOrDefault();
                            }
                        }
                        else
                        {
                            paymentCurrencyTypeId = currencyTypeNonCash;
                        }

                        var paymentDetail = new FinancialPaymentDetail();
                        paymentDetail.CreatedDateTime         = receivedDate;
                        paymentDetail.CreatedByPersonAliasId  = giverAliasId;
                        paymentDetail.ModifiedDateTime        = ImportDateTime;
                        paymentDetail.ModifiedByPersonAliasId = giverAliasId;
                        paymentDetail.CurrencyTypeValueId     = paymentCurrencyTypeId;
                        paymentDetail.CreditCardTypeValueId   = creditCardTypeId;
                        paymentDetail.AccountNumberMasked     = cardLastFour;
                        paymentDetail.ForeignKey = contributionId.ToString();
                        paymentDetail.ForeignId  = contributionId;

                        transaction.FinancialPaymentDetail = paymentDetail;
                    }

                    string checkNumber = row["Check_Number"] as string;
                    // if the check number is valid, put it in the transaction code
                    if (checkNumber.AsType <int?>() != null)
                    {
                        transaction.TransactionCode = checkNumber;
                    }
                    // check for SecureGive kiosk transactions
                    else if (!string.IsNullOrEmpty(checkNumber) && checkNumber.StartsWith("SG"))
                    {
                        transaction.SourceTypeValueId = sourceTypeKiosk;
                    }

                    string  fundName         = row["Fund_Name"] as string;
                    string  subFund          = row["Sub_Fund_Name"] as string;
                    string  fundGLAccount    = row["Fund_GL_Account"] as string;
                    string  subFundGLAccount = row["Sub_Fund_GL_Account"] as string;
                    Boolean?isFundActive     = row["Fund_Is_active"] as Boolean?;
                    decimal?statedValue      = row["Stated_Value"] as decimal?;
                    decimal?amount           = row["Amount"] as decimal?;
                    if (fundName != null & amount != null)
                    {
                        int transactionAccountId;
                        var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) && a.CampusId == null);
                        if (parentAccount == null)
                        {
                            parentAccount = AddAccount(lookupContext, fundName, fundGLAccount, null, null, isFundActive);
                            accountList.Add(parentAccount);
                        }

                        if (subFund != null)
                        {
                            int?campusFundId = null;
                            // assign a campus if the subfund is a campus fund
                            var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode));
                            if (campusFund != null)
                            {
                                // use full campus name as the subfund
                                subFund      = campusFund.Name;
                                campusFundId = campusFund.Id;
                            }

                            // add info to easily find/assign this fund in the view
                            subFund = string.Format("{0} {1}", subFund, fundName);

                            var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund) && c.ParentAccountId == parentAccount.Id);
                            if (childAccount == null)
                            {
                                // create a child account with a campusId if it was set
                                childAccount = AddAccount(lookupContext, subFund, subFundGLAccount, campusFundId, parentAccount.Id, isFundActive);
                                accountList.Add(childAccount);
                            }

                            transactionAccountId = childAccount.Id;
                        }
                        else
                        {
                            transactionAccountId = parentAccount.Id;
                        }

                        if (amount == 0 && statedValue != null && statedValue != 0)
                        {
                            amount = statedValue;
                        }

                        var transactionDetail = new FinancialTransactionDetail();
                        transactionDetail.Amount          = (decimal)amount;
                        transactionDetail.CreatedDateTime = receivedDate;
                        transactionDetail.AccountId       = transactionAccountId;
                        transaction.TransactionDetails.Add(transactionDetail);

                        if (amount < 0)
                        {
                            transaction.RefundDetails = new FinancialTransactionRefund();
                            transaction.RefundDetails.CreatedDateTime     = receivedDate;
                            transaction.RefundDetails.RefundReasonValueId = refundReasons.Where(dv => summary != null && dv.Value.Contains(summary))
                                                                            .Select(dv => (int?)dv.Id).FirstOrDefault();
                            transaction.RefundDetails.RefundReasonSummary = summary;
                        }
                    }

                    newTransactions.Add(transaction);
                    completed++;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} contributions imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveContributions(newTransactions);
                        newTransactions.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newTransactions.Any())
            {
                SaveContributions(newTransactions);
            }

            ReportProgress(100, string.Format("Finished contribution import: {0:N0} contributions imported.", completed));
        }
예제 #7
0
파일: Group.cs 프로젝트: treusch/Bulldozer
        /// <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);
        }
예제 #8
0
        /// <summary>
        /// Maps the pledge.
        /// </summary>
        /// <param name="queryable">The queryable.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapPledge(IQueryable <Row> tableData)
        {
            var lookupContext = new RockContext();
            List <FinancialAccount> accountList     = new FinancialAccountService(lookupContext).Queryable().ToList();
            List <FinancialPledge>  importedPledges = new FinancialPledgeService(lookupContext).Queryable().ToList();

            var pledgeFrequencies = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY), lookupContext).DefinedValues;

            var newPledges = new List <FinancialPledge>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying pledge import ({0:N0} found).", totalRows));

            foreach (var row in tableData)
            {
                decimal? amount    = row["Total_Pledge"] as decimal?;
                DateTime?startDate = row["Start_Date"] as DateTime?;
                DateTime?endDate   = row["End_Date"] as DateTime?;
                if (amount != null && startDate != null && endDate != null)
                {
                    int?individualId = row["Individual_ID"] as int?;
                    int?householdId  = row["Household_ID"] as int?;
                    int?personId     = GetPersonAliasId(individualId, householdId);
                    if (personId != null && !importedPledges.Any(p => p.PersonAliasId == personId && p.TotalAmount == amount && p.StartDate.Equals(startDate)))
                    {
                        var pledge = new FinancialPledge();
                        pledge.CreatedByPersonAliasId = ImportPersonAlias.Id;
                        pledge.StartDate   = (DateTime)startDate;
                        pledge.EndDate     = (DateTime)endDate;
                        pledge.TotalAmount = (decimal)amount;

                        string frequency = row["Pledge_Frequency_Name"].ToString().ToLower();
                        if (frequency != null)
                        {
                            if (frequency == "one time" || frequency == "as can")
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies.FirstOrDefault(f => f.Guid == new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME)).Id;
                            }
                            else
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies
                                                                .Where(f => f.Value.ToLower().StartsWith(frequency) || f.Description.ToLower().StartsWith(frequency))
                                                                .Select(f => f.Id).FirstOrDefault();
                            }
                        }

                        string fundName = row["Fund_Name"] as string;
                        string subFund  = row["Sub_Fund_Name"] as string;
                        if (fundName != null)
                        {
                            FinancialAccount matchingAccount = null;
                            int?fundCampusId = null;
                            if (subFund != null)
                            {
                                // match by campus if the subfund appears to be a campus
                                fundCampusId = CampusList.Where(c => c.Name.StartsWith(subFund) || c.ShortCode == subFund)
                                               .Select(c => (int?)c.Id).FirstOrDefault();

                                if (fundCampusId != null)
                                {
                                    matchingAccount = accountList.FirstOrDefault(a => a.Name.StartsWith(fundName) && a.CampusId != null && a.CampusId.Equals(fundCampusId));
                                }
                                else
                                {
                                    matchingAccount = accountList.FirstOrDefault(a => a.Name.StartsWith(fundName) && a.Name.StartsWith(subFund));
                                }
                            }
                            else
                            {
                                matchingAccount = accountList.FirstOrDefault(a => a.Name.StartsWith(fundName));
                            }

                            if (matchingAccount == null)
                            {
                                matchingAccount = AddAccount(lookupContext, fundName, fundCampusId);
                                accountList.Add(matchingAccount);
                            }

                            pledge.AccountId = matchingAccount.Id;
                        }

                        // Attributes to add?
                        // Pledge_Drive_Name

                        newPledges.Add(pledge);
                        completed++;
                        if (completed % percentage < 1)
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress(percentComplete, string.Format("{0:N0} pledges imported ({1}% complete).", completed, percentComplete));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SavePledges(newPledges);
                            ReportPartialProgress();
                        }
                    }
                }
            }

            if (newPledges.Any())
            {
                SavePledges(newPledges);
            }

            ReportProgress(100, string.Format("Finished pledge import: {0:N0} pledges imported.", completed));
        }
예제 #9
0
        /// <summary>
        /// Maps the activity ministry.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <returns></returns>
        private void MapActivityMinistry(IQueryable <Row> tableData)
        {
            var lookupContext = new RockContext();

            // Add an Attribute for the unique F1 Ministry Id
            int groupEntityTypeId   = EntityTypeCache.Read("Rock.Model.Group").Id;
            var ministryAttributeId = new AttributeService(lookupContext).Queryable().Where(a => a.EntityTypeId == groupEntityTypeId &&
                                                                                            a.Key == "F1MinistryId").Select(a => a.Id).FirstOrDefault();

            if (ministryAttributeId == 0)
            {
                var newMinistryAttribute = new Rock.Model.Attribute();
                newMinistryAttribute.Key                       = "F1MinistryId";
                newMinistryAttribute.Name                      = "F1 Ministry Id";
                newMinistryAttribute.FieldTypeId               = IntegerFieldTypeId;
                newMinistryAttribute.EntityTypeId              = groupEntityTypeId;
                newMinistryAttribute.EntityTypeQualifierValue  = string.Empty;
                newMinistryAttribute.EntityTypeQualifierColumn = string.Empty;
                newMinistryAttribute.Description               = "The FellowshipOne identifier for the ministry that was imported";
                newMinistryAttribute.DefaultValue              = string.Empty;
                newMinistryAttribute.IsMultiValue              = false;
                newMinistryAttribute.IsRequired                = false;
                newMinistryAttribute.Order                     = 0;

                lookupContext.Attributes.Add(newMinistryAttribute);
                lookupContext.SaveChanges(DisableAudit);
                ministryAttributeId = newMinistryAttribute.Id;
            }

            // Get previously imported Ministries
            var importedMinistries = new AttributeValueService(lookupContext).GetByAttributeId(ministryAttributeId)
                                     .ToDictionary(t => t.Value.AsType <int?>(), t => t.EntityId);

            var newGroups = new List <Group>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying ministry import ({0:N0} found).", totalRows));

            foreach (var row in tableData)
            {
                int?ministryId = row["Ministry_ID"] as int?;
                if (ministryId != null && !importedMinistries.ContainsKey(ministryId))
                {
                    string ministryName     = row["Ministry_Name"] as string;
                    bool?  ministryIsActive = row["Ministry_Active"] as bool?;

                    int?   activityId       = row["Activity_ID"] as int?;
                    string activityName     = row["Activity_Name"] as string;
                    bool?  activityIsActive = row["Activity_Active"] as bool?;

                    if (ministryName != null)
                    {
                        var ministry = new Group();
                        ministry.Name     = ministryName.Trim();
                        ministry.IsActive = ministryIsActive ?? false;
                        ministry.CampusId = CampusList.Where(c => ministryName.StartsWith(c.Name) || ministryName.StartsWith(c.ShortCode))
                                            .Select(c => (int?)c.Id).FirstOrDefault();

                        // create new group for activity with ministry as parent group

                        newGroups.Add(ministry);
                        completed++;

                        if (completed % percentage < 1)
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress(percentComplete, string.Format("{0:N0} ministries imported ({1}% complete).", completed, percentComplete));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SaveActivityMinistry(newGroups);
                            ReportPartialProgress();
                            newGroups.Clear();
                        }
                    }
                }
            }

            if (newGroups.Any())
            {
                SaveActivityMinistry(newGroups);
            }

            ReportProgress(100, string.Format("Finished ministry import: {0:N0} ministries imported.", completed));
        }
예제 #10
0
        /// <summary>
        /// Maps the person.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="selectedColumns">The selected columns.</param>
        private void MapPerson(IQueryable <Row> tableData, List <string> selectedColumns = null)
        {
            var lookupContext        = new RockContext();
            var groupTypeRoleService = new GroupTypeRoleService(lookupContext);

            // Marital statuses: Married, Single, Separated, etc
            var maritalStatusTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_MARITAL_STATUS), lookupContext).DefinedValues;

            // Connection statuses: Member, Visitor, Attendee, etc
            var connectionStatusTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_CONNECTION_STATUS), lookupContext).DefinedValues;

            // Record status reasons: No Activity, Moved, Deceased, etc
            var recordStatusReasons = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_RECORD_STATUS_REASON), lookupContext).DefinedValues;

            // Record statuses: Active, Inactive, Pending
            int?recordStatusActiveId   = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE), lookupContext).Id;
            int?recordStatusInactiveId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE), lookupContext).Id;
            int?recordStatusPendingId  = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_PENDING), lookupContext).Id;

            // Record type: Person
            int?personRecordTypeId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON), lookupContext).Id;

            // Suffix type: Dr., Jr., II, etc
            var suffixTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_SUFFIX)).DefinedValues;

            // Title type: Mr., Mrs. Dr., etc
            var titleTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_TITLE), lookupContext).DefinedValues;

            // Note type: Comment
            int noteCommentTypeId = new NoteTypeService(lookupContext).Get(new Guid("7E53487C-D650-4D85-97E2-350EB8332763")).Id;

            // Group roles: Owner, Adult, Child, others
            GroupTypeRole ownerRole            = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER));
            int           adultRoleId          = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)).Id;
            int           childRoleId          = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD)).Id;
            int           inviteeRoleId        = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_INVITED)).Id;
            int           invitedByRoleId      = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_INVITED_BY)).Id;
            int           canCheckInRoleId     = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_CAN_CHECK_IN)).Id;
            int           allowCheckInByRoleId = groupTypeRoleService.Get(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_ALLOW_CHECK_IN_BY)).Id;

            // Group type: Family
            int familyGroupTypeId = new GroupTypeService(lookupContext).Get(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY)).Id;

            // Look up additional Person attributes (existing)
            var personAttributes = new AttributeService(lookupContext).GetByEntityTypeId(PersonEntityTypeId).ToList();

            // Cached F1 attributes: IndividualId, HouseholdId
            // Core attributes: PreviousChurch, Position, Employer, School
            var individualIdAttribute   = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "F1IndividualId"));
            var householdIdAttribute    = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "F1HouseholdId"));
            var previousChurchAttribute = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "PreviousChurch"));
            var employerAttribute       = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "Employer"));
            var positionAttribute       = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "Position"));
            var firstVisitAttribute     = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "FirstVisit"));
            var schoolAttribute         = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "School"));
            var membershipDateAttribute = AttributeCache.Read(personAttributes.FirstOrDefault(a => a.Key == "MembershipDate"));

            var familyList  = new List <Group>();
            var visitorList = new List <Group>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

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

            foreach (var groupedRows in tableData.GroupBy <Row, int?>(r => r["Household_ID"] as int?))
            {
                var familyGroup         = new Group();
                var householdCampusList = new List <string>();

                foreach (var row in groupedRows)
                {
                    bool   isFamilyRelationship = true;
                    string currentCampus        = string.Empty;
                    int?   individualId         = row["Individual_ID"] as int?;
                    int?   householdId          = row["Household_ID"] as int?;
                    if (GetPersonAliasId(individualId, householdId) == null)
                    {
                        var person = new Person();
                        person.FirstName              = row["First_Name"] as string;
                        person.MiddleName             = row["Middle_Name"] as string;
                        person.NickName               = row["Goes_By"] as string ?? person.FirstName;
                        person.LastName               = row["Last_Name"] as string;
                        person.BirthDate              = row["Date_Of_Birth"] as DateTime?;
                        person.CreatedByPersonAliasId = ImportPersonAlias.Id;
                        person.RecordTypeValueId      = personRecordTypeId;
                        person.ForeignId              = individualId.ToString();
                        int groupRoleId = adultRoleId;

                        var gender = row["Gender"] as string;
                        if (gender != null)
                        {
                            person.Gender = (Gender)Enum.Parse(typeof(Gender), gender);
                        }

                        string prefix = row["Prefix"] as string;
                        if (prefix != null)
                        {
                            prefix = prefix.RemoveSpecialCharacters().Trim();
                            person.TitleValueId = titleTypes.Where(s => prefix == s.Value.RemoveSpecialCharacters())
                                                  .Select(s => (int?)s.Id).FirstOrDefault();
                        }

                        string suffix = row["Suffix"] as string;
                        if (suffix != null)
                        {
                            suffix = suffix.RemoveSpecialCharacters().Trim();
                            person.SuffixValueId = suffixTypes.Where(s => suffix == s.Value.RemoveSpecialCharacters())
                                                   .Select(s => (int?)s.Id).FirstOrDefault();
                        }

                        string maritalStatus = row["Marital_Status"] as string;
                        if (maritalStatus != null)
                        {
                            person.MaritalStatusValueId = maritalStatusTypes.Where(dv => dv.Value == maritalStatus)
                                                          .Select(dv => (int?)dv.Id).FirstOrDefault();
                        }
                        else
                        {
                            person.MaritalStatusValueId = maritalStatusTypes.Where(dv => dv.Value == "Unknown")
                                                          .Select(dv => (int?)dv.Id).FirstOrDefault();
                        }

                        string familyRole = row["Household_Position"].ToString().ToLower();
                        if (familyRole != null)
                        {
                            if (familyRole == "visitor")
                            {
                                isFamilyRelationship = false;
                            }

                            if (familyRole == "child" || person.Age < 18)
                            {
                                groupRoleId = childRoleId;
                            }
                        }

                        string memberStatus = row["Status_Name"].ToString().ToLower();
                        if (memberStatus == "member")
                        {
                            person.ConnectionStatusValueId = connectionStatusTypes.FirstOrDefault(dv => dv.Guid == new Guid(Rock.SystemGuid.DefinedValue.PERSON_CONNECTION_STATUS_MEMBER)).Id;
                            person.RecordStatusValueId     = recordStatusActiveId;
                        }
                        else if (memberStatus == "visitor")
                        {
                            person.ConnectionStatusValueId = connectionStatusTypes.FirstOrDefault(dv => dv.Guid == new Guid(Rock.SystemGuid.DefinedValue.PERSON_CONNECTION_STATUS_VISITOR)).Id;
                            person.RecordStatusValueId     = recordStatusActiveId;
                        }
                        else if (memberStatus == "deceased")
                        {
                            person.IsDeceased = true;
                            person.RecordStatusReasonValueId = recordStatusReasons.Where(dv => dv.Value == "Deceased")
                                                               .Select(dv => dv.Id).FirstOrDefault();
                            person.RecordStatusValueId = recordStatusInactiveId;
                        }
                        else
                        {
                            // F1 defaults are Member & Visitor; all others are user-defined
                            var customConnectionType = connectionStatusTypes.Where(dv => dv.Value == memberStatus)
                                                       .Select(dv => (int?)dv.Id).FirstOrDefault();

                            int attendeeId = connectionStatusTypes.FirstOrDefault(dv => dv.Guid == new Guid(Rock.SystemGuid.DefinedValue.PERSON_CONNECTION_STATUS_ATTENDEE)).Id;
                            person.ConnectionStatusValueId = customConnectionType ?? attendeeId;
                            person.RecordStatusValueId     = recordStatusActiveId;
                        }

                        string campus = row["SubStatus_Name"] as string;
                        if (campus != null)
                        {
                            currentCampus = campus;
                        }

                        string status_comment = row["Status_Comment"] as string;
                        if (status_comment != null)
                        {
                            person.SystemNote = status_comment;
                        }

                        // Map F1 attributes
                        person.Attributes      = new Dictionary <string, AttributeCache>();
                        person.AttributeValues = new Dictionary <string, AttributeValue>();

                        // individual_id already defined in scope
                        AddPersonAttribute(individualIdAttribute, person, individualId.ToString());

                        // household_id already defined in scope
                        AddPersonAttribute(householdIdAttribute, person, householdId.ToString());

                        string previousChurch = row["Former_Church"] as string;
                        AddPersonAttribute(previousChurchAttribute, person, previousChurch);

                        string employer = row["Employer"] as string;
                        AddPersonAttribute(employerAttribute, person, employer);

                        string position = row["Occupation_Name"] as string ?? row["Occupation_Description"] as string;
                        AddPersonAttribute(positionAttribute, person, position);

                        string school = row["School_Name"] as string;
                        AddPersonAttribute(schoolAttribute, person, school);

                        DateTime?membershipDate = row["Status_Date"] as DateTime?;
                        if (membershipDate != null)
                        {
                            person.CreatedDateTime = membershipDate;
                            AddPersonAttribute(membershipDateAttribute, person, membershipDate.Value.ToString("MM/dd/yyyy"));
                        }

                        DateTime?firstVisit = row["First_Record"] as DateTime?;
                        if (firstVisit != null)
                        {
                            person.CreatedDateTime = firstVisit;
                            AddPersonAttribute(firstVisitAttribute, person, firstVisit.Value.ToString("MM/dd/yyyy"));
                        }

                        // Other Attributes to create:
                        // former name
                        // bar_code
                        // member_env_code
                        // denomination_name

                        var groupMember = new GroupMember();
                        groupMember.Person            = person;
                        groupMember.GroupRoleId       = groupRoleId;
                        groupMember.GroupMemberStatus = GroupMemberStatus.Active;

                        if (isFamilyRelationship)
                        {
                            householdCampusList.Add(currentCampus);
                            familyGroup.Members.Add(groupMember);
                            familyGroup.ForeignId = householdId.ToString();
                        }
                        else
                        {
                            var visitorGroup = new Group();
                            visitorGroup.ForeignId = householdId.ToString();
                            visitorGroup.Members.Add(groupMember);
                            visitorGroup.GroupTypeId = familyGroupTypeId;
                            visitorGroup.Name        = person.LastName + " Family";
                            visitorGroup.CampusId    = CampusList.Where(c => c.Name.StartsWith(currentCampus) || c.ShortCode == currentCampus)
                                                       .Select(c => (int?)c.Id).FirstOrDefault();
                            familyList.Add(visitorGroup);
                            completed += visitorGroup.Members.Count;

                            visitorList.Add(visitorGroup);
                        }
                    }
                }

                if (familyGroup.Members.Any())
                {
                    familyGroup.Name = familyGroup.Members.OrderByDescending(p => p.Person.Age)
                                       .FirstOrDefault().Person.LastName + " Family";
                    familyGroup.GroupTypeId = familyGroupTypeId;

                    string primaryHouseholdCampus = householdCampusList.GroupBy(c => c).OrderByDescending(c => c.Count())
                                                    .Select(c => c.Key).FirstOrDefault();
                    if (primaryHouseholdCampus != null)
                    {
                        familyGroup.CampusId = CampusList.Where(c => c.Name.StartsWith(primaryHouseholdCampus) || c.ShortCode == primaryHouseholdCampus)
                                               .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    familyList.Add(familyGroup);
                    completed += familyGroup.Members.Count;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} people imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SavePeople(familyList, visitorList, ownerRole, childRoleId, inviteeRoleId, invitedByRoleId, canCheckInRoleId, allowCheckInByRoleId);

                        familyList.Clear();
                        visitorList.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // Save any remaining families in the batch
            if (familyList.Any())
            {
                SavePeople(familyList, visitorList, ownerRole, childRoleId, inviteeRoleId, invitedByRoleId, canCheckInRoleId, allowCheckInByRoleId);
            }

            ReportProgress(100, string.Format("Finished person import: {0:N0} people imported.", completed));
        }
예제 #11
0
        /// <summary>
        /// Maps the contribution.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="selectedColumns">The selected columns.</param>
        private void MapContribution(IQueryable <Row> tableData, List <string> selectedColumns = null)
        {
            var lookupContext                      = new RockContext();
            int transactionEntityTypeId            = EntityTypeCache.Read("Rock.Model.FinancialTransaction").Id;
            var transactionTypeContributionId      = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION), lookupContext).Id;
            var transactionTypeEventRegistrationId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_EVENT_REGISTRATION), lookupContext).Id;

            int currencyTypeACH        = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH), lookupContext).Id;
            int currencyTypeCash       = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH), lookupContext).Id;
            int currencyTypeCheck      = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK), lookupContext).Id;
            int currencyTypeCreditCard = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD), lookupContext).Id;

            var refundReasons = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON), lookupContext).DefinedValues;

            List <FinancialPledge>  pledgeList  = new FinancialPledgeService(lookupContext).Queryable().ToList();
            List <FinancialAccount> accountList = new FinancialAccountService(lookupContext).Queryable().ToList();

            // Get all imported contributions
            var importedContributions = new FinancialTransactionService(lookupContext).Queryable()
                                        .Select(t => new { ContributionId = t.ForeignId, TransactionId = t.Id })
                                        .ToDictionary(t => t.ContributionId.AsType <int?>(), t => (int?)t.TransactionId);

            var householdAVList = new AttributeValueService(lookupContext).Queryable().Where(av => av.AttributeId == HouseholdAttributeId).ToList();

            // List for batching new contributions
            var newTransactions = new List <FinancialTransaction>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

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

            foreach (var row in tableData)
            {
                int?individualId   = row["Individual_ID"] as int?;
                int?householdId    = row["Household_ID"] as int?;
                int?contributionId = row["ContributionID"] as int?;

                if (contributionId != null && !importedContributions.ContainsKey(contributionId))
                {
                    var transaction = new FinancialTransaction();

                    string fundName = row["Fund_Name"] as string;

                    //Crossroads - Anything under a fund name that starts with Receipt - is an Event Registration.
                    if (fundName.StartsWith("Receipt -"))
                    {
                        transaction.TransactionTypeValueId = transactionTypeEventRegistrationId;
                    }
                    else
                    {
                        transaction.TransactionTypeValueId = transactionTypeContributionId;
                    }

                    int?associatedPersonId;
                    if (individualId != null)
                    {
                        associatedPersonId = GetPersonAliasId(individualId, householdId);
                    }                                                                                                   //will get the exact person if Individual Id is not null.
                    else
                    {
                        associatedPersonId = GetPersonId(householdAVList, householdId);
                    }                                                                          //Will attempt to get the Head first, then Spouse, then Child. Will exclude Other and Visitor
                    if (associatedPersonId != null)
                    {
                        transaction.AuthorizedPersonAliasId  = associatedPersonId;
                        transaction.CreatedByPersonAliasId   = ImportPersonAlias.Id;
                        transaction.ProcessedByPersonAliasId = associatedPersonId;
                        transaction.ForeignId = contributionId.ToString();

                        string summary = row["Memo"] as string;
                        if (summary != null)
                        {
                            transaction.Summary = summary;
                        }

                        int?batchId = row["BatchID"] as int?;
                        if (batchId != null && ImportedBatches.Any(b => b.Key == batchId))
                        {
                            transaction.BatchId = ImportedBatches.FirstOrDefault(b => b.Key == batchId).Value;
                        }

                        DateTime?receivedDate = row["Received_Date"] as DateTime?;
                        if (receivedDate != null)
                        {
                            transaction.TransactionDateTime = receivedDate;
                            transaction.CreatedDateTime     = receivedDate;
                        }

                        bool   isTypeNonCash    = false;
                        string contributionType = row["Contribution_Type_Name"].ToString().ToLower();
                        if (contributionType != null)
                        {
                            if (contributionType == "ach")
                            {
                                transaction.CurrencyTypeValueId = currencyTypeACH;
                            }
                            else if (contributionType == "cash")
                            {
                                transaction.CurrencyTypeValueId = currencyTypeCash;
                            }
                            else if (contributionType == "check")
                            {
                                transaction.CurrencyTypeValueId = currencyTypeCheck;
                            }
                            else if (contributionType == "credit card")
                            {
                                transaction.CurrencyTypeValueId = currencyTypeCreditCard;
                            }
                            else
                            {
                                isTypeNonCash = true;
                            }
                        }

                        string checkNumber = row["Check_Number"] as string;
                        if (checkNumber != null && checkNumber.AsType <int?>() != null)
                        {
                            // routing & account set to zero
                            transaction.CheckMicrEncrypted = Encryption.EncryptString(string.Format("{0}_{1}_{2}", 0, 0, checkNumber));
                        }


                        decimal?amount = row["Amount"] as decimal?;
                        if (fundName != null & amount != null)
                        {
                            FinancialAccount matchingAccount = null;
                            int?   parentAccountId           = null;
                            string parentAccountName         = String.Empty;
                            int?   fundCampusId = null;
                            fundName = fundName.Trim();

                            string subFund = row["Sub_Fund_Name"] as string;
                            if (subFund != null)
                            {
                                subFund = subFund.Trim();

                                // Check if subfund was used to mark a multi-site campus
                                fundCampusId = CampusList.Where(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode))
                                               .Select(c => (int?)c.Id).FirstOrDefault();

                                // Matched a campus, check to see if an account exists for that campus already
                                if (fundCampusId != null)
                                {
                                    matchingAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) &&
                                                                                 a.CampusId != null && a.CampusId.Equals(fundCampusId));
                                }
                                else
                                {
                                    // No campus match, look for an account that matches parent name and subfund name
                                    matchingAccount = accountList.FirstOrDefault(a => a.ParentAccountId != null && a.ParentAccount.Name.Equals(fundName) && a.Name.Equals(subFund));

                                    if (matchingAccount == null)
                                    {
                                        // Check if a parent account exists already
                                        FinancialAccount parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName));
                                        if (parentAccount == null)
                                        {
                                            parentAccount = AddAccount(lookupContext, fundName, fundCampusId);
                                            accountList.Add(parentAccount);
                                        }

                                        // set data for subfund to be created
                                        parentAccountId   = parentAccount.Id;
                                        fundName          = subFund;
                                        parentAccountName = parentAccount.Name;
                                    }
                                }
                            }
                            else
                            {
                                matchingAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) && a.CampusId == null);
                            }

                            if (matchingAccount == null)
                            {
                                // No account matches, create the new account with campus Id and parent Id if they were set
                                matchingAccount = AddAccount(lookupContext, fundName, fundCampusId, parentAccountName, parentAccountId);

                                accountList.Add(matchingAccount);
                            }

                            var transactionDetail = new FinancialTransactionDetail();
                            transactionDetail.Amount          = (decimal)amount;
                            transactionDetail.CreatedDateTime = receivedDate;
                            transactionDetail.AccountId       = matchingAccount.Id;
                            transactionDetail.IsNonCash       = isTypeNonCash;
                            transaction.TransactionDetails.Add(transactionDetail);


                            if (amount < 0)
                            {
                                var transactionRefund = new FinancialTransactionRefund();
                                transactionRefund.CreatedDateTime     = receivedDate;
                                transactionRefund.RefundReasonSummary = summary;
                                transactionRefund.RefundReasonValueId = refundReasons.Where(dv => summary != null && dv.Value.Contains(summary))
                                                                        .Select(dv => (int?)dv.Id).FirstOrDefault();
                                transaction.Refund = transactionRefund;
                            }
                        }

                        newTransactions.Add(transaction);
                        completed++;
                        if (completed % percentage < 1)
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress(percentComplete, string.Format("{0:N0} contributions imported ({1}% complete).", completed, percentComplete));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SaveContributions(newTransactions);
                            newTransactions.Clear();
                            ReportPartialProgress();
                        }
                    }
                }
            }

            if (newTransactions.Any())
            {
                SaveContributions(newTransactions);
            }

            ReportProgress(100, string.Format("Finished contribution import: {0:N0} contributions imported.", completed));
        }
예제 #12
0
        /// <summary>
        /// Loads the family data.
        /// </summary>
        /// <param name="csvData">The CSV data.</param>
        private int LoadFamily(CsvDataModel csvData)
        {
            // Required variables
            var lookupContext     = new RockContext();
            var locationService   = new LocationService(lookupContext);
            int familyGroupTypeId = GroupTypeCache.GetFamilyGroupType().Id;

            int numImportedFamilies = ImportedPeople.Select(p => p.ForeignId).Distinct().Count();

            int homeLocationTypeId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME)).Id;
            int workLocationTypeId = DefinedValueCache.Read(new Guid("E071472A-F805-4FC4-917A-D5E3C095C35C")).Id;

            var currentFamilyGroup = new Group();
            var newFamilyList      = new List <Group>();
            var newGroupLocations  = new Dictionary <GroupLocation, string>();

            string currentFamilyId = string.Empty;
            int    completed       = 0;

            ReportProgress(0, string.Format("Starting family import ({0:N0} already exist).", numImportedFamilies));

            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string rowFamilyId   = row[FamilyId];
                string rowFamilyName = row[FamilyName];

                if (!string.IsNullOrWhiteSpace(rowFamilyId) && rowFamilyId != currentFamilyGroup.ForeignId)
                {
                    currentFamilyGroup = ImportedPeople.FirstOrDefault(p => p.ForeignId == rowFamilyId);
                    if (currentFamilyGroup == null)
                    {
                        currentFamilyGroup           = new Group();
                        currentFamilyGroup.ForeignId = rowFamilyId;
                        currentFamilyGroup.Name      = row[FamilyName];
                        currentFamilyGroup.CreatedByPersonAliasId = ImportPersonAlias.Id;
                        currentFamilyGroup.GroupTypeId            = familyGroupTypeId;
                        newFamilyList.Add(currentFamilyGroup);
                    }

                    // Set the family campus
                    string campusName = row[Campus];
                    if (!string.IsNullOrWhiteSpace(campusName))
                    {
                        var familyCampus = CampusList.Where(c => c.Name.StartsWith(campusName) || c.ShortCode.StartsWith(campusName)).FirstOrDefault();
                        if (familyCampus == null)
                        {
                            familyCampus          = new Campus();
                            familyCampus.IsSystem = false;
                            familyCampus.Name     = campusName;
                            lookupContext.Campuses.Add(familyCampus);
                            lookupContext.SaveChanges(true);
                        }

                        // This won't assign a campus if the family already exists because the context doesn't get saved
                        currentFamilyGroup.CampusId = familyCampus.Id;
                    }

                    // Add the family addresses since they exist in this file
                    string famAddress  = row[Address];
                    string famAddress2 = row[Address2];
                    string famCity     = row[City];
                    string famState    = row[State];
                    string famZip      = row[Zip];
                    string famCountry  = row[Country];

                    // Use the core Rock location service to add or lookup an address
                    Location primaryAddress = locationService.Get(famAddress, famAddress2, famCity, famState, famZip, famCountry);
                    if (primaryAddress != null)
                    {
                        primaryAddress.Name = currentFamilyGroup.Name + " Home";

                        var primaryLocation = new GroupLocation();
                        primaryLocation.LocationId               = primaryAddress.Id;
                        primaryLocation.IsMailingLocation        = true;
                        primaryLocation.IsMappedLocation         = true;
                        primaryLocation.GroupLocationTypeValueId = homeLocationTypeId;
                        newGroupLocations.Add(primaryLocation, rowFamilyId);
                    }

                    string famSecondAddress  = row[SecondaryAddress];
                    string famSecondAddress2 = row[SecondaryAddress2];
                    string famSecondCity     = row[SecondaryCity];
                    string famSecondState    = row[SecondaryState];
                    string famSecondZip      = row[SecondaryZip];
                    string famSecondCountry  = row[SecondaryCountry];

                    Location secondaryAddress = locationService.Get(famSecondAddress, famSecondAddress2, famSecondCity, famSecondState, famSecondZip, famSecondCountry);
                    if (secondaryAddress != null)
                    {
                        secondaryAddress.Name = currentFamilyGroup.Name + " Work";

                        var secondaryLocation = new GroupLocation();
                        secondaryLocation.LocationId               = primaryAddress.Id;
                        secondaryLocation.IsMailingLocation        = true;
                        secondaryLocation.IsMappedLocation         = true;
                        secondaryLocation.GroupLocationTypeValueId = workLocationTypeId;
                        newGroupLocations.Add(secondaryLocation, rowFamilyId);
                    }

                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, string.Format("{0:N0} families imported.", completed));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFamilies(newFamilyList, newGroupLocations);
                        ReportPartialProgress();

                        // Reset lookup context
                        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);
            }

            ReportProgress(0, string.Format("Finished family import: {0:N0} families imported.", completed));
            return(completed);
        }
예제 #13
0
        /// <summary>
        /// Maps the pledge.
        /// </summary>
        /// <param name="csvData">todo: describe csvData parameter on MapPledge</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapPledge(CSVInstance csvData)
        {
            var lookupContext   = new RockContext();
            var accountList     = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();
            var importedPledges = new FinancialPledgeService(lookupContext).Queryable().AsNoTracking()
                                  .Where(p => p.ForeignId != null)
                                  .ToDictionary(t => (int)t.ForeignId, t => (int?)t.Id);

            var pledgeFrequencies        = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY), lookupContext).DefinedValues;
            var oneTimePledgeFrequencyId = pledgeFrequencies.FirstOrDefault(f => f.Guid == new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME)).Id;

            var newPledges = new List <FinancialPledge>();

            var completed = 0;

            ReportProgress(0, $"Verifying pledge import ({importedPledges.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 amountKey    = row[TotalPledge];
                var amount       = amountKey.AsType <decimal?>();
                var startDateKey = row[StartDate];
                if (string.IsNullOrWhiteSpace(startDateKey))
                {
                    startDateKey = "01/01/0001";
                }
                var startDate  = startDateKey.AsType <DateTime?>();
                var endDateKey = row[EndDate];
                if (string.IsNullOrWhiteSpace(endDateKey))
                {
                    endDateKey = "12/31/9999";
                }
                var endDate        = endDateKey.AsType <DateTime?>();
                var createdDateKey = row[PledgeCreatedDate];
                if (string.IsNullOrWhiteSpace(createdDateKey))
                {
                    createdDateKey = ImportDateTime.ToString();
                }
                var createdDate     = createdDateKey.AsType <DateTime?>();
                var modifiedDateKey = row[PledgeModifiedDate];
                if (string.IsNullOrWhiteSpace(modifiedDateKey))
                {
                    modifiedDateKey = ImportDateTime.ToString();
                }
                var modifiedDate = modifiedDateKey.AsType <DateTime?>();

                var pledgeIdKey = row[PledgeId];
                var pledgeId    = pledgeIdKey.AsType <int?>();
                if (amount != null && !importedPledges.ContainsKey((int)pledgeId))
                {
                    var individualIdKey = row[IndividualID];

                    var personKeys = GetPersonKeys(individualIdKey);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        var pledge = new FinancialPledge
                        {
                            PersonAliasId          = personKeys.PersonAliasId,
                            CreatedByPersonAliasId = ImportPersonAliasId,
                            StartDate               = (DateTime)startDate,
                            EndDate                 = (DateTime)endDate,
                            TotalAmount             = (decimal)amount,
                            CreatedDateTime         = createdDate,
                            ModifiedDateTime        = modifiedDate,
                            ModifiedByPersonAliasId = ImportPersonAliasId,
                            ForeignKey              = pledgeIdKey,
                            ForeignId               = pledgeId
                        };

                        var frequency = row[PledgeFrequencyName].ToString().ToLower();
                        if (!string.IsNullOrWhiteSpace(frequency))
                        {
                            frequency = frequency.ToLower();
                            if (frequency.Equals("one time") || frequency.Equals("one-time") || frequency.Equals("as can"))
                            {
                                pledge.PledgeFrequencyValueId = oneTimePledgeFrequencyId;
                            }
                            else
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies
                                                                .Where(f => f.Value.ToLower().StartsWith(frequency) || f.Description.ToLower().StartsWith(frequency))
                                                                .Select(f => f.Id).FirstOrDefault();
                            }
                        }

                        var fundName           = row[FundName] as string;
                        var subFund            = row[SubFundName] as string;
                        var fundGLAccount      = row[FundGLAccount] as string;
                        var subFundGLAccount   = row[SubFundGLAccount] as string;
                        var isFundActiveKey    = row[FundIsActive];
                        var isFundActive       = isFundActiveKey.AsType <bool?>();
                        var isSubFundActiveKey = row[SubFundIsActive];
                        var isSubFundActive    = isSubFundActiveKey.AsType <bool?>();

                        if (!string.IsNullOrWhiteSpace(fundName))
                        {
                            var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName.Truncate(50)));
                            if (parentAccount == null)
                            {
                                parentAccount = AddAccount(lookupContext, fundName, string.Empty, null, null, isFundActive, null, null, null, null, "", "", null);
                                accountList.Add(parentAccount);
                            }

                            if (!string.IsNullOrWhiteSpace(subFund))
                            {
                                int?campusFundId = null;
                                // assign a campus if the subfund is a campus fund
                                var campusFund = CampusList.FirstOrDefault(c => subFund.Contains(c.Name) || subFund.Contains(c.ShortCode));
                                if (campusFund != null)
                                {
                                    campusFundId = campusFund.Id;
                                }

                                // add info to easily find/assign this fund in the view
                                subFund = $"{fundName} {subFund}";

                                var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund.Truncate(50)) && c.ParentAccountId == parentAccount.Id);
                                if (childAccount == null)
                                {
                                    // create a child account with a campusId if it was set
                                    childAccount = AddAccount(lookupContext, subFund, string.Empty, campusFundId, parentAccount.Id, isSubFundActive, null, null, null, null, "", "", null);
                                    accountList.Add(childAccount);
                                }

                                pledge.AccountId = childAccount.Id;
                            }
                            else
                            {
                                pledge.AccountId = parentAccount.Id;
                            }
                        }

                        newPledges.Add(pledge);
                        completed++;
                        if (completed % (ReportingNumber * 10) < 1)
                        {
                            ReportProgress(0, $"{completed:N0} pledges imported.");
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SavePledges(newPledges);
                            ReportPartialProgress();
                            newPledges.Clear();
                        }
                    }
                }
            }

            if (newPledges.Any())
            {
                SavePledges(newPledges);
            }

            ReportProgress(100, $"Finished pledge import: {completed:N0} pledges imported.");
            return(completed);
        }
예제 #14
0
        /// <summary>
        /// Maps the contribution.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        private int MapContribution(CSVInstance csvData)
        {
            var lookupContext = new RockContext();

            var currencyTypes          = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE));
            var currencyTypeACH        = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH))).Id;
            var currencyTypeCash       = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH))).Id;
            var currencyTypeCheck      = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK))).Id;
            var currencyTypeCreditCard = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD))).Id;
            var currencyTypeNonCash    = currencyTypes.DefinedValues.Where(dv => dv.Value.Equals("Non-Cash")).Select(dv => (int?)dv.Id).FirstOrDefault();

            if (currencyTypeNonCash == null)
            {
                var newTenderNonCash = new DefinedValue
                {
                    Value         = "Non-Cash",
                    Description   = "Non-Cash",
                    DefinedTypeId = currencyTypes.Id
                };
                lookupContext.DefinedValues.Add(newTenderNonCash);
                lookupContext.SaveChanges();
                currencyTypeNonCash = newTenderNonCash.Id;
            }

            var creditCardTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE)).DefinedValues;

            var sourceTypeOnsite  = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_ONSITE_COLLECTION), lookupContext).Id;
            var sourceTypeWebsite = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE), lookupContext).Id;
            var sourceTypeKiosk   = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_KIOSK), lookupContext).Id;

            var refundReasons = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON), lookupContext).DefinedValues;

            var accountList = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();

            int?defaultBatchId = null;

            if (ImportedBatches.ContainsKey(0))
            {
                defaultBatchId = ImportedBatches[0];
            }

            // Look for custom attributes in the Contribution file
            var allFields        = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList();
            var customAttributes = allFields
                                   .Where(f => f.index > ContributionCreditCardType)
                                   .ToDictionary(f => f.index, f => f.node.Name);

            // Get all imported contributions
            var importedContributions = new FinancialTransactionService(lookupContext).Queryable().AsNoTracking()
                                        .Where(c => c.ForeignId != null)
                                        .Select(t => (int)t.ForeignId)
                                        .OrderBy(t => t).ToList();

            // List for batching new contributions
            var newTransactions = new List <FinancialTransaction>();

            var completed = 0;

            ReportProgress(0, $"Verifying contribution import ({importedContributions.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 individualIdKey   = row[IndividualID];
                var contributionIdKey = row[ContributionID];
                var contributionId    = contributionIdKey.AsType <int?>();

                if (contributionId != null && !importedContributions.Contains((int)contributionId))
                {
                    var transaction = new FinancialTransaction
                    {
                        CreatedByPersonAliasId  = ImportPersonAliasId,
                        ModifiedByPersonAliasId = ImportPersonAliasId,
                        TransactionTypeValueId  = TransactionTypeContributionId,
                        ForeignKey = contributionId.ToString(),
                        ForeignId  = contributionId
                    };

                    int?giverAliasId = null;
                    var personKeys   = GetPersonKeys(individualIdKey);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        giverAliasId = personKeys.PersonAliasId;
                        transaction.CreatedByPersonAliasId   = giverAliasId;
                        transaction.AuthorizedPersonAliasId  = giverAliasId;
                        transaction.ProcessedByPersonAliasId = giverAliasId;
                    }
                    else if (AnonymousGiverAliasId != null && AnonymousGiverAliasId > 0)
                    {
                        giverAliasId = AnonymousGiverAliasId;
                        transaction.AuthorizedPersonAliasId  = giverAliasId;
                        transaction.ProcessedByPersonAliasId = giverAliasId;
                    }

                    var summary = row[Memo] as string;
                    if (!string.IsNullOrWhiteSpace(summary))
                    {
                        transaction.Summary = summary;
                    }

                    var batchIdKey = row[ContributionBatchID];
                    var batchId    = batchIdKey.AsType <int?>();
                    if (batchId != null && ImportedBatches.Any(b => b.Key.Equals(batchId)))
                    {
                        transaction.BatchId = ImportedBatches.FirstOrDefault(b => b.Key.Equals(batchId)).Value;
                    }
                    else
                    {
                        // use the default batch for any non-matching transactions
                        transaction.BatchId = defaultBatchId;
                    }

                    var receivedDateKey = row[ReceivedDate];
                    var receivedDate    = receivedDateKey.AsType <DateTime?>();
                    if (receivedDate != null)
                    {
                        transaction.TransactionDateTime = receivedDate;
                        transaction.CreatedDateTime     = receivedDate;
                        transaction.ModifiedDateTime    = ImportDateTime;
                    }

                    var contributionType = row[ContributionTypeName];
                    var creditCardType   = row[ContributionCreditCardType];
                    if (!string.IsNullOrWhiteSpace(contributionType))
                    {
                        // set default source to onsite, exceptions listed below
                        transaction.SourceTypeValueId = sourceTypeOnsite;

                        int?paymentCurrencyTypeId = null, creditCardTypeId = null;

                        if (contributionType.Equals("cash", StringComparison.CurrentCultureIgnoreCase))
                        {
                            paymentCurrencyTypeId = currencyTypeCash;
                        }
                        else if (contributionType.Equals("check", StringComparison.CurrentCultureIgnoreCase))
                        {
                            paymentCurrencyTypeId = currencyTypeCheck;
                        }
                        else if (contributionType.Equals("ach", StringComparison.CurrentCultureIgnoreCase))
                        {
                            paymentCurrencyTypeId         = currencyTypeACH;
                            transaction.SourceTypeValueId = sourceTypeWebsite;
                        }
                        else if (contributionType.Equals("credit card", StringComparison.CurrentCultureIgnoreCase))
                        {
                            paymentCurrencyTypeId         = currencyTypeCreditCard;
                            transaction.SourceTypeValueId = sourceTypeWebsite;

                            // Determine CC Type
                            if (!string.IsNullOrWhiteSpace(creditCardType))
                            {
                                creditCardTypeId = creditCardTypes.Where(c => c.Value.StartsWith(creditCardType, StringComparison.CurrentCultureIgnoreCase) ||
                                                                         c.Description.StartsWith(creditCardType, StringComparison.CurrentCultureIgnoreCase))
                                                   .Select(c => c.Id).FirstOrDefault();
                            }
                        }
                        else
                        {
                            paymentCurrencyTypeId = currencyTypeNonCash;
                        }

                        var paymentDetail = new FinancialPaymentDetail
                        {
                            CreatedDateTime         = receivedDate,
                            CreatedByPersonAliasId  = giverAliasId,
                            ModifiedDateTime        = ImportDateTime,
                            ModifiedByPersonAliasId = giverAliasId,
                            CurrencyTypeValueId     = paymentCurrencyTypeId,
                            CreditCardTypeValueId   = creditCardTypeId,
                            ForeignKey = contributionId.ToString(),
                            ForeignId  = contributionId
                        };

                        transaction.FinancialPaymentDetail = paymentDetail;
                    }

                    var transactionCode = row[CheckNumber] as string;
                    // if transaction code provided, put it in the transaction code
                    if (!string.IsNullOrEmpty(transactionCode))
                    {
                        transaction.TransactionCode = transactionCode;

                        // check for SecureGive kiosk transactions
                        if (transactionCode.StartsWith("SG"))
                        {
                            transaction.SourceTypeValueId = sourceTypeKiosk;
                        }
                    }

                    var fundName           = row[FundName] as string;
                    var subFund            = row[SubFundName] as string;
                    var fundGLAccount      = row[FundGLAccount] as string;
                    var subFundGLAccount   = row[SubFundGLAccount] as string;
                    var isFundActiveKey    = row[FundIsActive];
                    var isFundActive       = isFundActiveKey.AsType <bool?>();
                    var isSubFundActiveKey = row[SubFundIsActive];
                    var isSubFundActive    = isSubFundActiveKey.AsType <bool?>();
                    var statedValueKey     = row[StatedValue];
                    var statedValue        = statedValueKey.AsType <decimal?>();
                    var amountKey          = row[Amount];
                    var amount             = amountKey.AsType <decimal?>();
                    if (!string.IsNullOrWhiteSpace(fundName) & amount != null)
                    {
                        int transactionAccountId;
                        var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName.Truncate(50)));
                        if (parentAccount == null)
                        {
                            parentAccount = AddAccount(lookupContext, fundName, fundGLAccount, null, null, isFundActive, null, null, null, null, "", "", null);
                            accountList.Add(parentAccount);
                        }

                        if (!string.IsNullOrWhiteSpace(subFund))
                        {
                            int?campusFundId = null;
                            // assign a campus if the subfund is a campus fund
                            var campusFund = CampusList.FirstOrDefault(c => subFund.Contains(c.Name) || subFund.Contains(c.ShortCode));
                            if (campusFund != null)
                            {
                                campusFundId = campusFund.Id;
                            }

                            // add info to easily find/assign this fund in the view
                            subFund = $"{fundName} {subFund}";

                            var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund.Truncate(50)) && c.ParentAccountId == parentAccount.Id);
                            if (childAccount == null)
                            {
                                // create a child account with a campusId if it was set
                                childAccount = AddAccount(lookupContext, subFund, subFundGLAccount, campusFundId, parentAccount.Id, isSubFundActive, null, null, null, null, "", "", null);
                                accountList.Add(childAccount);
                            }

                            transactionAccountId = childAccount.Id;
                        }
                        else
                        {
                            transactionAccountId = parentAccount.Id;
                        }

                        if (amount == 0 && statedValue != null && statedValue != 0)
                        {
                            amount = statedValue;
                        }

                        var transactionDetail = new FinancialTransactionDetail
                        {
                            Amount          = (decimal)amount,
                            CreatedDateTime = receivedDate,
                            AccountId       = transactionAccountId
                        };
                        transaction.TransactionDetails.Add(transactionDetail);

                        if (amount < 0)
                        {
                            transaction.RefundDetails = new FinancialTransactionRefund();
                            transaction.RefundDetails.CreatedDateTime     = receivedDate;
                            transaction.RefundDetails.RefundReasonValueId = refundReasons.Where(dv => summary != null && dv.Value.Contains(summary))
                                                                            .Select(dv => (int?)dv.Id).FirstOrDefault();
                            transaction.RefundDetails.RefundReasonSummary = summary;
                        }
                    }

                    newTransactions.Add(transaction);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, $"{completed:N0} contributions imported.");
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveContributions(newTransactions);
                        newTransactions.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newTransactions.Any())
            {
                SaveContributions(newTransactions);
            }

            ReportProgress(100, $"Finished contribution import: {completed:N0} contributions imported.");
            return(completed);
        }
예제 #15
0
        /// <summary>
        /// Maps the home group membership data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapGroups(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext        = new RockContext();
            var newGroupMembers      = new List <GroupMember>();
            var importedGroupMembers = lookupContext.GroupMembers.Count(gm => gm.ForeignKey != null && gm.Group.GroupTypeId == GeneralGroupTypeId);
            var groupRoleMember      = GroupTypeCache.Get(GeneralGroupTypeId).Roles.FirstOrDefault(r => r.Name.Equals("Member"));

            var archivedScheduleName = "Archived Attendance";
            var archivedScheduleId   = new ScheduleService(lookupContext).Queryable()
                                       .Where(s => s.Name.Equals(archivedScheduleName, StringComparison.OrdinalIgnoreCase))
                                       .Select(s => ( int? )s.Id).FirstOrDefault();

            if (!archivedScheduleId.HasValue)
            {
                var archivedSchedule = AddNamedSchedule(lookupContext, archivedScheduleName, null, null, null,
                                                        ImportDateTime, archivedScheduleName.RemoveSpecialCharacters(), true, ImportPersonAliasId);
                archivedScheduleId = archivedSchedule.Id;
            }

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

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

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

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

            ReportProgress(0, string.Format("Verifying people groups import ({0:N0} found, {1:N0} already exist).", totalRows, importedGroupMembers));

            foreach (var row in tableData.Where(r => r != null))
            {
                var groupId      = row["Group_ID"] as int?;
                var groupName    = row["Group_Name"] as string;
                var individualId = row["Individual_ID"] as int?;
                var groupCreated = row["Created_Date"] as DateTime?;
                var groupType    = row["Group_Type_Name"] as string;

                // require at least a group id and name
                if (groupId.HasValue && !string.IsNullOrWhiteSpace(groupName) && !groupName.Equals("Delete", StringComparison.OrdinalIgnoreCase))
                {
                    var peopleGroup = ImportedGroups.FirstOrDefault(g => g.ForeignKey.Equals(groupId.ToString()));
                    if (peopleGroup == null)
                    {
                        int?campusId           = null;
                        var parentGroupId      = archivedGroups.Id;
                        var currentGroupTypeId = GeneralGroupTypeId;
                        if (!string.IsNullOrWhiteSpace(groupType))
                        {
                            // check for a campus on the grouptype
                            campusId = GetCampusId(groupType, true, SearchDirection.Ends);
                            if (campusId.HasValue)
                            {
                                groupType = StripSuffix(groupType, campusId);
                            }

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

                            // create a placeholder group for the grouptype if it doesn't exist
                            var groupTypePlaceholder = ImportedGroups.FirstOrDefault(g => g.GroupTypeId == currentGroupType.Id && g.ForeignKey.Equals(groupType.RemoveWhitespace()));
                            if (groupTypePlaceholder == null)
                            {
                                groupTypePlaceholder = AddGroup(lookupContext, currentGroupType.Id, archivedGroups.Id, groupType, true, null, ImportDateTime,
                                                                groupType.RemoveWhitespace(), true, ImportPersonAliasId);
                                ImportedGroups.Add(groupTypePlaceholder);
                            }

                            parentGroupId      = groupTypePlaceholder.Id;
                            currentGroupTypeId = currentGroupType.Id;
                        }

                        // put the current group under a campus parent if it exists
                        campusId = campusId ?? GetCampusId(groupName);
                        if (campusId.HasValue)
                        {
                            // create a campus level parent for the home group
                            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, currentGroupTypeId, parentGroupId, campus.Name, true, campus.Id, ImportDateTime, campus.ShortCode, true, ImportPersonAliasId);
                                ImportedGroups.Add(campusGroup);
                            }

                            parentGroupId = campusGroup.Id;
                        }

                        // add the group, finally
                        peopleGroup = AddGroup(lookupContext, currentGroupTypeId, parentGroupId, groupName, true, campusId, null, groupId.ToString(), true, ImportPersonAliasId, archivedScheduleId);
                        ImportedGroups.Add(peopleGroup);
                    }

                    // add the group member
                    var personKeys = GetPersonKeys(individualId, null);
                    if (personKeys != null)
                    {
                        newGroupMembers.Add(new GroupMember
                        {
                            IsSystem          = false,
                            GroupId           = peopleGroup.Id,
                            PersonId          = personKeys.PersonId,
                            GroupRoleId       = groupRoleMember.Id,
                            GroupMemberStatus = GroupMemberStatus.Active,
                            ForeignKey        = string.Format("Membership imported {0}", ImportDateTime)
                        });

                        completedItems++;
                    }

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

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveGroupMembers(newGroupMembers);
                        ReportPartialProgress();

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

            if (newGroupMembers.Any())
            {
                SaveGroupMembers(newGroupMembers);
            }

            lookupContext.Dispose();
            ReportProgress(100, string.Format("Finished people groups import: {0:N0} members imported.", completedItems));
        }
예제 #16
0
        /// <summary>
        /// Maps the contribution.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        private int MapContribution(CSVInstance csvData)
        {
            var lookupContext                 = new RockContext();
            int transactionEntityTypeId       = EntityTypeCache.Read("Rock.Model.FinancialTransaction").Id;
            var transactionTypeContributionId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION), lookupContext).Id;

            var currencyTypes          = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CURRENCY_TYPE));
            int currencyTypeACH        = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_ACH))).Id;
            int currencyTypeCash       = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CASH))).Id;
            int currencyTypeCheck      = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CHECK))).Id;
            int currencyTypeCreditCard = currencyTypes.DefinedValues.FirstOrDefault(dv => dv.Guid.Equals(new Guid(Rock.SystemGuid.DefinedValue.CURRENCY_TYPE_CREDIT_CARD))).Id;
            int?currencyTypeNonCash    = currencyTypes.DefinedValues.Where(dv => dv.Value.Equals("Non-Cash")).Select(dv => (int?)dv.Id).FirstOrDefault();

            if (currencyTypeNonCash == null)
            {
                var newTenderNonCash = new DefinedValue();
                newTenderNonCash.Value         = "Non-Cash";
                newTenderNonCash.Description   = "Non-Cash";
                newTenderNonCash.DefinedTypeId = currencyTypes.Id;
                lookupContext.DefinedValues.Add(newTenderNonCash);
                lookupContext.SaveChanges();

                currencyTypeNonCash = newTenderNonCash.Id;
            }

            var creditCardTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_CREDIT_CARD_TYPE)).DefinedValues;

            int sourceTypeOnsite  = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_ONSITE_COLLECTION), lookupContext).Id;
            int sourceTypeWebsite = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_WEBSITE), lookupContext).Id;
            int sourceTypeKiosk   = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.FINANCIAL_SOURCE_TYPE_KIOSK), lookupContext).Id;

            var refundReasons = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_TRANSACTION_REFUND_REASON), lookupContext).DefinedValues;

            var accountList = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();

            int?defaultBatchId = null;

            if (ImportedBatches.ContainsKey(0))
            {
                defaultBatchId = ImportedBatches[0];
            }

            // Get all imported contributions
            var importedContributions = new FinancialTransactionService(lookupContext).Queryable().AsNoTracking()
                                        .Where(c => c.ForeignId != null)
                                        .ToDictionary(t => (int)t.ForeignId, t => (int?)t.Id);

            // List for batching new contributions
            var newTransactions = new List <FinancialTransaction>();

            int completed = 0;

            ReportProgress(0, string.Format("Verifying contribution import ({0:N0} already exist).", importedContributions.Count));
            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string individualIdKey   = row[IndividualID];
                int?   individualId      = individualIdKey.AsType <int?>();
                string contributionIdKey = row[ContributionID];
                int?   contributionId    = contributionIdKey.AsType <int?>();

                if (contributionId != null && !importedContributions.ContainsKey((int)contributionId))
                {
                    var transaction = new FinancialTransaction();
                    transaction.CreatedByPersonAliasId  = ImportPersonAliasId;
                    transaction.ModifiedByPersonAliasId = ImportPersonAliasId;
                    transaction.TransactionTypeValueId  = transactionTypeContributionId;
                    transaction.ForeignKey = contributionId.ToString();
                    transaction.ForeignId  = contributionId;

                    int?giverAliasId = null;
                    var personKeys   = GetPersonKeys(individualId);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        giverAliasId = personKeys.PersonAliasId;
                        transaction.CreatedByPersonAliasId   = giverAliasId;
                        transaction.AuthorizedPersonAliasId  = giverAliasId;
                        transaction.ProcessedByPersonAliasId = giverAliasId;
                    }

                    string summary = row[Memo] as string;
                    if (summary != null)
                    {
                        transaction.Summary = summary;
                    }

                    string batchIdKey = row[ContributionBatchID];
                    int?   batchId    = batchIdKey.AsType <int?>();
                    if (batchId != null && ImportedBatches.Any(b => b.Key.Equals(batchId)))
                    {
                        transaction.BatchId = ImportedBatches.FirstOrDefault(b => b.Key.Equals(batchId)).Value;
                    }
                    else
                    {
                        // use the default batch for any non-matching transactions
                        transaction.BatchId = defaultBatchId;
                    }

                    string   receivedDateKey = row[ReceivedDate];
                    DateTime?receivedDate    = receivedDateKey.AsType <DateTime?>();
                    if (receivedDate != null)
                    {
                        transaction.TransactionDateTime = receivedDate;
                        transaction.CreatedDateTime     = receivedDate;
                        transaction.ModifiedDateTime    = ImportDateTime;
                    }

                    string contributionType = row[ContributionTypeName].ToStringSafe().ToLower();
                    if (contributionType != null)
                    {
                        // set default source to onsite, exceptions listed below
                        transaction.SourceTypeValueId = sourceTypeOnsite;

                        int?paymentCurrencyTypeId = null, creditCardTypeId = null;

                        if (contributionType == "cash")
                        {
                            paymentCurrencyTypeId = currencyTypeCash;
                        }
                        else if (contributionType == "check")
                        {
                            paymentCurrencyTypeId = currencyTypeCheck;
                        }
                        else if (contributionType == "ach")
                        {
                            paymentCurrencyTypeId         = currencyTypeACH;
                            transaction.SourceTypeValueId = sourceTypeWebsite;
                        }
                        else if (contributionType == "credit card")
                        {
                            paymentCurrencyTypeId         = currencyTypeCreditCard;
                            transaction.SourceTypeValueId = sourceTypeWebsite;
                        }
                        else
                        {
                            paymentCurrencyTypeId = currencyTypeNonCash;
                        }

                        var paymentDetail = new FinancialPaymentDetail();
                        paymentDetail.CreatedDateTime         = receivedDate;
                        paymentDetail.CreatedByPersonAliasId  = giverAliasId;
                        paymentDetail.ModifiedDateTime        = ImportDateTime;
                        paymentDetail.ModifiedByPersonAliasId = giverAliasId;
                        paymentDetail.CurrencyTypeValueId     = paymentCurrencyTypeId;
                        paymentDetail.CreditCardTypeValueId   = creditCardTypeId;
                        paymentDetail.ForeignKey = contributionId.ToString();
                        paymentDetail.ForeignId  = contributionId;

                        transaction.FinancialPaymentDetail = paymentDetail;
                    }

                    string checkNumber = row[CheckNumber] as string;
                    // if the check number is valid, put it in the transaction code
                    if (checkNumber.AsType <int?>() != null)
                    {
                        transaction.TransactionCode = checkNumber;
                    }
                    // check for SecureGive kiosk transactions
                    else if (!string.IsNullOrEmpty(checkNumber) && checkNumber.StartsWith("SG"))
                    {
                        transaction.SourceTypeValueId = sourceTypeKiosk;
                    }

                    string  fundName         = row[FundName] as string;
                    string  subFund          = row[SubFundName] as string;
                    string  fundGLAccount    = row[FundGLAccount] as string;
                    string  subFundGLAccount = row[SubFundGLAccount] as string;
                    string  isFundActiveKey  = row[FundIsActive];
                    Boolean?isFundActive     = isFundActiveKey.AsType <Boolean?>();
                    string  statedValueKey   = row[StatedValue];
                    decimal?statedValue      = statedValueKey.AsType <decimal?>();
                    string  amountKey        = row[Amount];
                    decimal?amount           = amountKey.AsType <decimal?>();
                    if (fundName != null & amount != null)
                    {
                        int transactionAccountId;
                        var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) && a.CampusId == null);
                        if (parentAccount == null)
                        {
                            parentAccount = AddAccount(lookupContext, fundName, fundGLAccount, null, null, isFundActive);
                            accountList.Add(parentAccount);
                        }

                        if (!String.IsNullOrWhiteSpace(subFund))
                        {
                            int?campusFundId = null;
                            // assign a campus if the subfund is a campus fund
                            var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode));
                            if (campusFund != null)
                            {
                                // use full campus name as the subfund
                                subFund      = campusFund.Name;
                                campusFundId = campusFund.Id;
                            }

                            // add info to easily find/assign this fund in the view
                            subFund = string.Format("{0} {1}", subFund, fundName);

                            var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund) && c.ParentAccountId == parentAccount.Id);
                            if (childAccount == null)
                            {
                                // create a child account with a campusId if it was set
                                childAccount = AddAccount(lookupContext, subFund, subFundGLAccount, campusFundId, parentAccount.Id, isFundActive);
                                accountList.Add(childAccount);
                            }

                            transactionAccountId = childAccount.Id;
                        }
                        else
                        {
                            transactionAccountId = parentAccount.Id;
                        }

                        if (amount == 0 && statedValue != null && statedValue != 0)
                        {
                            amount = statedValue;
                        }

                        var transactionDetail = new FinancialTransactionDetail();
                        transactionDetail.Amount          = (decimal)amount;
                        transactionDetail.CreatedDateTime = receivedDate;
                        transactionDetail.AccountId       = transactionAccountId;
                        transaction.TransactionDetails.Add(transactionDetail);

                        if (amount < 0)
                        {
                            transaction.RefundDetails = new FinancialTransactionRefund();
                            transaction.RefundDetails.CreatedDateTime     = receivedDate;
                            transaction.RefundDetails.RefundReasonValueId = refundReasons.Where(dv => summary != null && dv.Value.Contains(summary))
                                                                            .Select(dv => (int?)dv.Id).FirstOrDefault();
                            transaction.RefundDetails.RefundReasonSummary = summary;
                        }
                    }

                    newTransactions.Add(transaction);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, string.Format("{0:N0} contributions imported.", completed));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveContributions(newTransactions);
                        newTransactions.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newTransactions.Any())
            {
                SaveContributions(newTransactions);
            }

            ReportProgress(100, string.Format("Finished contribution import: {0:N0} contributions imported.", completed));
            return(completed);
        }
예제 #17
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapBatch(IQueryable <Row> tableData)
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches        = new List <FinancialBatch>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying batch import ({0:N0} found, {1:N0} already exist).", totalRows, ImportedBatches.Count));
            foreach (var row in tableData.Where(r => r != null))
            {
                int?batchId = row["BatchID"] as int?;
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey             = batchId.ToString();
                    batch.ForeignId            = batchId;
                    batch.Note                 = string.Empty;
                    batch.Status               = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row["BatchName"] as string;
                    if (name != null)
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    DateTime?batchDate = row["BatchDate"] as DateTime?;
                    if (batchDate != null)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;
                    }

                    decimal?amount = row["BatchAmount"] as decimal?;
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} batches imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);
                        newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime        = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status        = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name          = string.Format("Default Batch (Imported {0})", ImportDateTime);
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey    = "0";
                defaultBatch.ForeignId     = 0;

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, string.Format("Finished batch import: {0:N0} batches imported.", completed));
        }
예제 #18
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapBatch(CSVInstance csvData)
        {
            var batchStatusClosed = Rock.Model.BatchStatus.Closed;
            var newBatches        = new List <FinancialBatch>();

            int completed = 0;

            ReportProgress(0, string.Format("Verifying batch import ({0:N0} already exist).", ImportedBatches.Count));
            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string batchIdKey = row[BatchID];
                int?   batchId    = batchIdKey.AsType <int?>();
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch();
                    batch.CreatedByPersonAliasId = ImportPersonAliasId;
                    batch.ForeignKey             = batchId.ToString();
                    batch.ForeignId            = batchId;
                    batch.Note                 = string.Empty;
                    batch.Status               = batchStatusClosed;
                    batch.AccountingSystemCode = string.Empty;

                    string name = row[BatchName] as string;
                    if (name != null)
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    string   batchDateKey = row[BatchDate];
                    DateTime?batchDate    = batchDateKey.AsType <DateTime?>();
                    if (batchDate != null)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;
                    }

                    string  amountKey = row[BatchAmount];
                    decimal?amount    = amountKey.AsType <decimal?>();
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, string.Format("{0:N0} batches imported.", completed));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);
                        newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch();
                defaultBatch.CreatedDateTime        = ImportDateTime;
                defaultBatch.CreatedByPersonAliasId = ImportPersonAliasId;
                defaultBatch.Status        = Rock.Model.BatchStatus.Closed;
                defaultBatch.Name          = string.Format("Default Batch (Imported {0})", ImportDateTime);
                defaultBatch.ControlAmount = 0.0m;
                defaultBatch.ForeignKey    = "0";
                defaultBatch.ForeignId     = 0;

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, string.Format("Finished batch import: {0:N0} batches imported.", completed));
            return(completed);
        }
예제 #19
0
        /// <summary>
        /// Maps the pledge.
        /// </summary>
        /// <param name="queryable">The queryable.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapPledge(IQueryable <Row> tableData)
        {
            var lookupContext   = new RockContext();
            var accountList     = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();
            var importedPledges = new FinancialPledgeService(lookupContext).Queryable().AsNoTracking().ToList();

            var pledgeFrequencies        = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY), lookupContext).DefinedValues;
            int oneTimePledgeFrequencyId = pledgeFrequencies.FirstOrDefault(f => f.Guid == new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME)).Id;

            var newPledges = new List <FinancialPledge>();

            int completed  = 0;
            int totalRows  = tableData.Count();
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying pledge import ({0:N0} found).", totalRows));

            foreach (var row in tableData.Where(r => r != null))
            {
                decimal? amount    = row["Total_Pledge"] as decimal?;
                DateTime?startDate = row["Start_Date"] as DateTime?;
                DateTime?endDate   = row["End_Date"] as DateTime?;
                if (amount != null && startDate != null && endDate != null)
                {
                    int?individualId = row["Individual_ID"] as int?;
                    int?householdId  = row["Household_ID"] as int?;

                    var personKeys = GetPersonKeys(individualId, householdId, includeVisitors: false);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        var pledge = new FinancialPledge();
                        pledge.PersonAliasId          = personKeys.PersonAliasId;
                        pledge.CreatedByPersonAliasId = ImportPersonAliasId;
                        pledge.ModifiedDateTime       = ImportDateTime;
                        pledge.StartDate   = (DateTime)startDate;
                        pledge.EndDate     = (DateTime)endDate;
                        pledge.TotalAmount = (decimal)amount;

                        string frequency = row["Pledge_Frequency_Name"].ToString().ToLower();
                        if (frequency != null)
                        {
                            frequency = frequency.ToLower();
                            if (frequency.Equals("one time") || frequency.Equals("as can"))
                            {
                                pledge.PledgeFrequencyValueId = oneTimePledgeFrequencyId;
                            }
                            else
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies
                                                                .Where(f => f.Value.ToLower().StartsWith(frequency) || f.Description.ToLower().StartsWith(frequency))
                                                                .Select(f => f.Id).FirstOrDefault();
                            }
                        }

                        string fundName = row["Fund_Name"] as string;
                        string subFund  = row["Sub_Fund_Name"] as string;
                        if (fundName != null)
                        {
                            var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) && a.CampusId == null);
                            if (parentAccount == null)
                            {
                                parentAccount = AddAccount(lookupContext, fundName, string.Empty, null, null, null);
                                accountList.Add(parentAccount);
                            }

                            if (subFund != null)
                            {
                                int?campusFundId = null;
                                // assign a campus if the subfund is a campus fund
                                var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode));
                                if (campusFund != null)
                                {
                                    // use full campus name as the subfund
                                    subFund      = campusFund.Name;
                                    campusFundId = campusFund.Id;
                                }

                                // add info to easily find/assign this fund in the view
                                subFund = string.Format("{0} {1}", subFund, fundName);

                                var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund) && c.ParentAccountId == parentAccount.Id);
                                if (childAccount == null)
                                {
                                    // create a child account with a campusId if it was set
                                    childAccount = AddAccount(lookupContext, subFund, string.Empty, campusFundId, parentAccount.Id, null);
                                    accountList.Add(childAccount);
                                }

                                pledge.AccountId = childAccount.Id;
                            }
                            else
                            {
                                pledge.AccountId = parentAccount.Id;
                            }
                        }

                        newPledges.Add(pledge);
                        completed++;
                        if (completed % percentage < 1)
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress(percentComplete, string.Format("{0:N0} pledges imported ({1}% complete).", completed, percentComplete));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SavePledges(newPledges);
                            ReportPartialProgress();
                            newPledges.Clear();
                        }
                    }
                }
            }

            if (newPledges.Any())
            {
                SavePledges(newPledges);
            }

            ReportProgress(100, string.Format("Finished pledge import: {0:N0} pledges imported.", completed));
        }
예제 #20
0
        /// <summary>
        /// Maps the pledge.
        /// </summary>
        /// <param name="queryable">The queryable.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapPledge(CSVInstance csvData)
        {
            var lookupContext   = new RockContext();
            var accountList     = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();
            var importedPledges = new FinancialPledgeService(lookupContext).Queryable().AsNoTracking().ToList();

            var pledgeFrequencies        = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY), lookupContext).DefinedValues;
            int oneTimePledgeFrequencyId = pledgeFrequencies.FirstOrDefault(f => f.Guid == new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME)).Id;

            var newPledges = new List <FinancialPledge>();

            int completed = 0;

            ReportProgress(0, string.Format("Verifying pledge import ({0:N0} already exist).", importedPledges.Count));

            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string   amountKey    = row[TotalPledge];
                decimal? amount       = amountKey.AsType <decimal?>();
                string   startDateKey = row[StartDate];
                DateTime?startDate    = startDateKey.AsType <DateTime?>();
                string   endDateKey   = row[EndDate];
                DateTime?endDate      = endDateKey.AsType <DateTime?>();
                if (amount != null && startDate != null && endDate != null)
                {
                    string individualIdKey = row[IndividualID];
                    int?   individualId    = individualIdKey.AsType <int?>();

                    var personKeys = GetPersonKeys(individualId);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        var pledge = new FinancialPledge();
                        pledge.PersonAliasId          = personKeys.PersonAliasId;
                        pledge.CreatedByPersonAliasId = ImportPersonAliasId;
                        pledge.StartDate   = (DateTime)startDate;
                        pledge.EndDate     = (DateTime)endDate;
                        pledge.TotalAmount = (decimal)amount;

                        string frequency = row[PledgeFrequencyName].ToString().ToLower();
                        if (frequency != null)
                        {
                            frequency = frequency.ToLower();
                            if (frequency.Equals("one time") || frequency.Equals("as can"))
                            {
                                pledge.PledgeFrequencyValueId = oneTimePledgeFrequencyId;
                            }
                            else
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies
                                                                .Where(f => f.Value.ToLower().StartsWith(frequency) || f.Description.ToLower().StartsWith(frequency))
                                                                .Select(f => f.Id).FirstOrDefault();
                            }
                        }

                        string  fundName         = row[FundName] as string;
                        string  subFund          = row[SubFundName] as string;
                        string  fundGLAccount    = row[FundGLAccount] as string;
                        string  subFundGLAccount = row[SubFundGLAccount] as string;
                        string  isFundActiveKey  = row[FundIsActive];
                        Boolean?isFundActive     = isFundActiveKey.AsType <Boolean?>();

                        if (fundName != null)
                        {
                            var parentAccount = accountList.FirstOrDefault(a => a.Name.Equals(fundName) && a.CampusId == null);
                            if (parentAccount == null)
                            {
                                parentAccount = AddAccount(lookupContext, fundName, string.Empty, null, null, isFundActive);
                                accountList.Add(parentAccount);
                            }

                            if (subFund != null)
                            {
                                int?campusFundId = null;
                                // assign a campus if the subfund is a campus fund
                                var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode));
                                if (campusFund != null)
                                {
                                    // use full campus name as the subfund
                                    subFund      = campusFund.Name;
                                    campusFundId = campusFund.Id;
                                }

                                // add info to easily find/assign this fund in the view
                                subFund = string.Format("{0} {1}", subFund, fundName);

                                var childAccount = accountList.FirstOrDefault(c => c.Name.Equals(subFund) && c.ParentAccountId == parentAccount.Id);
                                if (childAccount == null)
                                {
                                    // create a child account with a campusId if it was set
                                    childAccount = AddAccount(lookupContext, subFund, string.Empty, campusFundId, parentAccount.Id, isFundActive);
                                    accountList.Add(childAccount);
                                }

                                pledge.AccountId = childAccount.Id;
                            }
                            else
                            {
                                pledge.AccountId = parentAccount.Id;
                            }
                        }

                        newPledges.Add(pledge);
                        completed++;
                        if (completed % (ReportingNumber * 10) < 1)
                        {
                            ReportProgress(0, string.Format("{0:N0} pledges imported.", completed));
                        }
                        else if (completed % ReportingNumber < 1)
                        {
                            SavePledges(newPledges);
                            ReportPartialProgress();
                            newPledges.Clear();
                        }
                    }
                }
            }

            if (newPledges.Any())
            {
                SavePledges(newPledges);
            }

            ReportProgress(100, string.Format("Finished pledge import: {0:N0} pledges imported.", completed));
            return(completed);
        }
예제 #21
0
파일: Group.cs 프로젝트: treusch/Bulldozer
        /// <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);
        }
예제 #22
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.");
        }
예제 #23
0
파일: Family.cs 프로젝트: timlem/Excavator
        /// <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);
            int familyGroupTypeId = GroupTypeCache.GetFamilyGroupType().Id;

            int numImportedFamilies = ImportedFamilies.Count();

            int homeLocationTypeId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_HOME)).Id;
            int workLocationTypeId = DefinedValueCache.Read(new Guid(Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_WORK)).Id;

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

            string currentFamilyKey = string.Empty;
            int    completed        = 0;

            ReportProgress(0, string.Format("Starting family import ({0:N0} already exist).", numImportedFamilies));

            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                string rowFamilyKey  = row[FamilyId];
                int?   rowFamilyId   = rowFamilyKey.AsType <int?>();
                string rowFamilyName = row[FamilyName];

                if (rowFamilyKey != null && rowFamilyKey != currentFamilyGroup.ForeignKey)
                {
                    currentFamilyGroup = ImportedFamilies.FirstOrDefault(g => g.ForeignKey == rowFamilyKey);
                    if (currentFamilyGroup == null)
                    {
                        currentFamilyGroup                        = new Group();
                        currentFamilyGroup.ForeignKey             = rowFamilyKey;
                        currentFamilyGroup.ForeignId              = rowFamilyId;
                        currentFamilyGroup.Name                   = row[FamilyName];
                        currentFamilyGroup.CreatedByPersonAliasId = ImportPersonAliasId;
                        currentFamilyGroup.GroupTypeId            = familyGroupTypeId;
                        newFamilyList.Add(currentFamilyGroup);
                    }
                    else
                    {
                        lookupContext.Groups.Attach(currentFamilyGroup);
                    }

                    // Set the family campus
                    string campusName = row[Campus];
                    if (!string.IsNullOrWhiteSpace(campusName))
                    {
                        var familyCampus = CampusList.Where(c => c.Name.Equals(campusName, StringComparison.InvariantCultureIgnoreCase) ||
                                                            c.ShortCode.Equals(campusName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        if (familyCampus == null)
                        {
                            familyCampus           = new Campus();
                            familyCampus.IsSystem  = false;
                            familyCampus.Name      = campusName;
                            familyCampus.ShortCode = campusName.RemoveWhitespace();
                            lookupContext.Campuses.Add(familyCampus);
                            lookupContext.SaveChanges(DisableAuditing);
                            CampusList.Add(familyCampus);
                        }

                        currentFamilyGroup.CampusId = familyCampus.Id;
                    }

                    // Add the family addresses since they exist in this file
                    string famAddress  = row[Address];
                    string famAddress2 = row[Address2];
                    string famCity     = row[City];
                    string famState    = row[State];
                    string famZip      = row[Zip];
                    string famCountry  = row[Country];

                    Location primaryAddress = locationService.Get(famAddress, famAddress2, famCity, famState, famZip, famCountry, verifyLocation: false);

                    if (primaryAddress != null)
                    {
                        var primaryLocation = new GroupLocation();
                        primaryLocation.LocationId               = primaryAddress.Id;
                        primaryLocation.IsMailingLocation        = true;
                        primaryLocation.IsMappedLocation         = true;
                        primaryLocation.GroupLocationTypeValueId = homeLocationTypeId;
                        newGroupLocations.Add(primaryLocation, rowFamilyKey);
                    }

                    string famSecondAddress  = row[SecondaryAddress];
                    string famSecondAddress2 = row[SecondaryAddress2];
                    string famSecondCity     = row[SecondaryCity];
                    string famSecondState    = row[SecondaryState];
                    string famSecondZip      = row[SecondaryZip];
                    string famSecondCountry  = row[SecondaryCountry];

                    Location secondaryAddress = locationService.Get(famSecondAddress, famSecondAddress2, famSecondCity, famSecondState, famSecondZip, famSecondCountry, verifyLocation: false);

                    if (secondaryAddress != null)
                    {
                        var secondaryLocation = new GroupLocation();
                        secondaryLocation.LocationId               = secondaryAddress.Id;
                        secondaryLocation.IsMailingLocation        = true;
                        secondaryLocation.IsMappedLocation         = true;
                        secondaryLocation.GroupLocationTypeValueId = workLocationTypeId;
                        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, string.Format("{0:N0} families imported.", completed));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFamilies(newFamilyList, newGroupLocations);
                        ReportPartialProgress();

                        // Reset lookup context
                        lookupContext.SaveChanges();
                        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, string.Format("Finished family import: {0:N0} families added or updated.", completed));
            return(completed);
        }
예제 #24
0
        /// <summary>
        /// Maps the headcount metrics.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private int MapMetrics(IQueryable <Row> tableData, long totalRows = 0)
        {
            // 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 archivedScheduleCategory = GetCategory(lookupContext, ScheduleEntityTypeId, null, "Archived Schedules");

            var scheduleService = new ScheduleService(lookupContext);
            var scheduleMetrics = scheduleService.Queryable().AsNoTracking().Where(s => s.Category.Guid == archivedScheduleCategory.Guid).ToList();

            var allMetrics       = metricService.Queryable().AsNoTracking().ToList();
            var metricCategories = categoryService.Queryable().AsNoTracking()
                                   .Where(c => c.EntityType.Guid == new Guid(Rock.SystemGuid.EntityType.METRICCATEGORY)).ToList();

            var defaultCategoryName = "Metrics";
            var defaultCategory     = metricCategories.FirstOrDefault(c => c.Name == defaultCategoryName);

            if (defaultCategory == null)
            {
                defaultCategory            = GetCategory(lookupContext, MetricCategoryEntityTypeId, null, defaultCategoryName);
                defaultCategory.ForeignKey = string.Format("Category imported {0}", ImportDateTime);
                metricCategories.Add(defaultCategory);
            }

            var    metricValues  = new List <MetricValue>();
            Metric currentMetric = null;

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

            ReportProgress(0, string.Format("Starting metrics import ({0:N0} already exist).", 0));

            foreach (var row in tableData.Where(r => r != null))
            {
                var foreignId      = row["Headcount_ID"] as int?;
                var activityId     = row["Activity_ID"] as int?;
                var rlcId          = row["RLC_ID"] as int?;
                var metricName     = row["RLC_name"] as string;
                var valueDate      = row["Start_Date_Time"] as DateTime?;
                var value          = row["Attendance"] as string;
                var metricNote     = row["Meeting_note"] as string;
                int?metricCampusId = null;

                if (!string.IsNullOrEmpty(metricName) && !string.IsNullOrWhiteSpace(value))
                {
                    var categoryName     = string.Empty;
                    var metricCategoryId = defaultCategory.Id;
                    if (activityId.HasValue)
                    {
                        var activityGroup = ImportedGroups.FirstOrDefault(g => g.ForeignId == activityId);
                        if (activityGroup != null && !string.IsNullOrWhiteSpace(activityGroup.Name))
                        {
                            metricCampusId = metricCampusId ?? GetCampusId(activityGroup.Name);
                            var activityCategory = metricCategories.FirstOrDefault(c => c.Name == activityGroup.Name && c.ParentCategoryId == metricCategoryId);
                            if (activityCategory == null)
                            {
                                activityCategory            = GetCategory(lookupContext, MetricCategoryEntityTypeId, metricCategoryId, activityGroup.Name);
                                activityCategory.ForeignKey = string.Format("Category imported {0}", ImportDateTime);
                                metricCategories.Add(activityCategory);
                            }

                            metricCategoryId = activityCategory.Id;
                        }
                    }

                    if (rlcId.HasValue)
                    {
                        var rlcGroup = ImportedGroups.FirstOrDefault(g => g.ForeignId == rlcId);
                        if (rlcGroup != null && !string.IsNullOrWhiteSpace(rlcGroup.Name))
                        {
                            metricCampusId = metricCampusId ?? GetCampusId(rlcGroup.Name);
                            var rlcCategory = metricCategories.FirstOrDefault(c => c.Name == rlcGroup.Name && c.ParentCategoryId == metricCategoryId);
                            if (rlcCategory == null)
                            {
                                rlcCategory            = GetCategory(lookupContext, MetricCategoryEntityTypeId, metricCategoryId, rlcGroup.Name);
                                rlcCategory.ForeignKey = string.Format("Category imported {0}", ImportDateTime);
                                metricCategories.Add(rlcCategory);
                            }

                            metricCategoryId = rlcCategory.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.ForeignId              = foreignId;
                        currentMetric.ForeignKey             = foreignId.ToStringSafe();

                        currentMetric.MetricPartitions = new List <MetricPartition>();
                        currentMetric.MetricPartitions.Add(new MetricPartition
                        {
                            Label        = "Campus",
                            Metric       = currentMetric,
                            EntityTypeId = CampusEntityTypeId,
                            EntityTypeQualifierColumn = string.Empty,
                            EntityTypeQualifierValue  = string.Empty
                        });

                        currentMetric.MetricPartitions.Add(new MetricPartition
                        {
                            Label        = "Service",
                            Metric       = currentMetric,
                            EntityTypeId = ScheduleEntityTypeId,
                            EntityTypeQualifierColumn = string.Empty,
                            EntityTypeQualifierValue  = string.Empty
                        });

                        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;
                    metricValue.MetricId   = currentMetric.Id;
                    metricValue.XValue     = string.Empty;
                    metricValue.YValue     = value.AsDecimalOrNull();
                    metricValue.ForeignKey = string.Format("Metric Value imported {0}", ImportDateTime);
                    metricValue.Note       = metricNote ?? string.Empty;

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

                        var metricSchedule = scheduleMetrics.FirstOrDefault(s => s.Name == scheduleName);
                        if (metricSchedule == null)
                        {
                            metricSchedule                        = new Schedule();
                            metricSchedule.Name                   = scheduleName;
                            metricSchedule.iCalendarContent       = CreateCalendarContent(date, "WEEKLY", ImportDateTime);
                            metricSchedule.CategoryId             = archivedScheduleCategory.Id;
                            metricSchedule.EffectiveStartDate     = ImportDateTime;
                            metricSchedule.CreatedByPersonAliasId = ImportPersonAliasId;
                            metricSchedule.CreatedDateTime        = ImportDateTime;
                            metricSchedule.ForeignKey             = string.Format("Metric Schedule imported {0}", ImportDateTime);
                            lookupContext.Schedules.Add(metricSchedule);
                            lookupContext.SaveChanges();

                            scheduleMetrics.Add(metricSchedule);
                        }

                        metricValue.MetricValuePartitions.Add(new MetricValuePartition
                        {
                            MetricPartitionId       = metricPartitionScheduleId,
                            EntityId                = metricSchedule.Id,
                            CreatedDateTime         = valueDate,
                            ModifiedDateTime        = valueDate,
                            CreatedByPersonAliasId  = ImportPersonAliasId,
                            ModifiedByPersonAliasId = ImportPersonAliasId
                        });
                    }

                    if (metricCampusId.HasValue && CampusList.Any(c => c.Id == metricCampusId))
                    {
                        var metricPartitionCampusId = currentMetric.MetricPartitions.FirstOrDefault(p => p.Label == "Campus").Id;
                        metricValue.MetricValuePartitions.Add(new MetricValuePartition {
                            MetricPartitionId = metricPartitionCampusId, EntityId = metricCampusId
                        });
                    }

                    metricValues.Add(metricValue);

                    completedItems++;
                    if (completedItems % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, string.Format("{0:N0} metrics imported.", completedItems));
                    }

                    if (completedItems % 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.", completedItems));
            return(completedItems);
        }
예제 #25
0
        /// <summary>
        /// Maps the pledge.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void MapPledge(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext   = new RockContext();
            var accountList     = new FinancialAccountService(lookupContext).Queryable().AsNoTracking().ToList();
            var importedPledges = new FinancialPledgeService(lookupContext).Queryable().AsNoTracking().ToList();

            var pledgeFrequencies        = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY), lookupContext).DefinedValues;
            var oneTimePledgeFrequencyId = pledgeFrequencies.FirstOrDefault(f => f.Guid == new Guid(Rock.SystemGuid.DefinedValue.TRANSACTION_FREQUENCY_ONE_TIME)).Id;

            var newPledges = new List <FinancialPledge>();

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

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

            ReportProgress(0, $"Verifying pledge import ({totalRows:N0} found).");

            foreach (var row in tableData.Where(r => r != null))
            {
                var amount    = row["Total_Pledge"] as decimal?;
                var startDate = row["Start_Date"] as DateTime?;
                var endDate   = row["End_Date"] as DateTime?;
                if (amount.HasValue && startDate.HasValue && endDate.HasValue)
                {
                    var individualId = row["Individual_ID"] as int?;
                    var householdId  = row["Household_ID"] as int?;

                    var personKeys = GetPersonKeys(individualId, householdId, includeVisitors: false);
                    if (personKeys != null && personKeys.PersonAliasId > 0)
                    {
                        var pledge = new FinancialPledge
                        {
                            PersonAliasId          = personKeys.PersonAliasId,
                            CreatedByPersonAliasId = ImportPersonAliasId,
                            ModifiedDateTime       = ImportDateTime,
                            StartDate   = ( DateTime )startDate,
                            EndDate     = ( DateTime )endDate,
                            TotalAmount = ( decimal )amount
                        };

                        var frequency = row["Pledge_Frequency_Name"].ToString();
                        if (!string.IsNullOrWhiteSpace(frequency))
                        {
                            if (frequency.Equals("one time", StringComparison.OrdinalIgnoreCase) || frequency.Equals("as can", StringComparison.OrdinalIgnoreCase))
                            {
                                pledge.PledgeFrequencyValueId = oneTimePledgeFrequencyId;
                            }
                            else
                            {
                                pledge.PledgeFrequencyValueId = pledgeFrequencies
                                                                .Where(f => f.Value.StartsWith(frequency, StringComparison.OrdinalIgnoreCase) || f.Description.StartsWith(frequency, StringComparison.OrdinalIgnoreCase))
                                                                .Select(f => f.Id).FirstOrDefault();
                            }
                        }

                        var fundName = row["Fund_Name"] as string;
                        var subFund  = row["Sub_Fund_Name"] as string;
                        if (!string.IsNullOrWhiteSpace(fundName))
                        {
                            var parentAccount = accountList.FirstOrDefault(a => !a.CampusId.HasValue && a.Name.Equals(fundName.Truncate(50), StringComparison.OrdinalIgnoreCase));
                            if (parentAccount == null)
                            {
                                parentAccount = AddFinancialAccount(lookupContext, fundName, $"{fundName} imported {ImportDateTime}", string.Empty, null, null, null, startDate, fundName.RemoveSpecialCharacters());
                                accountList.Add(parentAccount);
                            }

                            if (!string.IsNullOrWhiteSpace(subFund))
                            {
                                int?campusFundId = null;
                                // assign a campus if the subfund is a campus fund
                                var campusFund = CampusList.FirstOrDefault(c => subFund.StartsWith(c.Name) || subFund.StartsWith(c.ShortCode));
                                if (campusFund != null)
                                {
                                    // use full campus name as the subfund
                                    subFund      = campusFund.Name;
                                    campusFundId = campusFund.Id;
                                }

                                // add info to easily find/assign this fund in the view
                                subFund = $"{subFund} {fundName}";

                                var childAccount = accountList.FirstOrDefault(c => c.ParentAccountId == parentAccount.Id && c.Name.Equals(subFund.Truncate(50), StringComparison.OrdinalIgnoreCase));
                                if (childAccount == null)
                                {
                                    // create a child account with a campusId if it was set
                                    childAccount = AddFinancialAccount(lookupContext, subFund, $"{subFund} imported {ImportDateTime}", string.Empty, campusFundId, parentAccount.Id, null, startDate, subFund.RemoveSpecialCharacters(), accountTypeValueId: parentAccount.AccountTypeValueId);
                                    accountList.Add(childAccount);
                                }

                                pledge.AccountId = childAccount.Id;
                            }
                            else
                            {
                                pledge.AccountId = parentAccount.Id;
                            }
                        }

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

                        if (completedItems % ReportingNumber < 1)
                        {
                            SavePledges(newPledges);
                            ReportPartialProgress();
                            newPledges.Clear();
                        }
                    }
                }
            }

            if (newPledges.Any())
            {
                SavePledges(newPledges);
            }

            ReportProgress(100, $"Finished pledge import: {completedItems:N0} pledges imported.");
        }
예제 #26
0
        /// <summary>
        /// Maps the batch data.
        /// </summary>
        /// <param name="csvData">The table data.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private int MapBatch(CSVInstance csvData)
        {
            var newBatches        = new List <FinancialBatch>();
            var earliestBatchDate = ImportDateTime;

            var completed = 0;

            ReportProgress(0, $"Verifying batch import ({ImportedBatches.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 batchIdKey = row[BatchID];
                var batchId    = batchIdKey.AsType <int?>();
                if (batchId != null && !ImportedBatches.ContainsKey((int)batchId))
                {
                    var batch = new FinancialBatch
                    {
                        CreatedByPersonAliasId = ImportPersonAliasId,
                        ForeignKey             = batchId.ToString(),
                        ForeignId            = batchId,
                        Note                 = string.Empty,
                        Status               = BatchStatus.Closed,
                        AccountingSystemCode = string.Empty
                    };

                    var name = row[BatchName] as string;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        name           = name.Trim();
                        batch.Name     = name.Left(50);
                        batch.CampusId = CampusList.Where(c => name.StartsWith(c.Name) || name.StartsWith(c.ShortCode))
                                         .Select(c => (int?)c.Id).FirstOrDefault();
                    }

                    var batchDate = ParseDateOrDefault(row[BatchDate], null);
                    if (batchDate.HasValue)
                    {
                        batch.BatchStartDateTime = batchDate;
                        batch.BatchEndDateTime   = batchDate;

                        if (earliestBatchDate > batchDate)
                        {
                            earliestBatchDate = (DateTime)batchDate;
                        }
                    }

                    var amountKey = row[BatchAmount];
                    var amount    = amountKey.AsType <decimal?>();
                    if (amount != null)
                    {
                        batch.ControlAmount = amount.HasValue ? amount.Value : new decimal();
                    }

                    newBatches.Add(batch);
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, $"{completed:N0} batches imported.");
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFinancialBatches(newBatches);

                        foreach (var b in newBatches)
                        {
                            if (!ImportedBatches.ContainsKey((int)b.ForeignId))
                            {
                                ImportedBatches.Add((int)b.ForeignId, b.Id);
                            }
                            else
                            {
                                LogException("Duplicate Batch", string.Format("Batch #{0} is a duplicate and will be skipped. Please check the source data.", b.ForeignId));
                            }
                        }

                        newBatches.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            // add a default batch to use with contributions
            if (!ImportedBatches.ContainsKey(0))
            {
                var defaultBatch = new FinancialBatch
                {
                    CreatedDateTime        = ImportDateTime,
                    CreatedByPersonAliasId = ImportPersonAliasId,
                    Status             = BatchStatus.Closed,
                    BatchStartDateTime = earliestBatchDate,
                    Name          = $"Default Batch {ImportDateTime}",
                    ControlAmount = 0.0m,
                    ForeignKey    = "0",
                    ForeignId     = 0
                };

                newBatches.Add(defaultBatch);
            }

            if (newBatches.Any())
            {
                SaveFinancialBatches(newBatches);
                newBatches.ForEach(b => ImportedBatches.Add((int)b.ForeignId, (int?)b.Id));
            }

            ReportProgress(100, $"Finished batch import: {completed:N0} batches imported.");
            return(completed);
        }