private async Task <ImporterCargoData> GetCargoData(ImportExecuteContext context)
        {
            if (context.CustomProperties.TryGetValue(CARGO_DATA_KEY, out object value))
            {
                return((ImporterCargoData)value);
            }

            var allowManagingCustomerRoles = await _services.Permissions.AuthorizeAsync(Permissions.Customer.EditRole, _services.WorkContext.CurrentCustomer);

            var affiliateIds = await _db.Affiliates
                               .AsQueryable()
                               .Select(x => x.Id)
                               .ToListAsync(context.CancelToken);

            var customerNumbers = await _db.Customers
                                  .AsQueryable()
                                  .Where(x => !string.IsNullOrEmpty(x.CustomerNumber))
                                  .Select(x => x.CustomerNumber)
                                  .ToListAsync(context.CancelToken);

            var customerRoleIds = await _db.CustomerRoles
                                  .AsNoTracking()
                                  .Where(x => !string.IsNullOrEmpty(x.SystemName))
                                  .Select(x => new { x.Id, x.SystemName })
                                  .ToListAsync(context.CancelToken);

            var allCountries = await _db.Countries
                               .AsNoTracking()
                               .OrderBy(c => c.DisplayOrder)
                               .ThenBy(c => c.Name)
                               .ToListAsync(context.CancelToken);

            var countries = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);

            foreach (var country in allCountries)
            {
                countries[country.TwoLetterIsoCode]   = country.Id;
                countries[country.ThreeLetterIsoCode] = country.Id;
            }

            var stateProvinces = await _db.StateProvinces
                                 .AsNoTracking()
                                 .ToListAsync(context.CancelToken);

            var result = new ImporterCargoData
            {
                AllowManagingCustomerRoles = allowManagingCustomerRoles,
                AffiliateIds    = affiliateIds,
                CustomerNumbers = new HashSet <string>(customerNumbers, StringComparer.OrdinalIgnoreCase),
                CustomerRoleIds = customerRoleIds.ToDictionarySafe(x => x.SystemName, x => x.Id, StringComparer.OrdinalIgnoreCase),
                Countries       = countries,
                StateProvinces  = stateProvinces.ToDictionarySafe(x => new Tuple <int, string>(x.CountryId, x.Abbreviation), x => x.Id)
            };

            context.CustomProperties[CARGO_DATA_KEY] = result;
            return(result);
        }
        private static int?CountryCodeToId(string code, ImporterCargoData cargo)
        {
            if (code.HasValue() && cargo.Countries.TryGetValue(code, out var countryId) && countryId != 0)
            {
                return(countryId);
            }

            return(null);
        }
        private static int?StateAbbreviationToId(int?countryId, string abbreviation, ImporterCargoData cargo)
        {
            if (countryId.HasValue &&
                abbreviation.HasValue() &&
                cargo.StateProvinces.TryGetValue(Tuple.Create(countryId.Value, abbreviation), out var stateId) &&
                stateId != 0)
            {
                return(stateId);
            }

            return(null);
        }
        private static void ImportAddress(
            string fieldPrefix,
            ImportRow <Customer> row,
            ImportExecuteContext context,
            ImporterCargoData cargo)
        {
            // Last name is mandatory for an address to be imported or updated.
            if (!row.HasDataValue(fieldPrefix + "LastName"))
            {
                return;
            }

            Address address = null;

            if (fieldPrefix == "BillingAddress.")
            {
                address = row.Entity.BillingAddress ?? new Address {
                    CreatedOnUtc = context.UtcNow
                };
            }
            else if (fieldPrefix == "ShippingAddress.")
            {
                address = row.Entity.ShippingAddress ?? new Address {
                    CreatedOnUtc = context.UtcNow
                };
            }

            var childRow = new ImportRow <Address>(row.Segmenter, row.DataRow, row.Position);

            childRow.Initialize(address, row.EntityDisplayName);

            childRow.SetProperty(context.Result, fieldPrefix + "Salutation", x => x.Salutation);
            childRow.SetProperty(context.Result, fieldPrefix + "Title", x => x.Title);
            childRow.SetProperty(context.Result, fieldPrefix + "FirstName", x => x.FirstName);
            childRow.SetProperty(context.Result, fieldPrefix + "LastName", x => x.LastName);
            childRow.SetProperty(context.Result, fieldPrefix + "Email", x => x.Email);
            childRow.SetProperty(context.Result, fieldPrefix + "Company", x => x.Company);
            childRow.SetProperty(context.Result, fieldPrefix + "City", x => x.City);
            childRow.SetProperty(context.Result, fieldPrefix + "Address1", x => x.Address1);
            childRow.SetProperty(context.Result, fieldPrefix + "Address2", x => x.Address2);
            childRow.SetProperty(context.Result, fieldPrefix + "ZipPostalCode", x => x.ZipPostalCode);
            childRow.SetProperty(context.Result, fieldPrefix + "PhoneNumber", x => x.PhoneNumber);
            childRow.SetProperty(context.Result, fieldPrefix + "FaxNumber", x => x.FaxNumber);

            childRow.SetProperty(context.Result, fieldPrefix + "CountryId", x => x.CountryId);
            if (childRow.Entity.CountryId == null)
            {
                // Try with country code.
                childRow.SetProperty(context.Result, fieldPrefix + "CountryCode", x => x.CountryId, converter: (val, ci) => CountryCodeToId(val.ToString(), cargo));
            }

            var countryId = childRow.Entity.CountryId;

            if (countryId.HasValue)
            {
                if (row.HasDataValue(fieldPrefix + "StateProvinceId"))
                {
                    childRow.SetProperty(context.Result, fieldPrefix + "StateProvinceId", x => x.StateProvinceId);
                }
                else
                {
                    // Try with state abbreviation.
                    childRow.SetProperty(context.Result, fieldPrefix + "StateAbbreviation", x => x.StateProvinceId, converter: (val, ci) => StateAbbreviationToId(countryId, val.ToString(), cargo));
                }
            }

            if (!childRow.IsDirty)
            {
                // Not one single property could be set. Get out!
                return;
            }

            if (address.Id == 0)
            {
                // Avoid importing two addresses if billing and shipping address are equal.
                var appliedAddress = row.Entity.Addresses.FindAddress(address);
                if (appliedAddress == null)
                {
                    appliedAddress = address;
                    row.Entity.Addresses.Add(appliedAddress);
                }

                // Map address to customer.
                if (fieldPrefix == "BillingAddress.")
                {
                    row.Entity.BillingAddress = appliedAddress;
                }
                else if (fieldPrefix == "ShippingAddress.")
                {
                    row.Entity.ShippingAddress = appliedAddress;
                }
            }
        }