Overview of the setup

Feed can be enabled via standard generic export job in the .

 

The structure of the product feed is CSV with the following required fields:

Google fieldCorresponding MappingMemo
id
sku.code or product.codeYou can choose to use sku or product entity depending on your setup
title
sku.displayName or product.displayNameYou can choose to use sku or product entity depending on your setup
link
sku.seo.uri or product.seo.uri

You can choose to use sku or product entity depending on your setup

(warning) Note that you need to use a template to generate full URL, do NOT forget to include the warehouse code

e.g. "https://www.myshop.com/fc/MAIN/product/$1"

image_link
IMAGE0 atrribute on sku or product

You can choose to use sku or product entity depending on your setup

(warning) Use AVC data type to look up the attribute value

e.g. "https://www.myshop.com/imgvault/product/$1"

additional_image_link
IMAGE1 atrribute on sku or product

You can choose to use sku or product entity depending on your setup

(warning) Use AVC data type to look up the attribute value

e.g. "https://www.myshop.com/imgvault/product/$1"

price
 

(warning) Use PRICE data type to look up the minimal price. Use template as google expects the currency included

e.g. "$1 CHF"

shipping
 

(warning) At the moment it is recommended to hardcode the common shipping option with fixed shipping cost

e.g. "CH:::4.95 CHF" (CH is the code for your region and extra colons are separators for shipping attributes, which you can leave as default)

availability
 (warning) hardcode to "in_stock"
condition
 (warning) hardcode to "new"
brand
sku.product.brand.name or product.brand.nameYou can choose to use sku or product entity depending on your setup
gtin
sku.barCode or product.attribute.XXXX

You can choose to use sku or product entity depending on your setup

(warning) if you use product store GTIN in an attribute and use AVC data type

mpn
sku.nanufacturerCode or product.manufacturerCodeYou can choose to use sku or product entity depending on your setup

 

Note that in your descriptor you need to specify full path on the server where to put the file. It is recommended to place it in one of the apache resource directories for your site. Ensure you specify the resource path to avoid proxy to tomcat.

...
# Map /r to /resources file path
Alias /r /var/www/shop10/resources
...
# allow URLS under /r to pass and not fall unto tomcat proxy pass rule
ProxyPass /r !
...
ProxyPass / ajp://localhost:8012/
...
<Directory /var/www/shop10/>
        Options -Indexes -FollowSymLinks -MultiViews
        AllowOverride None
        Order allow,deny
        allow from all
</Directory> 
...
...
    <export-file-descriptor>
        <file-encoding>UTF-8</file-encoding>
        <file-name>/var/www/shop10/resources/2l8YSRX1tTAQq_merchantcentre.csv</file-name>
        <print-header>true</print-header>
        <column-delimiter>,</column-delimiter>
        <text-qualifier>&quot;</text-qualifier>
    </export-file-descriptor>
...

In the above example the feed file would be generated to "/var/www/shop10/resources/" and will be available under the URL: www.myshop.com/r/2l8YSRX1tTAQq_merchantcentre.csv

Example export descriptor

You need to define export descriptor for generating the CSV file and create a corresponding Export Group (in this example we use: "SHOP10: Merchant Centre Product Feed CSV").

Both of which can be setup from the Admin application.

Example export descriptor for "product" entity is listed below:

<!--
  ~ Copyright 2009 Inspire-Software.com
  ~
  ~    Licensed under the Apache License, Version 2.0 (the "License");
  ~    you may not use this file except in compliance with the License.
  ~    You may obtain a copy of the License at
  ~
  ~        http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~    Unless required by applicable law or agreed to in writing, software
  ~    distributed under the License is distributed on an "AS IS" BASIS,
  ~    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~    See the License for the specific language governing permissions and
  ~    limitations under the License.
  -->

<export-descriptor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:noNamespaceSchemaLocation="http://www.yes-cart.org/schema/export-descriptor.xsd">

    <context>
        <shop-code>MMS</shop-code>
    </context>

    <entity-type>org.yes.cart.domain.entity.Product</entity-type>

    <export-file-descriptor>
        <file-encoding>UTF-8</file-encoding>
        <file-name>/var/www/shop10/resources/2l8YSRX1tTAQq_merchantcentre.csv</file-name>
        <print-header>true</print-header>
        <column-delimiter>,</column-delimiter>
        <text-qualifier>&quot;</text-qualifier>
    </export-file-descriptor>

    <select-sql>
        select distinct s.product, w
        from ProductSkuEntity s, SkuPriceEntity r, SkuWarehouseEntity w
        where
              s.code = r.skuCode
          and r.shop.shopId = 15
          and r.currency = 'CHF'
          and r.pricingPolicy is null
          and (r.saleto is null or r.saleto &gt; {NOW})
          and s.code = w.skuCode
          and w.warehouse.warehouseId in (5,6)
          and w.quantity  &gt; 0
          and (w.availableto is null or w.availableto &gt; {NOW})
    </select-sql>

    <export-columns>

        <!-- SKU -->
        <column-descriptor>
            <column-header>id</column-header>
            <field-type>FIELD</field-type>
            <name>code</name>
        </column-descriptor>

        <!-- Display names DE -->
        <column-descriptor>
            <column-header>title</column-header>
            <field-type>FIELD</field-type>
            <name>name</name>
            <!--            <name>displayName</name>-->
            <!--            <language>de</language>-->
        </column-descriptor>

        <!-- Short description -->
        <column-descriptor>
            <column-header>description</column-header>
            <field-type>FIELD</field-type>
            <data-type>AVC</data-type>
            <name>attributes</name>
            <context>PRODUCT_DESCRIPTION2_de</context>
        </column-descriptor>

        <!-- Deep link -->
        <column-descriptor>
            <column-header>link</column-header>
            <field-type>FIELD</field-type>
            <data-type>org.yes.cart.domain.entity.Seo</data-type>
            <name>seo.uri</name>
            <value-regex>(.*)</value-regex>
            <value-regex-template>https://www.myshop.com/fc/MAIN/product/$1</value-regex-template>
        </column-descriptor>

        <!-- Image -->
        <column-descriptor>
            <column-header>image_link</column-header>
            <field-type>FIELD</field-type>
            <data-type>AVC</data-type>
            <name>attributes</name>
            <context>IMAGE0</context>
            <value-regex>(.*)</value-regex>
            <value-regex-template>https://www.myshop.com/imgvault/product/$1</value-regex-template>
        </column-descriptor>

        <!-- Image Alternative -->
        <column-descriptor>
            <column-header>additional_image_link</column-header>
            <field-type>FIELD</field-type>
            <data-type>AVC</data-type>
            <name>attributes</name>
            <context>IMAGE1</context>
            <value-regex>(.*)</value-regex>
            <value-regex-template>https://www.myshop.com/imgvault/product/$1</value-regex-template>
        </column-descriptor>

        <!-- Price in CHF incl VAT -->
        <column-descriptor>
            <column-header>price</column-header>
            <field-type>FIELD</field-type>
            <data-type>PRICE</data-type>
            <name>productId</name>
            <context>CHF</context>
            <value-regex>(.*)</value-regex>
            <value-regex-template>$1 CHF</value-regex-template>
        </column-descriptor>

        <!-- Order shipping cost -->
        <column-descriptor>
            <column-header>shipping</column-header>
            <field-type>FIELD</field-type>
            <name>productId</name>
            <value-constant>CH:::4.95 CHF</value-constant>
        </column-descriptor>

        <!-- Availability -->
        <column-descriptor>
            <column-header>availability</column-header>
            <field-type>FIELD</field-type>
            <name>productId</name>
            <value-constant>in_stock</value-constant>
        </column-descriptor>
        
        <!-- Condition -->
        <column-descriptor>
            <column-header>condition</column-header>
            <field-type>FIELD</field-type>
            <name>productId</name>
            <value-constant>new</value-constant>
        </column-descriptor>

        <!-- Brand,Manufacturer -->
        <column-descriptor>
            <column-header>brand</column-header>
            <field-type>FK_FIELD</field-type>
            <entity-type>org.yes.cart.domain.entity.Brand</entity-type>
            <name>brand.name</name>
        </column-descriptor>

        <!-- EAN or ISBN for Books -->
        <column-descriptor>
            <column-header>gtin</column-header>
            <field-type>FIELD</field-type>
            <data-type>AVC</data-type>
            <name>attributes</name>
            <context>atoppreiseexportean</context>
        </column-descriptor>

        <!-- Manufacturer SKU -->
        <column-descriptor>
            <column-header>mpn</column-header>
            <field-type>FIELD</field-type>
            <name>manufacturerCode</name>
        </column-descriptor>

        
    </export-columns>
</export-descriptor>

 

Example SQL to insert the JOB

The job configuration need to be setup via SQL (see example below) and it will be required to restart the Admin application for the changed to take effect in the job scheduler.

INSERT INTO TJOBDEFINITION (GUID, JOB_NAME, PROCESSOR, CONTEXT, HOST_REGEX, DEFAULT_CRON, DEFAULT_PAUSED)
  VALUES ('shop10MCProductFeedCSV', 'SHOP10: Merchant Centre Product Feed CSV', 'genericExportGroupProcessor', 
'config.user=
config.pass=
export.group=SHOP10: Merchant Centre Product Feed CSV',
  '^(ADM)$', '0 45 8 * * ?', 1);

 

Merchant Centre Specific Tips