public DataExporterContext(DataExportRequest request, bool isPreview, CancellationToken cancellationToken) { Request = request; IsPreview = isPreview; CancellationToken = cancellationToken; FolderContent = request.Profile.GetExportFolder(true, true); Filter = Deserialize <ExportFilter>(request.Profile.Filtering) ?? new(); Projection = Deserialize <ExportProjection>(request.Profile.Projection) ?? new(); if (request.Profile.Projection.IsEmpty()) { Projection.DescriptionMergingId = (int)ExportDescriptionMerging.Description; } Result = new DataExportResult { FileFolder = IsFileBasedExport ? FolderContent : null }; ExecuteContext = new ExportExecuteContext(Result, FolderContent, CancellationToken) { Filter = Filter, Projection = Projection, ProfileId = request.Profile.Id }; if (!IsPreview) { ExecuteContext.ProgressValueSetter = Request.ProgressValueSetter; } }
protected override void Export(ExportExecuteContext context) { var ignored = 0; var categoryIds = context.CustomProperties["CategoryIds"] as HashSet <int>; using (var writer = XmlWriter.Create(context.DataStream, ShopConnectorService.DefaultSettings)) { var helper = new ExportXmlHelper(writer, true); writer.WriteStartElement("Content"); writer.WriteStartElement("Categories"); writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == DataExchangeAbortion.None && context.DataSegmenter.ReadNextSegment()) { var segment = context.DataSegmenter.CurrentSegment; foreach (dynamic category in segment) { if (context.Abort != DataExchangeAbortion.None) { break; } Category entity = category.Entity; try { if (categoryIds != null && !categoryIds.Contains(entity.Id)) { ++ignored; } else { helper.WriteCategory(category, "Category"); ++context.RecordsSucceeded; } } catch (OutOfMemoryException) { context.Abort = DataExchangeAbortion.Hard; throw; } catch (Exception ex) { context.RecordException(ex, entity.Id); } } } writer.WriteElementString("Success", context.RecordsSucceeded.ToString()); writer.WriteElementString("Failure", context.RecordsFailed.ToString()); writer.WriteElementString("TotalRecords", (context.DataSegmenter.TotalRecords - ignored).ToString()); writer.WriteEndElement(); // Categories writer.WriteEndElement(); // Content } }
public DataExporterContext( DataExportRequest request, CancellationToken cancellationToken, bool isPreview = false) { Request = request; CancellationToken = cancellationToken; Filter = XmlHelper.Deserialize <ExportFilter>(request.Profile.Filtering); Projection = XmlHelper.Deserialize <ExportProjection>(request.Profile.Projection); IsPreview = isPreview; if (request.Profile.Projection.IsEmpty()) { Projection.DescriptionMergingId = (int)ExportDescriptionMerging.Description; } FolderContent = request.Profile.GetExportFolder(true, true); DeliveryTimes = new Dictionary <int, DeliveryTime>(); QuantityUnits = new Dictionary <int, QuantityUnit>(); Stores = new Dictionary <int, Store>(); Languages = new Dictionary <int, Language>(); Countries = new Dictionary <int, Country>(); ProductTemplates = new Dictionary <int, string>(); CategoryTemplates = new Dictionary <int, string>(); NewsletterSubscriptions = new HashSet <string>(); Translations = new Dictionary <string, LocalizedPropertyCollection>(); TranslationsPerPage = new Dictionary <string, LocalizedPropertyCollection>(); UrlRecords = new Dictionary <string, UrlRecordCollection>(); UrlRecordsPerPage = new Dictionary <string, UrlRecordCollection>(); StatsPerStore = new Dictionary <int, RecordStats>(); EntityIdsLoaded = new List <int>(); EntityIdsPerSegment = new HashSet <int>(); Result = new DataExportResult { FileFolder = IsFileBasedExport ? FolderContent : null }; ExecuteContext = new ExportExecuteContext(Result, CancellationToken, FolderContent); ExecuteContext.Filter = Filter; ExecuteContext.Projection = Projection; ExecuteContext.ProfileId = request.Profile.Id; if (!IsPreview) { ExecuteContext.ProgressValueSetter = Request.ProgressValueSetter; } }
public DataExporterContext( DataExportRequest request, CancellationToken cancellationToken, bool isPreview = false) { Request = request; CancellationToken = cancellationToken; Filter = XmlHelper.Deserialize <ExportFilter>(request.Profile.Filtering); Projection = XmlHelper.Deserialize <ExportProjection>(request.Profile.Projection); IsPreview = isPreview; FolderContent = request.Profile.GetExportFolder(true, true); Categories = new Dictionary <int, Category>(); CategoryPathes = new Dictionary <int, string>(); DeliveryTimes = new Dictionary <int, DeliveryTime>(); QuantityUnits = new Dictionary <int, QuantityUnit>(); Stores = new Dictionary <int, Store>(); Languages = new Dictionary <int, Language>(); Countries = new Dictionary <int, Country>(); ProductTemplates = new Dictionary <int, string>(); CategoryTemplates = new Dictionary <int, string>(); NewsletterSubscriptions = new HashSet <string>(); RecordsPerStore = new Dictionary <int, int>(); EntityIdsLoaded = new List <int>(); EntityIdsPerSegment = new List <int>(); Result = new DataExportResult { FileFolder = (IsFileBasedExport ? FolderContent : null) }; ExecuteContext = new ExportExecuteContext(Result, CancellationToken, FolderContent); ExecuteContext.Projection = XmlHelper.Deserialize <ExportProjection>(request.Profile.Projection); if (!IsPreview) { ExecuteContext.ProgressValueSetter = Request.ProgressValueSetter; } }
protected override void Export(ExportExecuteContext context) { Currency currency = context.Currency.Entity; var languageId = context.Projection.LanguageId ?? 0; var dateFormat = "yyyy-MM-ddTHH:mmZ"; var defaultCondition = "new"; var defaultAvailability = "in stock"; var measureWeight = GetBaseMeasureWeight(); var config = (context.ConfigurationData as ProfileConfigurationModel) ?? new ProfileConfigurationModel(); if (config.Condition.IsCaseInsensitiveEqual(Unspecified)) { defaultCondition = string.Empty; } else if (config.Condition.HasValue()) { defaultCondition = config.Condition; } if (config.Availability.IsCaseInsensitiveEqual(Unspecified)) { defaultAvailability = string.Empty; } else if (config.Availability.HasValue()) { defaultAvailability = config.Availability; } using (var writer = XmlWriter.Create(context.DataStream, ExportXmlHelper.DefaultSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "2.0"); writer.WriteAttributeString("xmlns", "g", null, _googleNamespace); writer.WriteStartElement("channel"); writer.WriteElementString("title", "{0} - Feed for Google Merchant Center".FormatInvariant((string)context.Store.Name)); writer.WriteElementString("link", "http://base.google.com/base/"); writer.WriteElementString("description", "Information about products"); while (context.Abort == DataExchangeAbortion.None && context.DataSegmenter.ReadNextSegment()) { var segment = context.DataSegmenter.CurrentSegment; int[] productIds = segment.Select(x => (int)((dynamic)x).Id).ToArray(); var googleProducts = _googleFeedService.GetGoogleProductRecords(productIds).ToDictionarySafe(x => x.ProductId); foreach (dynamic product in segment) { if (context.Abort != DataExchangeAbortion.None) { break; } Product entity = product.Entity; var gmc = googleProducts.Get(entity.Id); if (gmc != null && !gmc.Export) { continue; } writer.WriteStartElement("item"); try { string category = (gmc == null ? null : gmc.Taxonomy); string productType = product._CategoryPath; var price = (decimal)product.Price; var uniqueId = (string)product._UniqueId; var isParent = (bool)product._IsParent; string brand = product._Brand; string gtin = product.Gtin; string mpn = product.ManufacturerPartNumber; var availability = defaultAvailability; List <dynamic> productPictures = product.ProductPictures; var pictureUrls = productPictures .Select(x => (string)x.Picture._FullSizeImageUrl) .Where(x => x.HasValue()) .ToList(); var attributeValues = !isParent && product._AttributeCombinationValues != null ? ((ICollection <ProductVariantAttributeValue>)product._AttributeCombinationValues).ToMultimap(x => x.ProductVariantAttribute.ProductAttributeId, x => x) : new Multimap <int, ProductVariantAttributeValue>(); var specialPrice = product._FutureSpecialPrice as decimal?; if (!specialPrice.HasValue) { specialPrice = product._SpecialPrice; } if (category.IsEmpty()) { category = config.DefaultGoogleCategory; } if (category.IsEmpty()) { context.Log.Error(T("Plugins.Feed.Froogle.MissingDefaultCategory")); } if (entity.ManageInventoryMethod == ManageInventoryMethod.ManageStock && entity.StockQuantity <= 0) { if (entity.BackorderMode == BackorderMode.NoBackorders) { availability = "out of stock"; } else if (entity.BackorderMode == BackorderMode.AllowQtyBelow0 || entity.BackorderMode == BackorderMode.AllowQtyBelow0AndNotifyCustomer) { availability = entity.AvailableForPreOrder ? "preorder" : "out of stock"; } } WriteString(writer, "id", uniqueId); writer.WriteStartElement("title"); writer.WriteCData(((string)product.Name).Truncate(70).RemoveInvalidXmlChars()); writer.WriteEndElement(); writer.WriteStartElement("description"); writer.WriteCData(((string)product.FullDescription).RemoveInvalidXmlChars()); writer.WriteEndElement(); writer.WriteStartElement("g", "google_product_category", _googleNamespace); writer.WriteCData(category.RemoveInvalidXmlChars()); writer.WriteFullEndElement(); if (productType.HasValue()) { writer.WriteStartElement("g", "product_type", _googleNamespace); writer.WriteCData(productType.RemoveInvalidXmlChars()); writer.WriteFullEndElement(); } writer.WriteElementString("link", (string)product._DetailUrl); if (pictureUrls.Any()) { WriteString(writer, "image_link", pictureUrls.First()); if (config.AdditionalImages) { var imageCount = 0; foreach (var url in pictureUrls.Skip(1)) { if (++imageCount <= 10) { WriteString(writer, "additional_image_link", url); } } } } var condition = GetAttributeValue(attributeValues, "condition", languageId, null, defaultCondition); WriteString(writer, "condition", condition); WriteString(writer, "availability", availability); if (availability == "preorder" && entity.AvailableStartDateTimeUtc.HasValue && entity.AvailableStartDateTimeUtc.Value > DateTime.UtcNow) { var availabilityDate = entity.AvailableStartDateTimeUtc.Value.ToString(dateFormat); WriteString(writer, "availability_date", availabilityDate); } if (config.SpecialPrice && specialPrice.HasValue) { WriteString(writer, "sale_price", string.Concat(specialPrice.Value.FormatInvariant(), " ", currency.CurrencyCode)); if (entity.SpecialPriceStartDateTimeUtc.HasValue && entity.SpecialPriceEndDateTimeUtc.HasValue) { var specialPriceDate = "{0}/{1}".FormatInvariant( entity.SpecialPriceStartDateTimeUtc.Value.ToString(dateFormat), entity.SpecialPriceEndDateTimeUtc.Value.ToString(dateFormat)); WriteString(writer, "sale_price_effective_date", specialPriceDate); } price = (product._RegularPrice as decimal?) ?? price; } WriteString(writer, "price", string.Concat(price.FormatInvariant(), " ", currency.CurrencyCode)); WriteString(writer, "gtin", gtin); WriteString(writer, "brand", brand); WriteString(writer, "mpn", mpn); var identifierExists = brand.HasValue() && (gtin.HasValue() || mpn.HasValue()); WriteString(writer, "identifier_exists", identifierExists ? "yes" : "no"); var gender = GetAttributeValue(attributeValues, "gender", languageId, gmc?.Gender, config.Gender); WriteString(writer, "gender", gender); var ageGroup = GetAttributeValue(attributeValues, "age_group", languageId, gmc?.AgeGroup, config.AgeGroup); WriteString(writer, "age_group", ageGroup); var color = GetAttributeValue(attributeValues, "color", languageId, gmc?.Color, config.Color); WriteString(writer, "color", color); var size = GetAttributeValue(attributeValues, "size", languageId, gmc?.Size, config.Size); WriteString(writer, "size", size); var material = GetAttributeValue(attributeValues, "material", languageId, gmc?.Material, config.Material); WriteString(writer, "material", material); var pattern = GetAttributeValue(attributeValues, "pattern", languageId, gmc?.Pattern, config.Pattern); WriteString(writer, "pattern", pattern); var itemGroupId = gmc != null && gmc.ItemGroupId.HasValue() ? gmc.ItemGroupId : string.Empty; if (itemGroupId.HasValue()) { WriteString(writer, "item_group_id", itemGroupId); } if (config.ExpirationDays > 0) { WriteString(writer, "expiration_date", DateTime.UtcNow.AddDays(config.ExpirationDays).ToString("yyyy-MM-dd")); } if (config.ExportShipping) { var weight = string.Concat(((decimal)product.Weight).FormatInvariant(), " ", measureWeight); WriteString(writer, "shipping_weight", weight); } if (config.ExportBasePrice && entity.BasePriceHasValue) { var measureUnit = BasePriceUnits((string)product.BasePriceMeasureUnit); if (BasePriceSupported(entity.BasePriceBaseAmount ?? 0, measureUnit)) { var basePriceMeasure = "{0} {1}".FormatInvariant((entity.BasePriceAmount ?? decimal.Zero).FormatInvariant(), measureUnit); var basePriceBaseMeasure = "{0} {1}".FormatInvariant(entity.BasePriceBaseAmount ?? 1, measureUnit); WriteString(writer, "unit_pricing_measure", basePriceMeasure); WriteString(writer, "unit_pricing_base_measure", basePriceBaseMeasure); } } if (gmc != null) { WriteString(writer, "multipack", gmc.Multipack > 1 ? gmc.Multipack.ToString() : null); WriteString(writer, "is_bundle", gmc.IsBundle.HasValue ? (gmc.IsBundle.Value ? "yes" : "no") : null); WriteString(writer, "adult", gmc.IsAdult.HasValue ? (gmc.IsAdult.Value ? "yes" : "no") : null); WriteString(writer, "energy_efficiency_class", gmc.EnergyEfficiencyClass.HasValue() ? gmc.EnergyEfficiencyClass : null); } var customLabel0 = GetAttributeValue(attributeValues, "custom_label_0", languageId, gmc?.CustomLabel0, null); var customLabel1 = GetAttributeValue(attributeValues, "custom_label_1", languageId, gmc?.CustomLabel1, null); var customLabel2 = GetAttributeValue(attributeValues, "custom_label_2", languageId, gmc?.CustomLabel2, null); var customLabel3 = GetAttributeValue(attributeValues, "custom_label_3", languageId, gmc?.CustomLabel3, null); var customLabel4 = GetAttributeValue(attributeValues, "custom_label_4", languageId, gmc?.CustomLabel4, null); ++context.RecordsSucceeded; } catch (Exception exception) { context.RecordException(exception, entity.Id); } writer.WriteEndElement(); // item } } writer.WriteEndElement(); // channel writer.WriteEndElement(); // rss writer.WriteEndDocument(); } }
protected override Task ExportAsync(ExportExecuteContext context, CancellationToken cancelToken) => throw new NotImplementedException();
protected override void Export(ExportExecuteContext context) { dynamic currency = context.Currency; string measureWeightSystemKey = ""; var dateFormat = "yyyy-MM-ddTHH:mmZ"; var measureWeight = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId); if (measureWeight != null) { measureWeightSystemKey = measureWeight.SystemKeyword; } var config = (context.ConfigurationData as ProfileConfigurationModel) ?? new ProfileConfigurationModel(); using (var writer = XmlWriter.Create(context.DataStream, ExportXmlHelper.DefaultSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "2.0"); writer.WriteAttributeString("xmlns", "g", null, _googleNamespace); writer.WriteStartElement("channel"); writer.WriteElementString("title", "{0} - Feed for Google Merchant Center".FormatInvariant((string)context.Store.Name)); writer.WriteElementString("link", "http://base.google.com/base/"); writer.WriteElementString("description", "Information about products"); while (context.Abort == DataExchangeAbortion.None && context.DataSegmenter.ReadNextSegment()) { var segment = context.DataSegmenter.CurrentSegment; int[] productIds = segment.Select(x => (int)((dynamic)x).Id).ToArray(); var googleProducts = _googleFeedService.GetGoogleProductRecords(productIds); foreach (dynamic product in segment) { if (context.Abort != DataExchangeAbortion.None) { break; } Product entity = product.Entity; var gmc = googleProducts.FirstOrDefault(x => x.ProductId == entity.Id); if (gmc != null && !gmc.Export) { continue; } writer.WriteStartElement("item"); try { string category = (gmc == null ? null : gmc.Taxonomy); string productType = product._CategoryPath; string mainImageUrl = product._MainPictureUrl; var futureSpecialPrice = product._FutureSpecialPrice as decimal?; var price = (decimal)product.Price; string brand = product._Brand; string gtin = product.Gtin; string mpn = product.ManufacturerPartNumber; string condition = "new"; string availability = "in stock"; if (category.IsEmpty()) { category = config.DefaultGoogleCategory; } if (category.IsEmpty()) { context.Log.Error(T("Plugins.Feed.Froogle.MissingDefaultCategory")); } if (config.Condition.IsCaseInsensitiveEqual(Unspecified)) { condition = ""; } else if (config.Condition.HasValue()) { condition = config.Condition; } if (config.Availability.IsCaseInsensitiveEqual(Unspecified)) { availability = ""; } else if (config.Availability.HasValue()) { availability = config.Availability; } else { if (entity.ManageInventoryMethod == ManageInventoryMethod.ManageStock && entity.StockQuantity <= 0) { if (entity.BackorderMode == BackorderMode.NoBackorders) { availability = "out of stock"; } else if (entity.BackorderMode == BackorderMode.AllowQtyBelow0 || entity.BackorderMode == BackorderMode.AllowQtyBelow0AndNotifyCustomer) { availability = (entity.AvailableForPreOrder ? "preorder" : "out of stock"); } } } writer.WriteElementString("g", "id", _googleNamespace, entity.Id.ToString()); writer.WriteStartElement("title"); writer.WriteCData(((string)product.Name).Truncate(70).RemoveInvalidXmlChars()); writer.WriteEndElement(); writer.WriteStartElement("description"); writer.WriteCData(((string)product.FullDescription).RemoveInvalidXmlChars()); writer.WriteEndElement(); writer.WriteStartElement("g", "google_product_category", _googleNamespace); writer.WriteCData(category.RemoveInvalidXmlChars()); writer.WriteFullEndElement(); if (productType.HasValue()) { writer.WriteStartElement("g", "product_type", _googleNamespace); writer.WriteCData(productType.RemoveInvalidXmlChars()); writer.WriteFullEndElement(); } writer.WriteElementString("link", (string)product._DetailUrl); if (mainImageUrl.HasValue()) { writer.WriteElementString("g", "image_link", _googleNamespace, mainImageUrl); } if (config.AdditionalImages) { var imageCount = 0; foreach (dynamic productPicture in product.ProductPictures) { string pictureUrl = productPicture.Picture._ImageUrl; if (pictureUrl.HasValue() && (mainImageUrl.IsEmpty() || !mainImageUrl.IsCaseInsensitiveEqual(pictureUrl)) && ++imageCount <= 10) { writer.WriteElementString("g", "additional_image_link", _googleNamespace, pictureUrl); } } } writer.WriteElementString("g", "condition", _googleNamespace, condition); writer.WriteElementString("g", "availability", _googleNamespace, availability); if (availability == "preorder" && entity.AvailableStartDateTimeUtc.HasValue && entity.AvailableStartDateTimeUtc.Value > DateTime.UtcNow) { var availabilityDate = entity.AvailableStartDateTimeUtc.Value.ToString(dateFormat); writer.WriteElementString("g", "availability_date", _googleNamespace, availabilityDate); } if (config.SpecialPrice && futureSpecialPrice.HasValue && entity.SpecialPriceStartDateTimeUtc.HasValue && entity.SpecialPriceEndDateTimeUtc.HasValue) { var specialPriceDate = "{0}/{1}".FormatInvariant( entity.SpecialPriceStartDateTimeUtc.Value.ToString(dateFormat), entity.SpecialPriceEndDateTimeUtc.Value.ToString(dateFormat)); writer.WriteElementString("g", "sale_price", _googleNamespace, futureSpecialPrice.Value.FormatInvariant() + " " + (string)currency.CurrencyCode); writer.WriteElementString("g", "sale_price_effective_date", _googleNamespace, specialPriceDate); price = (product._RegularPrice as decimal?) ?? price; } writer.WriteElementString("g", "price", _googleNamespace, price.FormatInvariant() + " " + (string)currency.CurrencyCode); writer.WriteCData("gtin", gtin, "g", _googleNamespace); writer.WriteCData("brand", brand, "g", _googleNamespace); writer.WriteCData("mpn", mpn, "g", _googleNamespace); if (config.Gender.IsCaseInsensitiveEqual(Unspecified)) { writer.WriteCData("gender", "", "g", _googleNamespace); } else { writer.WriteCData("gender", gmc != null && gmc.Gender.HasValue() ? gmc.Gender : config.Gender, "g", _googleNamespace); } if (config.AgeGroup.IsCaseInsensitiveEqual(Unspecified)) { writer.WriteCData("age_group", "", "g", _googleNamespace); } else { writer.WriteCData("age_group", gmc != null && gmc.AgeGroup.HasValue() ? gmc.AgeGroup : config.AgeGroup, "g", _googleNamespace); } writer.WriteCData("color", gmc != null && gmc.Color.HasValue() ? gmc.Color : config.Color, "g", _googleNamespace); writer.WriteCData("size", gmc != null && gmc.Size.HasValue() ? gmc.Size : config.Size, "g", _googleNamespace); writer.WriteCData("material", gmc != null && gmc.Material.HasValue() ? gmc.Material : config.Material, "g", _googleNamespace); writer.WriteCData("pattern", gmc != null && gmc.Pattern.HasValue() ? gmc.Pattern : config.Pattern, "g", _googleNamespace); writer.WriteCData("item_group_id", gmc != null && gmc.ItemGroupId.HasValue() ? gmc.ItemGroupId : "", "g", _googleNamespace); writer.WriteElementString("g", "identifier_exists", _googleNamespace, gtin.HasValue() || brand.HasValue() || mpn.HasValue() ? "TRUE" : "FALSE"); if (config.ExpirationDays > 0) { writer.WriteElementString("g", "expiration_date", _googleNamespace, DateTime.UtcNow.AddDays(config.ExpirationDays).ToString("yyyy-MM-dd")); } if (config.ExportShipping) { string weightInfo; var weight = ((decimal)product.Weight).FormatInvariant(); if (measureWeightSystemKey.IsCaseInsensitiveEqual("gram")) { weightInfo = weight + " g"; } else if (measureWeightSystemKey.IsCaseInsensitiveEqual("lb")) { weightInfo = weight + " lb"; } else if (measureWeightSystemKey.IsCaseInsensitiveEqual("ounce")) { weightInfo = weight + " oz"; } else { weightInfo = weight + " kg"; } writer.WriteElementString("g", "shipping_weight", _googleNamespace, weightInfo); } if (config.ExportBasePrice && entity.BasePriceHasValue) { var measureUnit = BasePriceUnits((string)product.BasePriceMeasureUnit); if (BasePriceSupported(entity.BasePriceBaseAmount ?? 0, measureUnit)) { var basePriceMeasure = "{0} {1}".FormatInvariant((entity.BasePriceAmount ?? decimal.Zero).FormatInvariant(), measureUnit); var basePriceBaseMeasure = "{0} {1}".FormatInvariant(entity.BasePriceBaseAmount ?? 1, measureUnit); writer.WriteElementString("g", "unit_pricing_measure", _googleNamespace, basePriceMeasure); writer.WriteElementString("g", "unit_pricing_base_measure", _googleNamespace, basePriceBaseMeasure); } } if (gmc != null && gmc.Multipack > 1) { writer.WriteElementString("g", "multipack", _googleNamespace, gmc.Multipack.ToString()); } if (gmc != null && gmc.IsBundle.HasValue) { writer.WriteElementString("g", "is_bundle", _googleNamespace, gmc.IsBundle.Value ? "TRUE" : "FALSE"); } if (gmc != null && gmc.IsAdult.HasValue) { writer.WriteElementString("g", "adult", _googleNamespace, gmc.IsAdult.Value ? "TRUE" : "FALSE"); } if (gmc != null && gmc.EnergyEfficiencyClass.HasValue()) { writer.WriteElementString("g", "energy_efficiency_class", _googleNamespace, gmc.EnergyEfficiencyClass); } if (gmc != null && gmc.CustomLabel0.HasValue()) { writer.WriteElementString("g", "custom_label_0", _googleNamespace, gmc.CustomLabel0); } if (gmc != null && gmc.CustomLabel1.HasValue()) { writer.WriteElementString("g", "custom_label_1", _googleNamespace, gmc.CustomLabel1); } if (gmc != null && gmc.CustomLabel2.HasValue()) { writer.WriteElementString("g", "custom_label_2", _googleNamespace, gmc.CustomLabel2); } if (gmc != null && gmc.CustomLabel3.HasValue()) { writer.WriteElementString("g", "custom_label_3", _googleNamespace, gmc.CustomLabel3); } if (gmc != null && gmc.CustomLabel4.HasValue()) { writer.WriteElementString("g", "custom_label_4", _googleNamespace, gmc.CustomLabel4); } ++context.RecordsSucceeded; } catch (Exception exception) { context.RecordException(exception, entity.Id); } writer.WriteEndElement(); // item } } writer.WriteEndElement(); // channel writer.WriteEndElement(); // rss writer.WriteEndDocument(); } }
protected override void Export(ExportExecuteContext context) { var categoryIds = context.CustomProperties["CategoryIds"] as HashSet <int>; var storeIds = new HashSet <int>(context.CustomProperties["StoreIds"] as int[]); var domain = context.CustomProperties["Domain"] as string; var categoryToStoreMappings = GetCategoryToStoreMappings(); var allCategoryIds = _categoryRepository.TableUntracked .Where(x => !x.Deleted) .Select(x => new { x.Id, x.ParentCategoryId }) .ToDictionary(x => x.Id, x => x.ParentCategoryId); using (var writer = XmlWriter.Create(context.DataStream, ShopConnectorService.DefaultSettings)) { var helper = new ExportXmlHelper(writer, true); helper.Exclude = ExportXmlExclude.Category; writer.WriteStartElement("Content"); writer.WriteStartElement("Products"); writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion); while (context.Abort == DataExchangeAbortion.None && context.DataSegmenter.ReadNextSegment()) { var segment = context.DataSegmenter.CurrentSegment; var skuMappings = new Dictionary <int, string>(); if (domain.HasValue()) { var productIds = segment.Select(x => (int)((dynamic)x).Id).ToArray(); var mappings = _shopConnectorService.Value.GetSkuMappingsByProductIds(domain, productIds); skuMappings = mappings.ToDictionarySafe(x => x.ProductId, x => x.Sku); } foreach (dynamic product in segment) { if (context.Abort != DataExchangeAbortion.None) { break; } try { Product entity = product.Entity; // SKU mapping. if (skuMappings.TryGetValue(entity.Id, out var sku)) { product.Sku = sku; } helper.WriteProduct(product, "Product"); if (product.ProductCategories != null) { foreach (dynamic productCategory in product.ProductCategories) { if (productCategory.Category != null) { var categoryId = (int)productCategory.Category.Id; if (IsCategoryAllowed(categoryId, storeIds, allCategoryIds, categoryToStoreMappings)) { IncludeIdAndAllParentIds(categoryId, categoryIds, allCategoryIds); } } } } ++context.RecordsSucceeded; } catch (OutOfMemoryException) { context.Abort = DataExchangeAbortion.Hard; throw; } catch (Exception ex) { context.RecordException(ex, (int)product.Id); } } } writer.WriteElementString("Success", context.RecordsSucceeded.ToString()); writer.WriteElementString("Failure", context.RecordsFailed.ToString()); writer.WriteElementString("TotalRecords", context.DataSegmenter.TotalRecords.ToString()); writer.WriteEndElement(); // Products writer.WriteEndElement(); // Content var publicKey = (string)context.CustomProperties[ShopConnectorCore.Header.PublicKey]; var controllingData = ConnectionCache.ControllingData(); var connection = controllingData.Connections.FirstOrDefault(x => x.PublicKey == publicKey && x.IsForExport); if (connection != null) { connection.LastProductCallUtc = DateTime.UtcNow; ConnectionCache.ControllingData().ConnectionsUpdated = true; } } }