using System.Globalization; using FluentMigrator; using Nop.Core; using Nop.Core.Domain.Common; using Nop.Core.Domain.Configuration; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Directory; using Nop.Core.Domain.Localization; using Nop.Core.Domain.Logging; using Nop.Core.Domain.Messages; using Nop.Core.Domain.ScheduleTasks; using Nop.Core.Domain.Security; using Nop.Core.Domain.Shipping; namespace Nop.Data.Migrations.UpgradeTo460; [NopUpdateMigration("2023-07-26 14:00:00", "4.60", UpdateMigrationType.Data)] public class DataMigration : Migration { protected readonly INopDataProvider _dataProvider; public DataMigration(INopDataProvider dataProvider) { _dataProvider = dataProvider; } /// /// Collect the UP migration expressions /// public override void Up() { //#6789 GenericAttribute was previously named CustomCustomerAttributes and not CustomCustomerAttributesXML var customCustomerAttributeName = "CustomCustomerAttributes"; //#4601 customer attribute values to customer table column values var attributeKeys = new[] { nameof(Customer.FirstName), nameof(Customer.LastName), nameof(Customer.Gender), nameof(Customer.Company), nameof(Customer.StreetAddress), nameof(Customer.StreetAddress2), nameof(Customer.ZipPostalCode), nameof(Customer.City), nameof(Customer.County), nameof(Customer.Phone), nameof(Customer.Fax), nameof(Customer.VatNumber), nameof(Customer.TimeZoneId), nameof(Customer.CountryId), nameof(Customer.StateProvinceId), nameof(Customer.VatNumberStatusId), nameof(Customer.CurrencyId), nameof(Customer.LanguageId), nameof(Customer.TaxDisplayTypeId), nameof(Customer.DateOfBirth), customCustomerAttributeName }; var languages = _dataProvider.GetTable().ToList(); var currencies = _dataProvider.GetTable().ToList(); var customerRole = _dataProvider.GetTable().FirstOrDefault(cr => cr.SystemName == NopCustomerDefaults.RegisteredRoleName); var customerRoleId = customerRole?.Id ?? 0; var query = from c in _dataProvider.GetTable() join crm in _dataProvider.GetTable() on c.Id equals crm.CustomerId where !c.Deleted && (customerRoleId == 0 || crm.CustomerRoleId == customerRoleId) select c; var pageIndex = 0; var pageSize = 500; int castToInt(string value) { return int.TryParse(value, out var result) ? result : default; } string castToString(string value) { return value; } DateTime? castToDateTime(string value) { return DateTime.TryParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateOfBirth) ? dateOfBirth : default; } T getAttributeValue(IList attributes, string key, Func castTo, int maxLength = 1000) { var str = CommonHelper.EnsureMaximumLength(attributes.FirstOrDefault(ga => ga.Key == key)?.Value, maxLength); return castTo(str); } while (true) { var customers = query.ToPagedListAsync(pageIndex++, pageSize).Result; if (!customers.Any()) break; var customerIds = customers.Select(c => c.Id).ToList(); var genericAttributes = _dataProvider.GetTable() .Where(ga => ga.KeyGroup == nameof(Customer) && customerIds.Contains(ga.EntityId) && attributeKeys.Contains(ga.Key)).ToList(); if (!genericAttributes.Any()) continue; foreach (var customer in customers) { var customerAttributes = genericAttributes.Where(ga => ga.EntityId == customer.Id).ToList(); if (!customerAttributes.Any()) continue; customer.FirstName = getAttributeValue(customerAttributes, nameof(Customer.FirstName), castToString); customer.LastName = getAttributeValue(customerAttributes, nameof(Customer.LastName), castToString); customer.Gender = getAttributeValue(customerAttributes, nameof(Customer.Gender), castToString); customer.Company = getAttributeValue(customerAttributes, nameof(Customer.Company), castToString); customer.StreetAddress = getAttributeValue(customerAttributes, nameof(Customer.StreetAddress), castToString); customer.StreetAddress2 = getAttributeValue(customerAttributes, nameof(Customer.StreetAddress2), castToString); customer.ZipPostalCode = getAttributeValue(customerAttributes, nameof(Customer.ZipPostalCode), castToString); customer.City = getAttributeValue(customerAttributes, nameof(Customer.City), castToString); customer.County = getAttributeValue(customerAttributes, nameof(Customer.County), castToString); customer.Phone = getAttributeValue(customerAttributes, nameof(Customer.Phone), castToString); customer.Fax = getAttributeValue(customerAttributes, nameof(Customer.Fax), castToString); customer.VatNumber = getAttributeValue(customerAttributes, nameof(Customer.VatNumber), castToString); customer.TimeZoneId = getAttributeValue(customerAttributes, nameof(Customer.TimeZoneId), castToString); customer.CountryId = getAttributeValue(customerAttributes, nameof(Customer.CountryId), castToInt); customer.StateProvinceId = getAttributeValue(customerAttributes, nameof(Customer.StateProvinceId), castToInt); customer.VatNumberStatusId = getAttributeValue(customerAttributes, nameof(Customer.VatNumberStatusId), castToInt); customer.CurrencyId = currencies.FirstOrDefault(c => c.Id == getAttributeValue(customerAttributes, nameof(Customer.CurrencyId), castToInt))?.Id; customer.LanguageId = languages.FirstOrDefault(l => l.Id == getAttributeValue(customerAttributes, nameof(Customer.LanguageId), castToInt))?.Id; customer.TaxDisplayTypeId = getAttributeValue(customerAttributes, nameof(Customer.TaxDisplayTypeId), castToInt); customer.DateOfBirth = getAttributeValue(customerAttributes, nameof(Customer.DateOfBirth), castToDateTime); //#6789 if (string.IsNullOrEmpty(customer.CustomCustomerAttributesXML)) customer.CustomCustomerAttributesXML = getAttributeValue(customerAttributes, customCustomerAttributeName, castToString, int.MaxValue); } _dataProvider.UpdateEntities(customers); _dataProvider.BulkDeleteEntities(genericAttributes); } //#3777 new activity log types var activityLogTypeTable = _dataProvider.GetTable(); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ImportNewsLetterSubscriptions", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ImportNewsLetterSubscriptions", Enabled = true, Name = "Newsletter subscriptions were imported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportCustomers", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportCustomers", Enabled = true, Name = "Customers were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportCategories", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportCategories", Enabled = true, Name = "Categories were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportManufacturers", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportManufacturers", Enabled = true, Name = "Manufacturers were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportProducts", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportProducts", Enabled = true, Name = "Products were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportOrders", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportOrders", Enabled = true, Name = "Orders were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportStates", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportStates", Enabled = true, Name = "States were exported" } ); if (!activityLogTypeTable.Any(alt => string.Compare(alt.SystemKeyword, "ExportNewsLetterSubscriptions", StringComparison.InvariantCultureIgnoreCase) == 0)) _dataProvider.InsertEntity( new ActivityLogType { SystemKeyword = "ExportNewsLetterSubscriptions", Enabled = true, Name = "Newsletter subscriptions were exported" } ); //#5809 if (!_dataProvider.GetTable().Any(st => string.Compare(st.Type, "Nop.Services.Gdpr.DeleteInactiveCustomersTask, Nop.Services", StringComparison.InvariantCultureIgnoreCase) == 0)) { var _ = _dataProvider.InsertEntity( new ScheduleTask { Name = "Delete inactive customers (GDPR)", //24 hours Seconds = 86400, Type = "Nop.Services.Gdpr.DeleteInactiveCustomersTask, Nop.Services", Enabled = false, StopOnError = false } ); } //#5607 if (!_dataProvider.GetTable().Any(pr => string.Compare(pr.SystemName, "EnableMultiFactorAuthentication", StringComparison.InvariantCultureIgnoreCase) == 0)) { var multifactorAuthenticationPermissionRecord = _dataProvider.InsertEntity( new PermissionRecord { SystemName = "EnableMultiFactorAuthentication", Name = "Security. Enable Multi-factor authentication", Category = "Security" } ); var forceMultifactorAuthentication = _dataProvider.GetTable() .FirstOrDefault(s => string.Compare(s.Name, "MultiFactorAuthenticationSettings.ForceMultifactorAuthentication", StringComparison.InvariantCultureIgnoreCase) == 0 && string.Compare(s.Value, "True", StringComparison.InvariantCultureIgnoreCase) == 0) is not null; var customerRoles = _dataProvider.GetTable(); if (!forceMultifactorAuthentication) customerRoles = customerRoles.Where(cr => cr.SystemName == NopCustomerDefaults.AdministratorsRoleName || cr.SystemName == NopCustomerDefaults.RegisteredRoleName); foreach (var role in customerRoles.ToList()) { _dataProvider.InsertEntity( new PermissionRecordCustomerRoleMapping { CustomerRoleId = role.Id, PermissionRecordId = multifactorAuthenticationPermissionRecord.Id } ); } } var lastEnabledUtc = DateTime.UtcNow; if (!_dataProvider.GetTable().Any(st => string.Compare(st.Type, "Nop.Services.Common.ResetLicenseCheckTask, Nop.Services", StringComparison.InvariantCultureIgnoreCase) == 0)) { _dataProvider.InsertEntity(new ScheduleTask { Name = "ResetLicenseCheckTask", Seconds = 2073600, Type = "Nop.Services.Common.ResetLicenseCheckTask, Nop.Services", Enabled = true, LastEnabledUtc = lastEnabledUtc, StopOnError = false }); } //#3651 if (!_dataProvider.GetTable().Any(mt => string.Compare(mt.Name, MessageTemplateSystemNames.ORDER_PROCESSING_CUSTOMER_NOTIFICATION, StringComparison.InvariantCultureIgnoreCase) == 0)) { var _ = _dataProvider.InsertEntity( new MessageTemplate { Name = MessageTemplateSystemNames.ORDER_PROCESSING_CUSTOMER_NOTIFICATION, Subject = "%Store.Name%. Your order is processing", Body = $"

{Environment.NewLine}%Store.Name%{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}Hello %Order.CustomerFullName%,{Environment.NewLine}
{Environment.NewLine}Your order is processing. Below is the summary of the order.{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}Order Number: %Order.OrderNumber%{Environment.NewLine}
{Environment.NewLine}Order Details: %Order.OrderURLForCustomer%{Environment.NewLine}
{Environment.NewLine}Date Ordered: %Order.CreatedOn%{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}Billing Address{Environment.NewLine}
{Environment.NewLine}%Order.BillingFirstName% %Order.BillingLastName%{Environment.NewLine}
{Environment.NewLine}%Order.BillingAddress1%{Environment.NewLine}
{Environment.NewLine}%Order.BillingAddress2%{Environment.NewLine}
{Environment.NewLine}%Order.BillingCity% %Order.BillingZipPostalCode%{Environment.NewLine}
{Environment.NewLine}%Order.BillingStateProvince% %Order.BillingCountry%{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}%if (%Order.Shippable%) Shipping Address{Environment.NewLine}
{Environment.NewLine}%Order.ShippingFirstName% %Order.ShippingLastName%{Environment.NewLine}
{Environment.NewLine}%Order.ShippingAddress1%{Environment.NewLine}
{Environment.NewLine}%Order.ShippingAddress2%{Environment.NewLine}
{Environment.NewLine}%Order.ShippingCity% %Order.ShippingZipPostalCode%{Environment.NewLine}
{Environment.NewLine}%Order.ShippingStateProvince% %Order.ShippingCountry%{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine}Shipping Method: %Order.ShippingMethod%{Environment.NewLine}
{Environment.NewLine}
{Environment.NewLine} endif% %Order.Product(s)%{Environment.NewLine}

{Environment.NewLine}", IsActive = false, EmailAccountId = _dataProvider.GetTable().FirstOrDefault()?.Id ?? 0 } ); } //#6395 var paRange = _dataProvider.GetTable().FirstOrDefault(par => string.Compare(par.Name, "2 week", StringComparison.InvariantCultureIgnoreCase) == 0); if (paRange is not null) { paRange.Name = "2 weeks"; _dataProvider.UpdateEntity(paRange); } } public override void Down() { //add the downgrade logic if necessary } }