private void CreateFeed(FeedFileCreationContext fileCreation, TaskExecutionContext taskContext) { var xmlSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, CheckCharacters = false }; using (var writer = XmlWriter.Create(fileCreation.Stream, xmlSettings)) { try { fileCreation.Logger.Information("Log file - Google Merchant Center feed."); var searchContext = new ProductSearchContext { OrderBy = ProductSortingEnum.CreatedOn, PageSize = Settings.PageSize, StoreId = fileCreation.Store.Id, VisibleIndividuallyOnly = true }; var currency = Helper.GetUsedCurrency(Settings.CurrencyId); var measureWeightSystemKey = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).SystemKeyword; 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".FormatWith(fileCreation.Store.Name)); writer.WriteElementString("link", "http://base.google.com/base/"); writer.WriteElementString("description", "Information about products"); for (int i = 0; i < 9999999; ++i) { searchContext.PageIndex = i; // Perf _dbContext.DetachAll(); var products = _productService.SearchProducts(searchContext); if (fileCreation.TotalRecords == 0) { fileCreation.TotalRecords = products.TotalCount * fileCreation.StoreCount; // approx } foreach (var product in products) { fileCreation.Report(); if (product.ProductType == ProductType.SimpleProduct || product.ProductType == ProductType.BundledProduct) { WriteItem(fileCreation, writer, product, currency, measureWeightSystemKey); } else if (product.ProductType == ProductType.GroupedProduct) { var associatedSearchContext = new ProductSearchContext { OrderBy = ProductSortingEnum.CreatedOn, PageSize = int.MaxValue, StoreId = fileCreation.Store.Id, VisibleIndividuallyOnly = false, ParentGroupedProductId = product.Id }; foreach (var associatedProduct in _productService.SearchProducts(associatedSearchContext)) { WriteItem(fileCreation, writer, associatedProduct, currency, measureWeightSystemKey); } } if (taskContext.CancellationToken.IsCancellationRequested) { fileCreation.Logger.Warning("A cancellation has been requested"); break; } } if (!products.HasNextPage || taskContext.CancellationToken.IsCancellationRequested) { break; } } writer.WriteEndElement(); // channel writer.WriteEndElement(); // rss writer.WriteEndDocument(); if (fileCreation.ErrorMessage.HasValue()) { fileCreation.Logger.Error(fileCreation.ErrorMessage); } } catch (Exception exc) { fileCreation.Logger.Error(exc.Message, exc); } } }
private void CreateFeed(FeedFileCreationContext fileCreation, TaskExecutionContext taskContext) { var xmlSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, CheckCharacters = false }; using (var writer = XmlWriter.Create(fileCreation.Stream, xmlSettings)) { try { fileCreation.Logger.Information("Log file - Google Merchant Center feed."); var searchContext = new ProductSearchContext() { OrderBy = ProductSortingEnum.CreatedOn, PageSize = int.MaxValue, StoreId = fileCreation.Store.Id, VisibleIndividuallyOnly = true }; string breakingError = null; var qualifiedProducts = new List <Product>(); var currency = Helper.GetUsedCurrency(Settings.CurrencyId); var products = _productService.SearchProducts(searchContext); var measureWeightSystemKey = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).SystemKeyword; if (fileCreation.TotalRecords == 0) { fileCreation.TotalRecords = products.Count * fileCreation.StoreCount; } 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".FormatWith(fileCreation.Store.Name)); writer.WriteElementString("link", "http://base.google.com/base/"); writer.WriteElementString("description", "Information about products"); foreach (var product in products) { fileCreation.Report(); Helper.GetQualifiedProductsByProduct(product, fileCreation.Store, qualifiedProducts); foreach (var qualifiedProduct in qualifiedProducts) { writer.WriteStartElement("item"); try { breakingError = WriteItem(writer, fileCreation.Store, qualifiedProduct, currency, measureWeightSystemKey); } catch (Exception exc) { fileCreation.Logger.Error(exc.Message, exc); } writer.WriteEndElement(); // item } if (breakingError.HasValue()) { fileCreation.Logger.Error(breakingError); break; } if (taskContext.CancellationToken.IsCancellationRequested) { fileCreation.Logger.Warning("A cancellation has been requested"); break; } } writer.WriteEndElement(); // channel writer.WriteEndElement(); // rss writer.WriteEndDocument(); if (breakingError.HasValue()) { throw new SmartException(breakingError); } } catch (Exception exc) { fileCreation.Logger.Error(exc.Message, exc); } } }
private void WriteItem(FeedFileCreationContext fileCreation, XmlWriter writer, Product product, Currency currency, string measureWeightSystemKey) { GoogleProductRecord googleProduct = null; try { googleProduct = GetGoogleProductRecord(product.Id); if (googleProduct != null && !googleProduct.Export) { return; } } catch (Exception exc) { fileCreation.Logger.Error(exc.Message, exc); } writer.WriteStartElement("item"); try { var manu = _manufacturerService.GetProductManufacturersByProductId(product.Id).FirstOrDefault(); var mainImageUrl = Helper.GetMainProductImageUrl(fileCreation.Store, product); var category = ProductCategory(googleProduct); if (category.IsEmpty()) { fileCreation.ErrorMessage = Helper.GetResource("MissingDefaultCategory"); } string manuName = (manu != null ? manu.Manufacturer.GetLocalized(x => x.Name, Settings.LanguageId, true, false) : null); string productName = product.GetLocalized(x => x.Name, Settings.LanguageId, true, false); string shortDescription = product.GetLocalized(x => x.ShortDescription, Settings.LanguageId, true, false); string fullDescription = product.GetLocalized(x => x.FullDescription, Settings.LanguageId, true, false); var brand = (manuName ?? Settings.Brand); var mpn = Helper.GetManufacturerPartNumber(product); bool identifierExists = product.Gtin.HasValue() || brand.HasValue() || mpn.HasValue(); writer.WriteElementString("g", "id", _googleNamespace, product.Id.ToString()); writer.WriteStartElement("title"); writer.WriteCData(productName.Truncate(70)); writer.WriteEndElement(); var description = Helper.BuildProductDescription(productName, shortDescription, fullDescription, manuName, d => { if (fullDescription.IsEmpty() && shortDescription.IsEmpty()) { var rnd = new Random(); switch (rnd.Next(1, 5)) { case 1: return(d.Grow(Settings.AppendDescriptionText1, " ")); case 2: return(d.Grow(Settings.AppendDescriptionText2, " ")); case 3: return(d.Grow(Settings.AppendDescriptionText3, " ")); case 4: return(d.Grow(Settings.AppendDescriptionText4, " ")); case 5: return(d.Grow(Settings.AppendDescriptionText5, " ")); } } return(d); }); writer.WriteStartElement("description"); writer.WriteCData(description.RemoveInvalidXmlChars()); writer.WriteEndElement(); writer.WriteStartElement("g", "google_product_category", _googleNamespace); writer.WriteCData(category); writer.WriteFullEndElement(); string productType = Helper.GetCategoryPath(product); if (productType.HasValue()) { writer.WriteStartElement("g", "product_type", _googleNamespace); writer.WriteCData(productType); writer.WriteFullEndElement(); } writer.WriteElementString("link", Helper.GetProductDetailUrl(fileCreation.Store, product)); writer.WriteElementString("g", "image_link", _googleNamespace, mainImageUrl); foreach (string additionalImageUrl in Helper.GetAdditionalProductImages(fileCreation.Store, product, mainImageUrl)) { writer.WriteElementString("g", "additional_image_link", _googleNamespace, additionalImageUrl); } writer.WriteElementString("g", "condition", _googleNamespace, Condition()); writer.WriteElementString("g", "availability", _googleNamespace, Availability(product)); decimal price = Helper.GetProductPrice(product, currency); string specialPriceDate; if (SpecialPrice(product, out specialPriceDate)) { writer.WriteElementString("g", "sale_price", _googleNamespace, price.FormatInvariant() + " " + currency.CurrencyCode); writer.WriteElementString("g", "sale_price_effective_date", _googleNamespace, specialPriceDate); // get regular price ignoring any special price decimal specialPrice = product.SpecialPrice.Value; product.SpecialPrice = null; price = Helper.GetProductPrice(product, currency); product.SpecialPrice = specialPrice; _dbContext.SetToUnchanged <Product>(product); } writer.WriteElementString("g", "price", _googleNamespace, price.FormatInvariant() + " " + currency.CurrencyCode); writer.WriteCData("gtin", product.Gtin, "g", _googleNamespace); writer.WriteCData("brand", brand, "g", _googleNamespace); writer.WriteCData("mpn", mpn, "g", _googleNamespace); writer.WriteCData("gender", Gender(googleProduct), "g", _googleNamespace); writer.WriteCData("age_group", AgeGroup(googleProduct), "g", _googleNamespace); writer.WriteCData("color", Color(googleProduct), "g", _googleNamespace); writer.WriteCData("size", Size(googleProduct), "g", _googleNamespace); writer.WriteCData("material", Material(googleProduct), "g", _googleNamespace); writer.WriteCData("pattern", Pattern(googleProduct), "g", _googleNamespace); writer.WriteCData("item_group_id", ItemGroupId(googleProduct), "g", _googleNamespace); writer.WriteElementString("g", "online_only", _googleNamespace, Settings.OnlineOnly ? "y" : "n"); writer.WriteElementString("g", "identifier_exists", _googleNamespace, identifierExists ? "TRUE" : "FALSE"); if (Settings.ExpirationDays > 0) { writer.WriteElementString("g", "expiration_date", _googleNamespace, DateTime.UtcNow.AddDays(Settings.ExpirationDays).ToString("yyyy-MM-dd")); } if (Settings.ExportShipping) { string weightInfo, weight = 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 (Settings.ExportBasePrice && product.BasePriceHasValue) { string measureUnit = BasePriceUnits(product.BasePriceMeasureUnit); if (BasePriceSupported(product.BasePriceBaseAmount ?? 0, measureUnit)) { string basePriceMeasure = "{0} {1}".FormatWith((product.BasePriceAmount ?? decimal.Zero).FormatInvariant(), measureUnit); string basePriceBaseMeasure = "{0} {1}".FormatWith(product.BasePriceBaseAmount, measureUnit); writer.WriteElementString("g", "unit_pricing_measure", _googleNamespace, basePriceMeasure); writer.WriteElementString("g", "unit_pricing_base_measure", _googleNamespace, basePriceBaseMeasure); } } } catch (Exception exc) { fileCreation.Logger.Error(exc.Message, exc); } writer.WriteEndElement(); // item }