/// <summary>
        /// Prepare paged specification attribute option list model
        /// </summary>
        /// <param name="searchModel">Specification attribute option search model</param>
        /// <param name="specificationAttribute">Specification attribute</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the specification attribute option list model
        /// </returns>
        public virtual async Task <SpecificationAttributeOptionListModel> PrepareSpecificationAttributeOptionListModelAsync(
            SpecificationAttributeOptionSearchModel searchModel, SpecificationAttribute specificationAttribute)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (specificationAttribute == null)
            {
                throw new ArgumentNullException(nameof(specificationAttribute));
            }

            //get specification attribute options
            var options = (await _specificationAttributeService
                           .GetSpecificationAttributeOptionsBySpecificationAttributeAsync(specificationAttribute.Id)).ToPagedList(searchModel);

            //prepare list model
            var model = await new SpecificationAttributeOptionListModel().PrepareToGridAsync(searchModel, options, () =>
            {
                return(options.SelectAwait(async option =>
                {
                    //fill in model values from the entity
                    var optionModel = option.ToModel <SpecificationAttributeOptionModel>();

                    //in order to save performance to do not check whether a product is deleted, etc
                    optionModel.NumberOfAssociatedProducts = await _specificationAttributeService
                                                             .GetProductSpecificationAttributeCountAsync(specificationAttributeOptionId: option.Id);

                    return optionModel;
                }));
            });

            return(model);
        }
Example #2
0
        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();
        }
Example #3
0
        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
                );
        }
Example #4
0
        public virtual async Task <IActionResult> GetOptionsByAttributeId(string attributeId)
        {
            //do not make any permission validation here
            //because this method could be used on some other pages (such as product editing)
            //if (!await _permissionService.Authorize(StandardPermissionProvider.ManageAttributes))
            //    return AccessDeniedView();

            //this action method gets called via an ajax request
            if (string.IsNullOrEmpty(attributeId))
            {
                throw new ArgumentNullException(nameof(attributeId));
            }

            var options = await _specificationAttributeService.GetSpecificationAttributeOptionsBySpecificationAttributeAsync(Convert.ToInt32(attributeId));

            var result = (from o in options
                          select new { id = o.Id, name = o.Name }).ToList();

            return(Json(result));
        }
        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");
            //}
        }