Esempio n. 1
0
            private bool DeleteProducts(
                IReadOnlyCollection <ProductCatalog> productCatalogs,
                ICatalogPublisher catalogPublisher)
            {
                Stopwatch watchTotalDelete = Stopwatch.StartNew();
                bool      changesDetected  = false;

                //// 1: delete listings for the catalogs which are no longer exist in AX (were retracted for instance).
                //// This is the one of 2 fastest steps (because we don't need to query CRT for each product to figure out whether it is still there or not)

                DataAccessor dataAccessor = new DataAccessor(this.onlineChannel.RecordId, this.runtime.Configuration.ConnectionString, this.publishingConfig.CRTListingPageSize);
                Stopwatch    watch        = Stopwatch.StartNew();
                Dictionary <string, List <long> > catalogsToBeDeleted = dataAccessor.GetNotExistingCatalogs(productCatalogs);

                watch.Stop();
                this.LogTimingMessage(Resources.Duration_GetNotExistingCatalogs, watch.Elapsed, catalogsToBeDeleted.Count, catalogsToBeDeleted.Values.Count);

                if (catalogsToBeDeleted.Count > 0)
                {
                    watch.Restart();
                    catalogPublisher.OnDeleteProductsByCatalogIdRequested(catalogsToBeDeleted);
                    watch.Stop();
                    this.LogTimingMessage(Resources.Duration_Processor_DeleteListingsByCatalogs, watch.Elapsed);
                }

                watch.Restart();
                dataAccessor.DeleteListingsByCatalogs(catalogsToBeDeleted.SelectMany(c => c.Value));
                watch.Stop();
                this.LogTimingMessage(Resources.Duration_Manager_DeleteListingsByCatalogs, watch.Elapsed);

                // 2. delete listings for languages which are no longer exist on channel, this is another fast operation (in terms of querying CRT).
                watch.Restart();
                Dictionary <string, List <string> > languagesToBeDeleted = dataAccessor.GetNotExistingLanguages(this.ChannelLanguages);

                watch.Stop();
                this.LogTimingMessage(Resources.Duration_GetNotExistingLanguages, watch.Elapsed, languagesToBeDeleted.Keys.Count, languagesToBeDeleted.Values.Count);

                if (languagesToBeDeleted.Count > 0)
                {
                    watch.Restart();
                    catalogPublisher.OnDeleteProductsByLanguageIdRequested(languagesToBeDeleted);
                    watch.Stop();
                    this.LogTimingMessage(Resources.Duration_Processor_DeleteListingsByLanguage, watch.Elapsed);
                }

                if (languagesToBeDeleted.Count > 0)
                {
                    watch.Restart();
                    dataAccessor.DeleteListingsByLanguages(languagesToBeDeleted.SelectMany(c => c.Value));
                    watch.Stop();
                    this.LogTimingMessage(Resources.Duration_Processor_DeleteListingsByLanguages, watch.Elapsed);
                }

                changesDetected |= (catalogsToBeDeleted.Count > 0) || (languagesToBeDeleted.Count > 0);

                if (this.publishingConfig.CheckEveryListingForRemoval)
                {
                    // 3: Finally read all listings left from published listings table and ask CRT whehter the product still available there or not
                    watch.Restart();
                    Dictionary <long, List <ListingIdentity> > catalogs = dataAccessor.LoadAllListingsMap();
                    watch.Stop();
                    int listingsCount = 0;
                    foreach (List <ListingIdentity> list in catalogs.Values)
                    {
                        listingsCount += list.Count;
                    }

                    this.LogTimingMessage(Resources.Duration_LoadListingsMap, watch.Elapsed, listingsCount, catalogs.Keys.Count);

                    // Loop over published listings which are grouped by a catalog
                    foreach (KeyValuePair <long, List <ListingIdentity> > catalog in catalogs)
                    {
                        int bottomIndex = 0;
                        List <ListingIdentity> publishedIds = catalog.Value;

                        // Calling CRT, in a separate pages, to find out whether the products are still available or not.
                        while (bottomIndex < publishedIds.Count)
                        {
                            int topIndex = bottomIndex + this.publishingConfig.CRTListingPageSize - 1;
                            if (topIndex + 1 >= publishedIds.Count)
                            {
                                topIndex = publishedIds.Count - 1;
                            }

                            List <ListingIdentity> currentPagePublishedIds = publishedIds.GetRange(bottomIndex, topIndex + 1 - bottomIndex);
                            int previousBottomIndex = bottomIndex;
                            bottomIndex = topIndex + 1;

                            watch.Restart();
                            System.Collections.ObjectModel.ReadOnlyCollection <ProductExistenceId> crtIds = this.VerifyProductExistence(catalog.Key, ConvertToProductExistenceId(currentPagePublishedIds));
                            watch.Stop();
                            this.LogTimingMessage(Resources.Duration_VerifyProductExistence, watch.Elapsed, currentPagePublishedIds.Count, previousBottomIndex, publishedIds.Count, crtIds.Count);

                            IList <ListingIdentity> idsToBeRemoved = GetIdsToBeRemoved(crtIds, currentPagePublishedIds);
                            changesDetected |= idsToBeRemoved.Any();

                            if (idsToBeRemoved.Count > 0)
                            {
                                watch.Restart();
                                catalogPublisher.OnDeleteIndividualProductsRequested(idsToBeRemoved);
                                watch.Stop();
                                this.LogTimingMessage(Resources.Duration_Processor_DeleteListingsByCompositeIds, watch.Elapsed, idsToBeRemoved.Count);

                                watch.Restart();
                                dataAccessor.DeleteListingsByCompositeIds(catalog.Key, idsToBeRemoved);
                                watch.Stop();
                                this.LogTimingMessage(Resources.Duration_Manager_DeleteListingsByCompositeIds, watch.Elapsed, idsToBeRemoved.Count);
                            }

                            List <ListingPublishStatus> statuses = new List <ListingPublishStatus>();
                            foreach (ListingIdentity id in idsToBeRemoved)
                            {
                                statuses.Add(Listing.CreateStatusSuccessfullyDeleted(this.onlineChannel.RecordId, id.CatalogId, id.ProductId, id.LanguageId));
                            }

                            if (statuses.Count > 0)
                            {
                                this.UpdateListingPublishingStatus(statuses);
                            }
                        }
                    }

                    watchTotalDelete.Stop();
                    this.LogTimingMessage(Resources.Duration_DeleteProducts, watchTotalDelete.Elapsed, changesDetected);
                }

                return(changesDetected);
            }