/// <summary> /// Copy product specifications /// </summary> /// <param name="product">Product</param> /// <param name="productCopy">New product</param> /// <returns>A task that represents the asynchronous operation</returns> protected virtual async Task CopyProductSpecificationsAsync(Product product, Product productCopy) { var allLanguages = await _languageService.GetAllLanguagesAsync(); foreach (var productSpecificationAttribute in await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id)) { var psaCopy = new ProductSpecificationAttribute { ProductId = productCopy.Id, AttributeTypeId = productSpecificationAttribute.AttributeTypeId, SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId, CustomValue = productSpecificationAttribute.CustomValue, AllowFiltering = productSpecificationAttribute.AllowFiltering, ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage, DisplayOrder = productSpecificationAttribute.DisplayOrder }; await _specificationAttributeService.InsertProductSpecificationAttributeAsync(psaCopy); foreach (var language in allLanguages) { var customValue = await _localizationService.GetLocalizedAsync(productSpecificationAttribute, x => x.CustomValue, language.Id, false, false); if (!string.IsNullOrEmpty(customValue)) { await _localizedEntityService.SaveLocalizedValueAsync(psaCopy, x => x.CustomValue, customValue, language.Id); } } } }
private async Task ExportSpecificationsAsync(XmlWriter xml, Product product) { var allProductSpecAttrs = await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id); var features = new List <ProductSpecificationAttribute>(); foreach (var psa in allProductSpecAttrs) { var sao = await _specificationAttributeService.GetSpecificationAttributeOptionByIdAsync(psa.Id); if (sao == null) { continue; } var sa = await _specificationAttributeService.GetSpecificationAttributeByIdAsync(sao.Id); if (sa == null || sa.Name == "Color" || sa.Name == "Category") { continue; } features.Add(psa); } if (!features.Any()) { return; } xml.WriteStartElement(_featuresTag); foreach (var feature in features) { var specAttrId = (await _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttributeAsync(feature.Id))[0].SpecificationAttributeId; var sa = await _specificationAttributeService.GetSpecificationAttributeByIdAsync(specAttrId); xml.WriteStartElement(_featureTag); xml.WriteAttributeString("name", XmlConvert.EncodeName(sa.Name)); xml.WriteValue(XmlSanitize(sa.Name)); xml.WriteEndElement(); } xml.WriteEndElement(); }
public async Task SetSpecificationAttributesAsync(AbcMattressModel model, Product product) { var comfortSpecAttr = (await _specificationAttributeService.GetSpecificationAttributesAsync()) .Where(sa => sa.Name == "Comfort") .FirstOrDefault(); if (comfortSpecAttr == null) { throw new NopException("Unable to find 'Comfort' specification attribute."); } var options = await _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttributeAsync(comfortSpecAttr.Id); var option = options.Where(so => so.Name == model.Comfort) .FirstOrDefault(); if (option == null) { throw new NopException($"Unable to find '{model.Comfort}' " + "specification attribute option for the 'Comfort' " + "specification attribute."); } var productSpecificationAttributes = await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id); var comfortProductSpecAttr = productSpecificationAttributes.Where(psa => psa.SpecificationAttributeOptionId == option.Id) .FirstOrDefault(); // Found the existing product spec. attribute - just skip processing if (comfortProductSpecAttr != null) { return; } // delete any currently existing Comfort specs var optionIds = options.Select(o => o.Id); var existingComfortProductSpecAttributes = productSpecificationAttributes.Where(psa => optionIds.Contains(psa.SpecificationAttributeOptionId)); foreach (var psa in existingComfortProductSpecAttributes) { await _specificationAttributeService.DeleteProductSpecificationAttributeAsync(psa); } // Add new product spec attribute var productSpecAttr = new ProductSpecificationAttribute() { ProductId = product.Id, AttributeType = SpecificationAttributeType.Option, SpecificationAttributeOptionId = option.Id, AllowFiltering = true }; await _specificationAttributeService.InsertProductSpecificationAttributeAsync( productSpecAttr ); }
/// <summary> /// Copy product specifications /// </summary> /// <param name="product">Product</param> /// <param name="productCopy">New product</param> /// <returns>A task that represents the asynchronous operation</returns> protected virtual async Task CopyProductSpecificationsAsync(Product product, Product productCopy) { foreach (var productSpecificationAttribute in await _specificationAttributeService.GetProductSpecificationAttributesAsync(product.Id)) { var psaCopy = new ProductSpecificationAttribute { ProductId = productCopy.Id, AttributeTypeId = productSpecificationAttribute.AttributeTypeId, SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId, CustomValue = productSpecificationAttribute.CustomValue, AllowFiltering = productSpecificationAttribute.AllowFiltering, ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage, DisplayOrder = productSpecificationAttribute.DisplayOrder }; await _specificationAttributeService.InsertProductSpecificationAttributeAsync(psaCopy); } }
protected virtual async Task <ProductSpecificationApiModel> PrepareProductSpecificationAttributeModelAsync(Product product) { var result = new ProductSpecificationApiModel(); if (product == null) { var allProductSpecifications = new ProductSpecificationApiModel(); var specificationCacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.AllProductSpecificationsModelKey, product, await _storeContext.GetCurrentStoreAsync()); allProductSpecifications = await _staticCacheManager.GetAsync(specificationCacheKey, async() => { var productAllSpecificationAttributes = await _specificationAttributeService.GetProductSpecificationAttributesAsync(); foreach (var psa in productAllSpecificationAttributes) { var singleOption = await _specificationAttributeService.GetSpecificationAttributeOptionByIdAsync(psa.SpecificationAttributeOptionId); var checkModel = result.ProductSpecificationAttribute.FirstOrDefault(model => model.Id == singleOption.SpecificationAttributeId || model.Name == singleOption.Name); if (checkModel == null) { var model1 = new ProductSpecificationAttributeApiModel(); var attribute = await _specificationAttributeService.GetSpecificationAttributeByIdAsync(singleOption.SpecificationAttributeId); model1.Id = attribute.Id; model1.Name = await _localizationService.GetLocalizedAsync(attribute, x => x.Name); var options = await _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttributeAsync(attribute.Id); foreach (var option in options) { model1.Values.Add(new ProductSpecificationAttributeValueApiModel { AttributeTypeId = psa.AttributeTypeId, ColorSquaresRgb = option.ColorSquaresRgb, ValueRaw = psa.AttributeType switch { SpecificationAttributeType.Option => WebUtility.HtmlEncode(await _localizationService.GetLocalizedAsync(option, x => x.Name)), SpecificationAttributeType.CustomText => WebUtility.HtmlEncode(await _localizationService.GetLocalizedAsync(psa, x => x.CustomValue)), SpecificationAttributeType.CustomHtmlText => await _localizationService.GetLocalizedAsync(psa, x => x.CustomValue), SpecificationAttributeType.Hyperlink => $"<a href='{psa.CustomValue}' target='_blank'>{psa.CustomValue}</a>", _ => null } });
public async Task ExecuteAsync() { var specificationAttributes = await _specificationAttribute.GetSpecificationAttributesAsync(); var availableOnWeekdayAttribute = specificationAttributes.FirstOrDefault(x => x.Name.Equals("Available On Weekday")); if (availableOnWeekdayAttribute == null) { await _logger.WarningAsync("WeekdayProductRotation: Can't get available on weekday attribute"); throw new Exception("Can't get available on weekday attribute"); } var availableOnWeekdayOptions = await _specificationAttribute.GetSpecificationAttributeOptionsBySpecificationAttributeAsync(availableOnWeekdayAttribute.Id); if (!availableOnWeekdayOptions.Any()) { await _logger.WarningAsync("WeekdayProductRotation: Can't get options"); throw new Exception("Can't get options"); } var storeDateTime = await _dateTimeHelper.ConvertToUserTimeAsync(DateTime.Now); var today3PMLocal = new DateTime(storeDateTime.Year, storeDateTime.Month, storeDateTime.Day, 15, 0, 0); var today3PMUtc = _dateTimeHelper.ConvertToUtcTime(today3PMLocal); //var lastSuccessfulRunUtc = // await _settingService.GetSettingByKeyAsync<DateTime>( // LAST_SUCCESSFUL_RUN_KEY, // loadSharedValueIfNotFound: true); //if(lastSuccessfulRunUtc <= today3PMUtc) //{ DayOfWeek targetWeekdayMenu; if (storeDateTime.Hour > 15) { targetWeekdayMenu = GetNextWeekDay(storeDateTime.DayOfWeek); } else { targetWeekdayMenu = storeDateTime.DayOfWeek; } var publishableSpecificationOptionIds = GetPublishableWeekdaySpecificationOptionIds(availableOnWeekdayOptions, targetWeekdayMenu); await _logger.InformationAsync( $"WeekdayProductRotation: Target weekday = {targetWeekdayMenu}, option ids = {string.Join(',', publishableSpecificationOptionIds)}"); var allProducts = await _productService.SearchProductsAsync(showHidden : true); await _logger.InformationAsync( $"WeekdayProductRotation: Found {allProducts.TotalCount} products, " + $"{allProducts.TotalPages} pages"); int unpublishedCount = 0, publishedCount = 0, untouchedCount = 0; foreach (var product in allProducts) { var productSpecificationAttributes = await _specificationAttribute.GetProductSpecificationAttributesAsync(productId : product.Id); // publish / unpublish product only when it have at least one "Available On Weekday" product specification if (productSpecificationAttributes.Any(x => availableOnWeekdayOptions.Any(y => y.Id == x.SpecificationAttributeOptionId))) { if (productSpecificationAttributes.Any(x => publishableSpecificationOptionIds.Contains(x.SpecificationAttributeOptionId))) { await _logger.InformationAsync( $"WeekdayProductRotation: Publishing product {product.Name}"); product.Published = true; publishedCount++; } else { await _logger.InformationAsync( $"WeekdayProductRotation: Unpublishing product {product.Name}"); product.Published = false; unpublishedCount++; } await _productService.UpdateProductAsync(product); } else { await _logger.InformationAsync( $"WeekdayProductRotation: No weekday specification attribute for product {product.Name}"); untouchedCount++; } } await _settingService.SetSettingAsync <DateTime>( LAST_SUCCESSFUL_RUN_KEY, storeDateTime, clearCache : true); await _logger.InformationAsync($"Published {publishedCount}, " + $"unpublished {unpublishedCount}, " + $"left untouched {untouchedCount} products"); //} //else //{ // await _logger.InformationAsync("WeekdayProductRotation: Skipping for now"); //} }