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();
            }
        }
Exemplo n.º 2
0
        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();
            }
        }