/// <summary>
        /// Gets accessible Category IDs by applying both CAL and Product filtering
        /// </summary>
        /// <param name="pageSize">Results Page Size</param>
        /// <returns>List Category IDs as a List of Guids</returns>
        public List <Guid> GetAccessibleCategoryIds(int pageSize = 5)
        {
            var categoryIds = new List <Guid>();


            var articlesFetch = new Fetch
            {
                Distinct = true,
                Entity   = new FetchEntity
                {
                    Name    = "knowledgearticle",
                    Links   = new List <Link>(),
                    Filters = new List <Filter>
                    {
                        new Filter()
                        {
                            Conditions = new List <Condition>
                            {
                                new Condition("statecode", ConditionOperator.Equal, KnowledgeArticleState.Published),
                                new Condition("isrootarticle", ConditionOperator.Equal, 0),
                                new Condition("isinternal", ConditionOperator.Equal, 0)
                            }
                        }
                    }
                },
                PageSize = pageSize
            };

            // If CAL is enabled, then get the accessible categoryIds by querying Articles joining KnowledgeArticleCategories
            if (this.ContentAccessLevelProvider.IsEnabled())
            {
                // Apply Content Access Level filtering
                this.ContentAccessLevelProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, articlesFetch);
            }

            // If Product Filtering is enabled, then get the accessible categoryIds by querying Articles joining KnowledgeArticleCategories
            if (this.ProductAccessProvider.IsEnabled())
            {
                // Apply Product filtering
                this.ProductAccessProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, articlesFetch);
            }

            // Apply Category-KnowledgeArticle Intersect to determine whether it has any accessible articles on or under it.
            this.ApplyKnowledgeArticleCategoryIntersectToArticleFetch(articlesFetch);

            var categoryIdsCollection = articlesFetch.Execute(this.Portal.ServiceContext as IOrganizationService);

            if (categoryIdsCollection != null && categoryIdsCollection.Entities != null &&
                categoryIdsCollection.Entities.Any())
            {
                categoryIds = categoryIdsCollection.Entities.Select(e => (Guid)e.GetAttributeValue <AliasedValue>("id").Value).ToList();
            }
            if (!categoryIds.Any())
            {
                categoryIds.Add(Guid.Empty);
            }

            return(categoryIds);
        }
Пример #2
0
        private IEnumerable <IKnowledgeArticle> GetArticles(Fetch fetch)
        {
            var context = Dependencies.GetServiceContext();

            var articlesCollection = fetch.Execute(context as IOrganizationService, RequestFlag.AllowStaleData);

            if (articlesCollection == null || !articlesCollection.Entities.Any())
            {
                return(Enumerable.Empty <IKnowledgeArticle>());
            }

            return(new KnowledgeArticleFactory(Dependencies).Create(articlesCollection.Entities));
        }
Пример #3
0
        public SectionViewModel(IMyService service, IMapper mapper, IDialogService dialogService)
        {
            Fetch = ReactiveCommand.CreateFromObservable(() =>
                                                         Observable.FromAsync(service.GetItems)
                                                         .Select(list => list.Select(mapper.Map <ItemViewModel>).ToList()));

            Fetch.ShowExceptions(dialogService).DisposeWith(disposables);

            isBusy = Fetch.IsExecuting.ToProperty(this, vm => vm.IsBusy);
            items  = Fetch.ToProperty(this, vm => vm.Items);

            Fetch.Execute().Catch(Observable.Empty <List <ItemViewModel> >()).Subscribe();
        }
        public SampleSectionViewModel(IMyService service, IMapper mapper, IDialogService dialogService)
        {
            Fetch = ReactiveCommand.CreateFromObservable(() =>
                                                         Observable.FromAsync(service.GetItems)
                                                         .Select(list => list.Select(mapper.Map <ItemViewModel>).ToList()));

            ShowError = ReactiveCommand.CreateFromTask <Exception>(e => dialogService.Show("Error", $"There has been an error while fetching data from the service."));
            Fetch.ThrownExceptions.InvokeCommand(ShowError);

            isBusy = Fetch.IsExecuting.ToProperty(this, vm => vm.IsBusy);
            items  = Fetch.ToProperty(this, vm => vm.Items);

            Fetch.Execute().Catch(Observable.Return(Enumerable.Empty <ItemViewModel>())).Subscribe();
        }
Пример #5
0
        public FeedGroupViewModel(
            Func <Article, FeedItemViewModel> factory,
            INavigationService navigationService,
            IFeedStoreService feedStoreService,
            ISettingManager settingManager,
            Category category)
        {
            _source = new ReactiveList <FeedItemViewModel> {
                ChangeTrackingEnabled = true
            };
            _navigationService = navigationService;
            _feedStoreService  = feedStoreService;
            _settingManager    = settingManager;
            _category          = category;
            _factory           = factory;

            Modify = ReactiveCommand.CreateFromTask(_navigationService.Navigate <ChannelViewModel>);
            Fetch  = ReactiveCommand.CreateFromTask(() => _feedStoreService.Load(_category.Channels));
            Items  = _source.CreateDerivedCollection(x => x, x => !(!ShowRead && x.Read));

            Fetch.Select(articles => articles.Select(_factory))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Do(articles => _source.Clear())
            .Subscribe(_source.AddRange);
            Items.IsEmptyChanged
            .Subscribe(x => IsEmpty = x);

            Fetch.IsExecuting.Skip(1)
            .Subscribe(x => IsLoading = x);
            Fetch.IsExecuting
            .Where(executing => executing)
            .SelectMany(x => _settingManager.Read())
            .Select(settings => settings.Read)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => ShowRead = x);

            Fetch.IsExecuting
            .Where(executing => executing)
            .Select(executing => false)
            .Subscribe(x => HasErrors = x);
            Fetch.ThrownExceptions
            .Select(exception => true)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => HasErrors = x);

            Activator = new ViewModelActivator();
            this.WhenActivated((CompositeDisposable disposables) =>
                               Fetch.Execute().Subscribe());
        }
Пример #6
0
        public MainViewModel()
        {
            var container = new DependencyInjectionContainer();

            container.Configure(c =>
            {
                c.Export <InterfaceNamingConvention>().As <INamingConventionService>();
            });

            container.ProxyNamespace("http://localhost:61207", namespaces: typeof(IMyService).Namespace);

            var service = container.Locate <IMyService>();

            Fetch = ReactiveCommand.CreateFromTask(() => service.GetItems());
            items = Fetch.ToProperty(this, x => x.Items);
            Fetch.Execute().Subscribe();
        }
Пример #7
0
        /// <summary>
        /// Get the Categories by executing the Fetch
        /// </summary>
        /// <param name="fetch">Fetch to execute</param>
        /// <returns>Ienumerable of Category</returns>
        private IEnumerable <ICategory> GetCategories(Fetch fetch)
        {
            var context = this.Dependencies.GetServiceContext();

            var categoryCollection = fetch.Execute(context as IOrganizationService);

            if (categoryCollection == null || !categoryCollection.Entities.Any())
            {
                return(Enumerable.Empty <ICategory>());
            }

            // Localize the Category Labels if the current user's language is not the org's base language
            int lcid;

            if (this.CategoryLocalizationShouldOccur(fetch, out lcid))
            {
                this.LocalizeCategoryLabels(context, lcid, categoryCollection);
            }

            return(new CategoryFactory(this.Dependencies).Create(categoryCollection.Entities));
        }
Пример #8
0
        /// <summary>
        /// Gets the entity field value by guids.
        /// </summary>
        /// <typeparam name="T">type of value in "entityFieldName"-field</typeparam>
        /// <param name="entityGuids">The entity guids.</param>
        /// <param name="entityName">Name of the entity.</param>
        /// <param name="entityFieldName">Name of the entity field.</param>
        /// <param name="entityFieldNameForGuid">The entity field name for unique identifier.</param>
        /// <returns>Dictionary of "entityName"-entity guid and "entityFieldName"-field value</returns>
        protected virtual Dictionary <Guid, T> GetEntityFieldValueByGuids <T>(IEnumerable <Guid> entityGuids, string entityName, string entityFieldName, string entityFieldNameForGuid)
        {
            var entityFieldsFetch = new Fetch
            {
                Distinct = true,
                Entity   = new FetchEntity
                {
                    Name       = entityName,
                    Attributes = new List <FetchAttribute>
                    {
                        new FetchAttribute(entityFieldNameForGuid),
                        new FetchAttribute(entityFieldName)
                    },
                    Filters = new List <Xrm.Services.Query.Filter>()
                    {
                        new Xrm.Services.Query.Filter()
                        {
                            Type       = LogicalOperator.And,
                            Conditions = new List <Condition>()
                            {
                                new Condition
                                {
                                    Attribute = entityFieldNameForGuid,
                                    Operator  = ConditionOperator.In,
                                    Values    = entityGuids.Distinct().Cast <object>().ToList()
                                }
                            }
                        }
                    }
                }
            };
            var portalContext = PortalCrmConfigurationManager.CreatePortalContext();

            using (var serviceContext = portalContext.ServiceContext)
            {
                var entityCollection = entityFieldsFetch.Execute(serviceContext as IOrganizationService);
                return(entityCollection.Entities.ToDictionary(entity => entity.GetAttributeValue <Guid>(entityFieldNameForGuid), entity => entity.GetAttributeValue <T>(entityFieldName)));
            }
        }
Пример #9
0
        public SearchViewModel(
            Func <FeedlyItem, SearchItemViewModel> factory,
            ISearchService searchService)
        {
            Items = new ReactiveList <SearchItemViewModel>();
            this.WhenAnyValue(x => x.SearchQuery)
            .Select(x => x?.Trim())
            .DistinctUntilChanged()
            .Where(x => !string.IsNullOrWhiteSpace(x))
            .Throttle(TimeSpan.FromSeconds(0.8))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => Fetch.Execute());

            Fetch = ReactiveCommand.CreateFromTask(async() =>
            {
                IsLoading      = true;
                var search     = await searchService.SearchAsync(SearchQuery);
                var viewModels = search.Results.Select(factory);
                Items.Clear();
                Items.AddRange(viewModels);
                IsEmpty    = Items.Count == 0;
                IsGreeting = IsLoading = false;
            });
        }
Пример #10
0
        /// <summary>
        /// Gets Related Articles of a Category
        /// </summary>
        /// <returns>IEnumerable of Related Article</returns>
        public IEnumerable <RelatedArticle> SelectRelatedArticles()
        {
            var category = this.Select();

            var relatedArticlesFetch = new Fetch
            {
                Distinct = true,
                Entity   = new FetchEntity
                {
                    Name       = "knowledgearticle",
                    Attributes = new List <FetchAttribute>()
                    {
                        new FetchAttribute("articlepublicnumber"),
                        new FetchAttribute("knowledgearticleid"),
                        new FetchAttribute("title"),
                        new FetchAttribute("keywords"),
                        new FetchAttribute("createdon"),
                        new FetchAttribute("statecode"),
                        new FetchAttribute("statuscode"),
                        new FetchAttribute("isrootarticle"),
                        new FetchAttribute("islatestversion"),
                        new FetchAttribute("isprimary"),
                        new FetchAttribute("knowledgearticleviews")
                    },
                    Filters = new List <Filter>()
                    {
                        new Filter
                        {
                            Type       = LogicalOperator.And,
                            Conditions = new List <Condition>()
                            {
                                new Condition("isrootarticle", ConditionOperator.Equal, 0),
                                new Condition("statecode", ConditionOperator.Equal, 3),
                                new Condition("isinternal", ConditionOperator.Equal, 0)
                            }
                        },
                    },
                    Links = new List <Link>()
                    {
                        new Link
                        {
                            Name          = "knowledgearticlescategories",
                            FromAttribute = "knowledgearticleid",
                            ToAttribute   = "knowledgearticleid",
                            Intersect     = true,
                            Visible       = false,
                            Filters       = new List <Filter>()
                            {
                                new Filter
                                {
                                    Type       = LogicalOperator.And,
                                    Conditions = new List <Condition>()
                                    {
                                        new Condition("categoryid", ConditionOperator.Equal, category.Id)
                                    }
                                }
                            }
                        }
                    }
                }
            };

            var relatedArticles = Enumerable.Empty <RelatedArticle>();

            var serviceContext   = this.Dependencies.GetServiceContext();
            var securityProvider = this.Dependencies.GetSecurityProvider();
            var urlProvider      = this.Dependencies.GetUrlProvider();

            // Apply Content Access Level filtering
            var contentAccessProvider = new ContentAccessLevelProvider();

            contentAccessProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, relatedArticlesFetch);

            // Apply Product filtering
            var productAccessProvider = new ProductAccessProvider();

            productAccessProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, relatedArticlesFetch);

            var relatedArticlesEntityCollection = relatedArticlesFetch.Execute(serviceContext as IOrganizationService);

            if (relatedArticlesEntityCollection != null && relatedArticlesEntityCollection.Entities != null && relatedArticlesEntityCollection.Entities.Any())
            {
                relatedArticles =
                    relatedArticlesEntityCollection.Entities.Where(e => securityProvider.TryAssert(serviceContext, e, CrmEntityRight.Read))
                    .Select(e => new { Title = e.GetAttributeValue <string>("title"), Url = urlProvider.GetUrl(serviceContext, e) })
                    .Where(e => !(string.IsNullOrEmpty(e.Title) || string.IsNullOrEmpty(e.Url)))
                    .Select(e => new RelatedArticle(e.Title, e.Url))
                    .OrderBy(e => e.Title);
            }

            return(relatedArticles);
        }
Пример #11
0
        /// <summary>
        /// Retrieves the list of Products available to the current user
        /// </summary>
        /// <returns>Product entity collection</returns>
        public List <Guid> GetProducts()
        {
            // If anonymous user, return nothing
            if (this.CurrentUserEntityReference == null)
            {
                return(Enumerable.Empty <Guid>().ToList());
            }

            var productFetch = new Fetch
            {
                Distinct = true,
                Entity   = new FetchEntity
                {
                    Name       = "product",
                    Attributes = new List <FetchAttribute>
                    {
                        new FetchAttribute("productid")
                    },
                    Filters = new List <Filter>()
                }
            };

            var associatedToAccountOrContactFilter = new Filter
            {
                Type       = LogicalOperator.Or,
                Conditions = new List <Condition>(),
                Filters    = new List <Filter>()
            };

            // Get alias generator instance to maintain alias names consistency
            // via postfix incrementation
            var linkEntityAliasGenerator = LinkEntityAliasGenerator.CreateInstance();

            // Retrieve Contact to Product relationships and build Entity Permission links
            var contactToProductRelationshipNamesCollection =
                this.GetDelimitedSiteSettingValueCollection(ContactToProductRelationshipNames, ContactToProductFallbackRelationshipName);
            var contactLink = this.BuildLinksAndFilterChain(
                contactToProductRelationshipNamesCollection, productFetch, associatedToAccountOrContactFilter,
                this.CurrentUserEntityReference, null, OwningCustomerType.Contact, linkEntityAliasGenerator);

            productFetch.AddLink(contactLink);

            if (this.ParentCustomerEntityReference != null && this.ParentCustomerEntityReference.LogicalName == "contact")
            {
                // Retrieve parent Contact to Product relationships and build Entity Permission links
                var parentContactLink = this.BuildLinksAndFilterChain(
                    contactToProductRelationshipNamesCollection, productFetch, associatedToAccountOrContactFilter,
                    this.ParentCustomerEntityReference, null, OwningCustomerType.Contact, linkEntityAliasGenerator);
                productFetch.AddLink(parentContactLink);
            }
            else if (this.ParentCustomerEntityReference != null && this.ParentCustomerEntityReference.LogicalName == "account")
            {
                // Retrieve Account to Product relationships and build Entity Permission links
                var accountToProductRelationshipNamesCollection =
                    this.GetDelimitedSiteSettingValueCollection(AccountToProductRelationshipNames, AccountToProductFallbackRelationshipName);
                var accountLink = this.BuildLinksAndFilterChain(
                    accountToProductRelationshipNamesCollection, productFetch, associatedToAccountOrContactFilter,
                    null, this.ParentCustomerEntityReference, OwningCustomerType.Account, linkEntityAliasGenerator);
                productFetch.AddLink(accountLink);
            }

            var accountOrContactNotNullFilter = new Filter
            {
                Type       = LogicalOperator.Or,
                Conditions =
                    associatedToAccountOrContactFilter.Conditions.Select(
                        condition =>
                        new Condition
                {
                    EntityName = condition.EntityName,
                    Attribute  = condition.Attribute,
                    Operator   = ConditionOperator.NotNull
                }).ToList()
            };

            // This is the AND Filter that will ensure state is Active and the Product is joined to either Contact or Account
            productFetch.AddFilter(new Filter
            {
                Type       = LogicalOperator.And,
                Conditions = new List <Condition>
                {
                    new Condition("statecode", ConditionOperator.Equal, 0)
                },
                Filters = new List <Filter>
                {
                    accountOrContactNotNullFilter,
                    associatedToAccountOrContactFilter,
                }
            });

            var productsCollection = productFetch.Execute(this.Portal.ServiceContext as IOrganizationService);

            return(productsCollection.Entities.Select(x => x.Id).ToList());
        }
        private void IncrementKnowledgeArticleReferrerViewCount(int referrer, string domainName)
        {
            var serviceContext = Dependencies.GetServiceContextForWrite();

            Condition[] conditions =
            {
                new Condition("knowledgearticleid", ConditionOperator.Equal,  KnowledgeArticle.Id),
                new Condition("viewdate",           ConditionOperator.Today),
                new Condition("adx_referrer",       ConditionOperator.Equal,  referrer)
            };

            var list = conditions.ToList();

            if (!string.IsNullOrEmpty(domainName))
            {
                list.Add(new Condition("adx_domainname", ConditionOperator.Equal, domainName));
            }
            var kbViewsfetch = new Fetch
            {
                Distinct = true,
                Entity   = new FetchEntity
                {
                    Name       = "knowledgearticleviews",
                    Attributes = new List <FetchAttribute>
                    {
                        new FetchAttribute("knowledgearticleviewsid"),
                        new FetchAttribute("knowledgearticleview"),
                    },
                    Filters = new[]
                    {
                        new Filter
                        {
                            Type       = LogicalOperator.And,
                            Conditions = list
                        }
                    },
                }
            };

            var kbViewsEntity = kbViewsfetch.Execute(serviceContext as IOrganizationService, RequestFlag.AllowStaleData).Entities.FirstOrDefault();


            if (kbViewsEntity == null)
            {
                var knowledgeArticleView = new Entity("knowledgearticleviews")
                {
                    Id = Guid.NewGuid()
                };
                knowledgeArticleView["knowledgearticleid"]   = KnowledgeArticle;
                knowledgeArticleView["viewdate"]             = DateTime.Now;
                knowledgeArticleView["adx_referrer"]         = new OptionSetValue(referrer);
                knowledgeArticleView["location"]             = new OptionSetValue(KnowledgeArticleViewCountWebLocation);
                knowledgeArticleView["knowledgearticleview"] = 1;
                knowledgeArticleView["adx_domainname"]       = string.IsNullOrEmpty(domainName) ? null : domainName;

                serviceContext.AddObject(knowledgeArticleView);
                serviceContext.SaveChanges();
            }
            else
            {
                var updateKnowledgeArticleView = new Entity("knowledgearticleviews")
                {
                    Id = kbViewsEntity.Id
                };
                updateKnowledgeArticleView["viewdate"]             = DateTime.Now;
                updateKnowledgeArticleView["knowledgearticleview"] = (int)kbViewsEntity.Attributes["knowledgearticleview"] + 1;

                var updateServiceContext = Dependencies.GetServiceContextForWrite();

                if (!updateServiceContext.IsAttached(updateKnowledgeArticleView))
                {
                    updateServiceContext.Attach(updateKnowledgeArticleView);
                }

                updateServiceContext.UpdateObject(updateKnowledgeArticleView);
                updateServiceContext.SaveChanges();
            }
        }