using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Common; using Nop.Services.Attributes; using Nop.Services.Localization; using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions; using Nop.Web.Areas.Admin.Models.Common; using Nop.Web.Framework.Factories; using Nop.Web.Framework.Models.Extensions; namespace Nop.Web.Areas.Admin.Factories; /// /// Represents the address attribute model factory implementation /// public partial class AddressAttributeModelFactory : IAddressAttributeModelFactory { #region Fields protected readonly IAttributeParser _addressAttributeParser; protected readonly IAttributeService _addressAttributeService; protected readonly ILocalizationService _localizationService; protected readonly ILocalizedModelFactory _localizedModelFactory; #endregion #region Ctor public AddressAttributeModelFactory(IAttributeParser addressAttributeParser, IAttributeService addressAttributeService, ILocalizationService localizationService, ILocalizedModelFactory localizedModelFactory) { _addressAttributeParser = addressAttributeParser; _addressAttributeService = addressAttributeService; _localizationService = localizationService; _localizedModelFactory = localizedModelFactory; } #endregion #region Utilities /// /// Prepare address attribute value search model /// /// Address attribute value search model /// Address attribute /// Address attribute value search model protected virtual AddressAttributeValueSearchModel PrepareAddressAttributeValueSearchModel(AddressAttributeValueSearchModel searchModel, AddressAttribute addressAttribute) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(addressAttribute); searchModel.AddressAttributeId = addressAttribute.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } #endregion #region Methods /// /// Prepare address attribute search model /// /// Address attribute search model /// /// A task that represents the asynchronous operation /// The task result contains the address attribute search model /// public virtual Task PrepareAddressAttributeSearchModelAsync(AddressAttributeSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return Task.FromResult(searchModel); } /// /// Prepare paged address attribute list model /// /// Address attribute search model /// /// A task that represents the asynchronous operation /// The task result contains the address attribute list model /// public virtual async Task PrepareAddressAttributeListModelAsync(AddressAttributeSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get address attributes var addressAttributes = (await _addressAttributeService.GetAllAttributesAsync()).ToPagedList(searchModel); //prepare grid model var model = await new AddressAttributeListModel().PrepareToGridAsync(searchModel, addressAttributes, () => { return addressAttributes.SelectAwait(async attribute => { //fill in model values from the entity var attributeModel = attribute.ToModel(); //fill in additional values (not existing in the entity) attributeModel.AttributeControlTypeName = await _localizationService.GetLocalizedEnumAsync(attribute.AttributeControlType); return attributeModel; }); }); return model; } /// /// Prepare address attribute model /// /// Address attribute model /// Address attribute /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the address attribute model /// public virtual async Task PrepareAddressAttributeModelAsync(AddressAttributeModel model, AddressAttribute addressAttribute, bool excludeProperties = false) { Func localizedModelConfiguration = null; if (addressAttribute != null) { //fill in model values from the entity model ??= addressAttribute.ToModel(); //prepare nested search model PrepareAddressAttributeValueSearchModel(model.AddressAttributeValueSearchModel, addressAttribute); //define localized model configuration action localizedModelConfiguration = async (locale, languageId) => { locale.Name = await _localizationService.GetLocalizedAsync(addressAttribute, entity => entity.Name, languageId, false, false); }; } //prepare localized models if (!excludeProperties) model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration); return model; } /// /// Prepare paged address attribute value list model /// /// Address attribute value search model /// Address attribute /// /// A task that represents the asynchronous operation /// The task result contains the address attribute value list model /// public virtual async Task PrepareAddressAttributeValueListModelAsync(AddressAttributeValueSearchModel searchModel, AddressAttribute addressAttribute) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(addressAttribute); //get address attribute values var addressAttributeValues = (await _addressAttributeService.GetAttributeValuesAsync(addressAttribute.Id)).ToPagedList(searchModel); //prepare grid model var model = new AddressAttributeValueListModel().PrepareToGrid(searchModel, addressAttributeValues, () => { //fill in model values from the entity return addressAttributeValues.Select(value => value.ToModel()); }); return model; } /// /// Prepare address attribute value model /// /// Address attribute value model /// Address attribute /// Address attribute value /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the address attribute value model /// public virtual async Task PrepareAddressAttributeValueModelAsync(AddressAttributeValueModel model, AddressAttribute addressAttribute, AddressAttributeValue addressAttributeValue, bool excludeProperties = false) { ArgumentNullException.ThrowIfNull(addressAttribute); Func localizedModelConfiguration = null; if (addressAttributeValue != null) { //fill in model values from the entity model ??= addressAttributeValue.ToModel(); //define localized model configuration action localizedModelConfiguration = async (locale, languageId) => { locale.Name = await _localizationService.GetLocalizedAsync(addressAttributeValue, entity => entity.Name, languageId, false, false); }; } model.AttributeId = addressAttribute.Id; //prepare localized models if (!excludeProperties) model.Locales = await _localizedModelFactory.PrepareLocalizedModelsAsync(localizedModelConfiguration); return model; } /// /// Prepare custom address attributes /// /// List of address attribute models /// Address /// A task that represents the asynchronous operation public virtual async Task PrepareCustomAddressAttributesAsync(IList models, Address address) { ArgumentNullException.ThrowIfNull(models); var attributes = await _addressAttributeService.GetAllAttributesAsync(); foreach (var attribute in attributes) { var attributeModel = new AddressModel.AddressAttributeModel { Id = attribute.Id, Name = attribute.Name, IsRequired = attribute.IsRequired, AttributeControlType = attribute.AttributeControlType, }; if (attribute.ShouldHaveValues) { //values var attributeValues = await _addressAttributeService.GetAttributeValuesAsync(attribute.Id); foreach (var attributeValue in attributeValues) { var attributeValueModel = new AddressModel.AddressAttributeValueModel { Id = attributeValue.Id, Name = attributeValue.Name, IsPreSelected = attributeValue.IsPreSelected }; attributeModel.Values.Add(attributeValueModel); } } //set already selected attributes var selectedAddressAttributes = address?.CustomAttributes; switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.Checkboxes: { if (!string.IsNullOrEmpty(selectedAddressAttributes)) { //clear default selection foreach (var item in attributeModel.Values) item.IsPreSelected = false; //select new values var selectedValues = await _addressAttributeParser.ParseAttributeValuesAsync(selectedAddressAttributes); foreach (var attributeValue in selectedValues) foreach (var item in attributeModel.Values) if (attributeValue.Id == item.Id) item.IsPreSelected = true; } } break; case AttributeControlType.ReadonlyCheckboxes: { //do nothing //values are already pre-set } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { if (!string.IsNullOrEmpty(selectedAddressAttributes)) { var enteredText = _addressAttributeParser.ParseValues(selectedAddressAttributes, attribute.Id); if (enteredText.Any()) attributeModel.DefaultValue = enteredText[0]; } } break; case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: case AttributeControlType.Datepicker: case AttributeControlType.FileUpload: default: //not supported attribute control types break; } models.Add(attributeModel); } } #endregion }