public void PublishRecursive(Category category)
        {
            foreach (var channel in _channelService.GetAll())
            {
                var categoryConnectionExists = category.ChannelLinks.Any(link => link.ChannelSystemId.Equals(channel.SystemId));
                if (!categoryConnectionExists)
                {
                    var writeCategory = category.MakeWritableClone();
                    writeCategory.ChannelLinks.Add(new CategoryToChannelLink(channel.SystemId));
                    _categoryService.Update(writeCategory);
                }

                foreach (var productLink in category.ProductLinks)
                {
                    foreach (var variant in _variantService.GetByBaseProduct(productLink.BaseProductSystemId))
                    {
                        var variantConnectionExists = variant.ChannelLinks.Any(link => link.ChannelSystemId.Equals(channel.SystemId));
                        if (!variantConnectionExists)
                        {
                            var writeVariant = variant.MakeWritableClone();
                            writeVariant.ChannelLinks.Add(new VariantToChannelLink(channel.SystemId));
                            _variantService.Update(writeVariant);
                        }
                    }
                }

                foreach (var childCategory in category.GetChildren())
                {
                    PublishRecursive(childCategory);
                }
            }
        }
Exemple #2
0
        private IEnumerable <SelectListItem> GetChannels()
        {
            var channels = _channelService.GetAll().Where(c => c.WebsiteSystemId != null && c.WebsiteSystemId != Guid.Empty);

            return(channels.Select(channel => new SelectListItem
            {
                Text = channel.Localizations.CurrentCulture.Name,
                Value = channel.SystemId.ToString()
            }));
        }
Exemple #3
0
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            RecordService recordService = new RecordService();

            records = new RecordCollection(recordService.GetAll());

            ProgramService programService = new ProgramService();

            programs = new ProgramCollection(programService.GetAll());

            dgridTvRecord.ItemsSource = records.collecion;
            dgridProgram.ItemsSource  = programs.collecion;

            ChannelService channelService = new ChannelService();

            channels = new ChannelCollection(channelService.GetAll());
        }
    /// <summary>
    /// Init campaign drop down
    /// </summary>
    /// <param name="currencyID">CurrencyID</param>
    private void InitWebSiteDropDown(Guid currencyID)
    {
        // Add web sites
        c_webSite.Items.Clear();
        if (ModuleCMS.ExistsInstance)
        {
            var countries  = _countryService.GetAll().Where(x => x.CurrencySystemId == currencyID).Select(c => c.SystemId).ToList();
            var websiteIds = _channelService.GetAll().Where(c => c.WebsiteSystemId != null && c.CountryLinks.Any(x => countries.Contains(x.CountrySystemId))).Select(y => y.WebsiteSystemId.GetValueOrDefault()).Distinct();
            foreach (Website webSite in websiteIds.Select(x => _websiteService.Get(x)))
            {
                ListItem item = new ListItem(webSite.Localizations.CurrentUICulture.Name, webSite.SystemId.ToString());
                c_webSite.Items.Add(item);
            }
        }
        ListItem itemAll = new ListItem(CurrentModule.Strings.GetValue(ModuleStringConstants.ALL_WEB_SITES, FoundationContext.LanguageID, true), Guid.Empty.ToString());

        c_webSite.Items.Insert(0, itemAll);
        c_webSite.SelectedIndex = -1;
        c_webSite.DataBind();
    }
        public override IEnumerable <(CultureInfo, IDocument)> BuildIndexDocuments(IndexQueueItem item)
        {
            var channels = _channelService.GetAll().Where(x => x.ProductLanguageSystemId.HasValue && x.ProductLanguageSystemId.Value != Guid.Empty).ToList();

            var baseProduct = _baseProductService.Get(item.SystemId);

            if (baseProduct == null)
            {
                // Product is removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var productFieldTemplate = _fieldTemplateService.Get <ProductFieldTemplate>(baseProduct.FieldTemplateSystemId);

            if (productFieldTemplate == null)
            {
                // Field template is removed, all products with this template is also removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var displayTemplate = _displayTemplateService.Get <ProductDisplayTemplate>(productFieldTemplate.DisplayTemplateSystemId);

            if (displayTemplate == null)
            {
                // Display template is removed, all products with template that using the display template is also removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var variants = _variantService.GetByBaseProduct(baseProduct.SystemId).ToList();

            if (variants.Count == 0)
            {
                // No variants exists for the BaseProduct, remove any existing document from index
                foreach (var channel in channels.GroupBy(x => x.ProductLanguageSystemId))
                {
                    var cultureInfo = _languageService.Get(channel.First().ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                    if (cultureInfo is null)
                    {
                        continue;
                    }
                    yield return(cultureInfo, RemoveByFieldDocument.Create <ProductDocument, Guid>(x => x.BaseProductSystemId, item.SystemId));
                }
                yield break;
            }

            var productDocuments     = CreateModelsPerChannel(baseProduct, productFieldTemplate, displayTemplate, ref variants);
            var usedVariantSystemIds = productDocuments.SelectMany(x => x.VariantSystemIds).ToHashSet();
            var usedChannelSystemIds = productDocuments.Select(x => x.ChannelSystemId).ToHashSet();

            // Remove all documents for all channel-combinations
            foreach (var channel in channels.Where(x => !usedChannelSystemIds.Contains(x.SystemId)))
            {
                var cultureInfo = _languageService.Get(channel.ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null)
                {
                    continue;
                }

                yield return(cultureInfo, new RemoveDocument(new ProductDocument {
                    ArticleNumber = baseProduct.Id, ChannelSystemId = channel.SystemId
                }));

                foreach (var variant in variants)
                {
                    yield return(cultureInfo, new RemoveDocument(new ProductDocument {
                        ArticleNumber = variant.Id, ChannelSystemId = channel.SystemId
                    }));
                }
            }

            var context = new Context(_contentBuilderService)
            {
                BaseProduct   = baseProduct,
                UsedVariants  = variants.Where(x => usedVariantSystemIds.Contains(x.SystemId)).ToList(),
                Permissions   = _searchPermissionService.GetPermissions(baseProduct),
                FieldTemplate = productFieldTemplate
            };

            context.Prices = BuildPriceData(context);

            foreach (var model in productDocuments)
            {
                var currentVariants = variants.Where(x => model.VariantSystemIds.Contains(x.SystemId)).ToList();
                var channel         = _channelService.Get(model.ChannelSystemId);
                if (channel is null)
                {
                    // Orphaned category link exists, skip to create new index document.
                    continue;
                }

                var cultureInfo = _languageService.Get(channel.ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null || currentVariants.Count == 0)
                {
                    // Channel does not have a culture or we don't have any variants in this channel.
                    continue;
                }

                PopulateProductDocument(model, cultureInfo, currentVariants, context, !displayTemplate.UseVariantUrl);
                yield return(cultureInfo, model);
            }
        }
        private void StatisticsUpdated()
        {
            var articleStatistics = new List <Tuple <Guid, string, decimal> >();

            foreach (var channel in _channelService.GetAll())
            {
                if (channel.WebsiteSystemId != null && channel.MarketSystemId != null)
                {
                    var market = _marketService.Get(channel.MarketSystemId.Value);
                    if (market?.AssortmentSystemId != null)
                    {
                        var categorySystemIds = _categoryService.GetChildCategories(Guid.Empty, market.AssortmentSystemId).SelectMany(x => x.GetChildren(true)).Select(x => x.SystemId).ToList();
                        articleStatistics.AddRange(ModuleECommerce.Instance.Statistics.GetMostSoldArticles(null, channel.WebsiteSystemId.Value, channel.SystemId, categorySystemIds, int.MaxValue, _token)
                                                   .GroupBy(x => x.VariantArticleNumber, StringComparer.OrdinalIgnoreCase)
                                                   .Select(x => new Tuple <Guid, string, decimal>(channel.WebsiteSystemId.Value, x.Key, x.Sum(z => z.Count))));
                    }
                }
            }

            var existingArticleNumbers = _mostSoldDataHolder.GetCurrentArticleNumbers();

            foreach (var item in articleStatistics.GroupBy(x => x.Item2))
            {
                if (!existingArticleNumbers.TryGetValue(item.Key, out HashSet <Guid> existingWebsite))
                {
                    existingWebsite = new HashSet <Guid>();
                }

                var isUpdated = item.Aggregate(false, (current, iitem) =>
                {
                    existingWebsite.Remove(iitem.Item1);
                    decimal old = -1;
                    if (_mostSoldDataHolder.TryGet(iitem.Item2, out IDictionary <Guid, decimal> c))
                    {
                        c.TryGetValue(iitem.Item1, out old);
                    }
                    var r = _mostSoldDataHolder.AddOrUpdate(iitem.Item2, iitem.Item1, iitem.Item3);
                    this.Log().Trace("WebSite: {3} Article: {0} IsUpdated: {2} IsCurrent: {5} OldCount: {4} Count: {1}", iitem.Item2, iitem.Item3, r, iitem.Item1, old, current);
                    return(r | current);
                });

                this.Log().Trace("Article: {0} IsUpdated: {1}", item.Key, isUpdated);
                if (isUpdated)
                {
                    this.Log().Trace("Article: {0} try get", item.Key);
                    var variant = _variantService.Get(item.Key);
                    if (variant != null)
                    {
                        this.Log().Trace("Article: {0} fire event", item.Key);
                        _eventBroker.Publish(new VariantUpdated(variant.SystemId, variant.BaseProductSystemId, new Lazy <Variant>(() => variant)));
                    }
                    else
                    {
                        this.Log().Trace("Article: {0} did not exists", item.Key);
                    }
                }
            }

            foreach (var item in existingArticleNumbers.Where(x => x.Value.Count > 0))
            {
                foreach (var iitem in item.Value)
                {
                    _mostSoldDataHolder.Remove(item.Key, iitem);
                }

                var variant = _variantService.Get(item.Key);
                if (variant != null)
                {
                    this.Log().Trace("Article: {0} fire event", item.Key);
                    _eventBroker.Publish(new VariantUpdated(variant.SystemId, variant.BaseProductSystemId, new Lazy <Variant>(() => variant)));
                }
            }
        }
Exemple #7
0
 public List <ChannelData> GetAll() => Service.GetAll();
Exemple #8
0
        public LitiumQuery(BaseProductService baseProductService,
                           VariantService variantService,
                           ChannelService channelService,
                           MarketService marketService,
                           CountryService countryService,
                           LanguageService languageService,
                           RoutingHelperService routingHelperService,
                           CategoryService categoryService,
                           PageService pageService,
                           WebsiteService websiteService,
                           RouteInfoService routeInfoService,
                           DataService dataService)
        {
            Name = "LitiumQuery";

            Field <WebsiteType>(
                "website",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId"
            }
                    ),
                resolve: (context) =>
            {
                var systemId = context.GetArgument <Guid>("systemId");
                var logoUrl  = websiteService.Get(systemId).Fields
                               .GetValue <Guid?>(AcceleratorWebsiteFieldNameConstants.LogotypeMain).Value
                               .MapTo <Web.Models.ImageModel>().GetUrlToImage(System.Drawing.Size.Empty, new System.Drawing.Size(-1, 50)).Url;
                return(new WebsiteModel()
                {
                    LogoUrl = logoUrl,
                    SystemId = systemId
                });
            }
                );

            Field <GlobalType>(
                "global",
                resolve: (context) =>
            {
                var channel   = channelService.GetAll().First();
                var market    = marketService.Get(channel.MarketSystemId.Value);
                var country   = countryService.Get(channel.CountryLinks.First().CountrySystemId);
                var culture   = languageService.Get(channel.WebsiteLanguageSystemId.Value);
                var uiCulture = languageService.Get(channel.ProductLanguageSystemId.Value);

                return(new GlobalModel()
                {
                    ChannelSystemId = channel.SystemId,
                    WebsiteSystemId = channel.WebsiteSystemId.Value,
                    AssortmentSystemId = market.AssortmentSystemId.Value,
                    CountrySystemId = country.SystemId,
                    CurrencySystemId = country.CurrencySystemId,
                    CurrentCulture = culture.Id,
                    CurrentUICulture = uiCulture.Id,
                });
            }
                );

            Field <CategoryType>(
                "category",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "id of the category, will be override if slug has value"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global"
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "category slug urls"
            }
                    ),
                resolve: context =>
            {
                var categoryId = context.GetArgument <Guid>("systemId");
                var slug       = context.GetArgument <string[]>("slug");
                if (slug != null && slug.Any())
                {
                    var globalModel = context.GetArgument <GlobalModel>("global");
                    return(GetCategoryFromSlug(slug, globalModel, routingHelperService, categoryService));
                }
                return(categoryService.Get(categoryId).MapTo <CategoryModel>());
            }
                );

            FieldAsync <PageInfoCategoryType>(
                "searchCategory",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await CategoryQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <ProductType>(
                "product",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "id of the product"
            },
                    new QueryArgument <StringGraphType> {
                Name = "slug", Description = "Product's slug url"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global"
            }
                    ),
                resolve: context =>
            {
                var systemId    = context.GetArgument <Guid>("systemId");
                var slug        = context.GetArgument <string>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                if (!string.IsNullOrEmpty(slug))
                {
                    systemId = GetProductSystemIdFromSlug(slug, globalModel, routingHelperService);
                }
                // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                using var scope = context.RequestServices.CreateScope();
                return(GetProduct(systemId, scope, baseProductService, variantService, globalModel));
            }
                );

            FieldAsync <PageInfoProductType>(
                "products",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <IdGraphType> {
                Name = "parentCategorySystemId", Description = "The optional parent category system id"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await ProductQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           context.GetArgument <Guid?>("parentCategorySystemId"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <PageType>(
                "page",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = "systemId", Description = "Id of the page. Can be empty GUID, the website's homepage will be returned in that case, where WebsiteSystemId should have value."
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "Page's slugs, will override systemId if available"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "Global context, which is needed to get page from slug"
            }
                    ),
                resolve: context =>
            {
                var slug        = context.GetArgument <string[]>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, null);
                if (slug != null && slug.Any())
                {
                    return(GetPageFromSlug(slug, globalModel, pageService, routingHelperService));
                }

                var systemId = context.GetArgument <Guid?>("systemId");
                if (systemId.HasValue && systemId.Value != Guid.Empty)
                {
                    return(pageService.Get(systemId.Value)?.MapTo <PageModel>());
                }
                return(pageService.GetChildPages(Guid.Empty, globalModel.WebsiteSystemId).FirstOrDefault()?.MapTo <PageModel>());
            }
                );

            FieldAsync <PageInfoPageType>(
                "searchPage",
                arguments: new QueryArguments(
                    new QueryArgument <IntGraphType> {
                Name = "offset"
            },
                    new QueryArgument <IntGraphType> {
                Name = "take"
            },
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <StringGraphType> {
                Name = "query", Description = "The search query"
            }
                    ),
                resolve: async context =>
            {
                return(await PageQuery.SearchAsync(
                           context.GetArgument <GlobalModel>("global"),
                           routeInfoService,
                           context.GetArgument <string>("query") ?? string.Empty,
                           context.GetArgument("take", 8),
                           context.GetArgument("offset", 0),
                           context.RequestServices
                           ));
            }
                );

            Field <ContentType>(
                "content",
                arguments: new QueryArguments(
                    new QueryArgument <GlobalInputType> {
                Name = "global", Description = "The global object"
            },
                    new QueryArgument <ListGraphType <StringGraphType> > {
                Name = "slug", Description = "The slug array"
            }
                    ),
                resolve: context =>
            {
                var slug        = context.GetArgument <string[]>("slug");
                var globalModel = context.GetArgument <GlobalModel>("global");
                routeInfoService.Setup(globalModel, null);

                var systemId = GetProductSystemIdFromSlug(slug[slug.Length - 1], globalModel, routingHelperService);
                if (systemId != Guid.Empty)
                {
                    // Special treatment for scoped services https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#scoped-services-with-a-singleton-schema-lifetime
                    // and make sure it is thread safe https://graphql-dotnet.github.io/docs/getting-started/dependency-injection/#thread-safety-with-scoped-services
                    using var scope = context.RequestServices.CreateScope();
                    return(GetProduct(systemId, scope, baseProductService, variantService, globalModel));
                }

                var category = GetCategoryFromSlug(slug, globalModel, routingHelperService, categoryService);
                if (category != null)
                {
                    return(category);
                }
                return(GetPageFromSlug(slug, globalModel, pageService, routingHelperService));
            }
                );
        }
        private bool ValidateImportForm(DeploymentViewModel.ImportViewModel importForm)
        {
            var isValid = true;

            if (string.IsNullOrWhiteSpace(importForm.PackageName))
            {
                isValid = false;
            }

            if (string.IsNullOrWhiteSpace(importForm.Name))
            {
                ModelState.AddModelError($"ImportForm.{nameof(importForm.Name)}", "accelerator.deployment.validation.required".AsAngularResourceString());
                isValid = false;
            }
            else
            {
                var name = _slugifyService.Slugify(CultureInfo.CurrentCulture, importForm.Name);

                if (_channelService.Get(name) != null)
                {
                    ModelState.AddModelError($"ImportForm.{nameof(importForm.Name)}", "accelerator.deployment.validation.channelexists".AsAngularResourceString());
                    isValid = false;
                }
            }

            var tempDomainName = !string.IsNullOrEmpty(importForm.DomainName) && importForm.DomainName.Contains("://") ? importForm.DomainName : "http://" + importForm.DomainName;

            if (string.IsNullOrWhiteSpace(importForm.DomainName))
            {
                ModelState.AddModelError($"ImportForm.{nameof(importForm.DomainName)}", "accelerator.deployment.validation.required".AsAngularResourceString());
                isValid = false;
            }
            else if (importForm.DomainName.Contains(" "))
            {
                ModelState.AddModelError($"ImportForm.{nameof(importForm.DomainName)}", "accelerator.deployment.validation.space".AsAngularResourceString());
                isValid = false;
            }
            else if (!Uri.TryCreate(tempDomainName, UriKind.RelativeOrAbsolute, out var uri))
            {
                ModelState.AddModelError($"ImportForm.{nameof(importForm.DomainName)}", "general.hostnameisnotvalid".AsAngularResourceString());
                isValid = false;
            }
            else
            {
                var domain  = AcceleratorPackage.ExtractDomainName(importForm.DomainName);
                var urlPath = AcceleratorPackage.ExtractUrlPath(importForm.DomainName).NullIfEmpty();

                if (urlPath?.Contains("/") == true)
                {
                    ModelState.AddModelError($"ImportForm.{nameof(importForm.DomainName)}", "accelerator.deployment.validation.urlpath".AsAngularResourceString());
                    isValid = false;
                }
                else
                {
                    var domainName = _domainNameService.Get(domain);
                    if (domainName != null && _channelService.GetAll().Any(x => x
                                                                           .DomainNameLinks
                                                                           .Any(z => z.DomainNameSystemId == domainName.SystemId && string.Equals(z.UrlPrefix, urlPath, StringComparison.OrdinalIgnoreCase))))
                    {
                        ModelState.AddModelError($"ImportForm.{nameof(importForm.DomainName)}", "accelerator.deployment.validation.domainnameexists".AsAngularResourceString());
                        isValid = false;
                    }
                }
            }

            return(isValid);
        }