protected abstract Task ProcessChunkAsync(ImportDataRequest request, Action <ImportProgressInfo> progressCallback, ICustomerImportPagedDataSource <TCsvMember> dataSource,
                                           ImportErrorsContext errorsContext, ImportProgressInfo importProgress, ICsvCustomerImportReporter importReporter);
Example #2
0
        protected override async Task ProcessChunkAsync(ImportDataRequest request, Action <ImportProgressInfo> progressCallback, ICustomerImportPagedDataSource <ImportableContact> dataSource,
                                                        ImportErrorsContext errorsContext, ImportProgressInfo importProgress, ICsvCustomerImportReporter importReporter)
        {
            var importContacts = dataSource.Items
                                 // expect records that was parsed with errors
                                 .Where(importContact => !errorsContext.ErrorsRows.Contains(importContact.Row))
                                 .ToArray();

            try
            {
                var internalIds = importContacts.Select(x => x.Record?.Id).Distinct()
                                  .Where(x => !string.IsNullOrEmpty(x))
                                  .ToArray();

                var outerIds = importContacts.Select(x => x.Record?.OuterId).Distinct()
                               .Where(x => !string.IsNullOrEmpty(x))
                               .ToArray();

                var existedContacts =
                    (await SearchMembersByIdAndOuterIdAsync(internalIds, outerIds, new[] { nameof(Contact) }, true))
                    .OfType <Contact>().ToArray();

                SetIdToNullForNotExisted(importContacts, existedContacts);

                SetIdToRealForExistedOuterId(importContacts, existedContacts);

                var validationResult = await ValidateAsync(importContacts, importReporter);

                var invalidImportContacts = validationResult.Errors
                                            .Select(x => (x.CustomState as ImportValidationState <ImportableContact>)?.InvalidRecord).Distinct().ToArray();

                importContacts = importContacts.Except(invalidImportContacts).ToArray();

                //reduce existed set after validation
                existedContacts = existedContacts.Where(ec => importContacts.Any(ic =>
                                                                                 ec.Id.EqualsInvariant(ic.Record.Id) ||
                                                                                 !string.IsNullOrEmpty(ec.OuterId) && ec.OuterId.EqualsInvariant(ic.Record.OuterId)))
                                  .ToArray();

                var updateImportContacts = importContacts.Where(x => existedContacts.Any(ec =>
                                                                                         ec.Id.EqualsInvariant(x.Record.Id) ||
                                                                                         (!ec.OuterId.IsNullOrEmpty() && ec.OuterId.EqualsInvariant(x.Record.OuterId)))
                                                                ).ToArray();

                existedContacts = GetReducedExistedByWrongOuterId(updateImportContacts, existedContacts).OfType <Contact>().ToArray();

                var createImportContacts = importContacts.Except(updateImportContacts).ToArray();

                var internalOrgIds = importContacts.Select(x => x.Record?.OrganizationId).Distinct()
                                     .Where(x => !string.IsNullOrEmpty(x)).ToArray();

                var outerOrgIds = importContacts.Select(x => x.Record?.OrganizationOuterId).Distinct()
                                  .Where(x => !string.IsNullOrEmpty(x)).ToArray();

                var existedOrganizations =
                    (await SearchMembersByIdAndOuterIdAsync(internalOrgIds, outerOrgIds,
                                                            new[] { nameof(Organization) })).OfType <Organization>().ToArray();

                var newContacts = CreateNewContacts(createImportContacts, existedOrganizations, request);

                PatchExistedContacts(existedContacts, updateImportContacts, existedOrganizations, request);

                var contactsForSave = newContacts.Union(existedContacts).ToArray();

                await _memberService.SaveChangesAsync(contactsForSave);

                await CreateAccountsForContacts(contactsForSave);

                importProgress.ContactsCreated += newContacts.Length;
                importProgress.ContactsUpdated += existedContacts.Length;
            }
            catch (Exception e)
            {
                HandleError(progressCallback, importProgress, e.Message);
            }
            finally
            {
                importProgress.ProcessedCount = Math.Min(dataSource.CurrentPageNumber * dataSource.PageSize, importProgress.TotalCount);
                importProgress.ErrorCount     = importProgress.ProcessedCount - importProgress.ContactsCreated - importProgress.ContactsUpdated;
            }
        }