Important Notice from AspDotNetStorefront
It is with dismay that we report that we have been forced, through the action of hackers, to shut off write-access to this forum. We are keen to leave the wealth of material available to you for research. We have opened a new forum from which our community of users can seek help, support and advice from us and from each other. To post a new question to our community, please visit: http://forums.vortx.com
Results 1 to 23 of 23

Thread: Google Product Feed Errors

  1. #1
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default Google Product Feed Errors

    I have done every required.. I thought. I have added the required field from this:
    http://manual.aspdotnetstorefront.co...ch-update.aspx

    Code:
    <g:id>
    <xsl:value-of select="productid"/>
    </g:id>
    That worked perfectly I do not receive the error from missing ID. However, now I have a whole new list of errors.

    Missing required attribute: condition (12613 errors)
    Please make sure you include all required attributes in your data feed.
    Examples:

    Item Nr. Item ID Line Nr.
    4 4 1 Show Item
    13 14 68 Show Item
    19 21 103 Show Item
    25 27 121 Show Item
    32 34 142 Show Item
    As well as:

    12613
    Missing recommended attribute: brand (12613 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    12613
    Missing recommended attribute: shipping weight (12613 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    12613
    Missing recommended attribute: google product category (12613 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    12613
    Missing recommended attribute: product type (12613 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    1025
    Missing recommended attribute: mpn (1025 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    215
    Missing recommended attribute: image link (215 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.


    121
    Missing recommended attribute: description (121 warnings)
    While items missing recommended attributes will process successfully, we recommend including relevant attributes if they are available.
    Is this something that I can fix through the code or is this something I will have to go through each product and make them more product feed friendly. I wouldn't think that every single one of them (12,613 products) would have an error.

    We are running on 8.0.1.2 any advice would be appreciated. Thank you in advance
    Last edited by gmaniac; 08-12-2011 at 09:17 AM. Reason: fix

  2. #2
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    gmaniac - i dont suppose for a minute that you will get a response from the guys at aspdnsf as the solution is already being sold by them in the marketplace
    8.0.1.4 W2008R2 64-bit MSSQL2005

  3. #3
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default it'll come

    I will be moving onto this project here shortly and when I get it I will post my solution, maybe save a couple people some money. I figured I wouldn't be receiving any help, especially since they told me they no longer support this version anymore (in affect a month and a half ago or so).

  4. #4
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    That's a good idea - perhaps we as developers should all contribute a small amount of our time to develop a free 'community built' Google Product feed.

    Each time Google update their feed spec, we can update the Xml Package.

    Let me get things kicked off by submitting the SQL Query we use in our feed.googlebase.xml.config package - this brings back fields such as Brand (used in the google brand field) and CategoryName (which we use as the product_type field). It also lets you exclude specific categories if you want and could probably be further improved.

    Code:
        <query name="Products" rowElementName="Product">
            <sql>
            <![CDATA[
            select c.Name categoryname, p.productid, p.name, isnull(pv.name, '') VariantName,
      p.description, p.sename, p.ImageFileNameOverride, p.SKU, 
      isnull(p.FroogleDescription, '') ProductFroogleDescription, 
      p.SEKeywords,
      m.Name brand, p.ManufacturerPartNumber, 
      pv.price, isnull(pv.saleprice, 0) saleprice, 
      isnull(pv.FroogleDescription, '') VariantFroogleDescription, 
      isnull(pv.description, '') VariantDescr,  pv.Condition,
    ROW_NUMBER() OVER (ORDER BY p.productid) AS ROW
           from dbo.product p 
           join dbo.productvariant pv on p.productid = pv.productid
           join dbo.ProductManufacturer pm on pm.ProductID = p.ProductID
           join dbo.Manufacturer m on m.ManufacturerID = pm.ManufacturerID 
           join dbo.ProductCategory pc on pc.ProductID = p.ProductID 
           join dbo.Category c on c.CategoryID = pc.CategoryID
           and pc.CategoryID in (select top 1 CategoryID from productcategory pc2 where pc2.productid = p.Productid
           and pc2.CategoryID not in(REPLACE THIS WITH IDS OF ANY CATEGORIES YOU WANT TO EXCLUDE FROM FEED: e.g 100,200) )
           left join 
           (select variantid, sum(quan) inventory 
           from dbo.inventory group by variantid) i on pv.variantid = i.variantid
                where p.IsSystem=0 
                    and p.deleted = 0 
                    and p.published = 1 
                    and p.ExcludeFromPriceFeeds = 0 
                    and pv.isdefault = 1
                    and case p.TrackInventoryBySizeAndColor when 1 then isnull(i.inventory, 0)
                     else pv.inventory end >= @HideProductsWithLessThanThisInventoryLevel  
            ]]>
            </sql>
            <queryparam paramname="@HideProductsWithLessThanThisInventoryLevel" paramtype="appconfig" requestparamname="HideProductsWithLessThanThisInventoryLevel" sqlDataType="int" defvalue="0"  validationpattern="" />
    	</query>
    g:condition

    Condition is now a simple test:

    Code:
    <g:condition>
    <xsl:choose>
    	<xsl:when test="number(Condition)=0">
    		New
    	</xsl:when>
    	<xsl:when test="number(Condition)=1">
    		Used
    	</xsl:when>
    </xsl:choose>
    </g:condition>
    g:brand

    Brand is also now straightforward:
    <g:brand><xsl:value-of select="brand"/></g:brand>

    g:image_link

    Slightly more involved, we add a param to the template for the Store URL:

    Code:
    <xsl:param name="StoreUrl">http://www.YOURDOMAIN.com</xsl:param>
    Then we build an image URL specific to the store. You could probably use the ASPDNSF function ProductImageURL() here but we found this to be quicker. In this example, the store uses the ImageFileNameOverride field and just has jpg images:

    Code:
    <xsl:param name="ItemImage" select="concat($StoreUrl,'/images/PRODUCT/medium/',ImageFileNameOverride,'.jpg')"></xsl:param>
    Then to actually output the image link:

    Code:
    <g:image_link>
      <xsl:value-of select="$ItemImage" />
    </g:image_link>
    Happy to see all this improved by the forum members.

    Adam

  5. #5
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default Thank you!

    I appreciate you taking the time to post this wonderful information. I will take a look at this in the morning after I finish a couple of other things. Looks like some great stuff, thank you again

  6. #6
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    How's it looking gmaniac ?

    Watching with interest
    8.0.1.4 W2008R2 64-bit MSSQL2005

  7. #7
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default Almost have it!

    Just letting everyone who is following this that I almost have it. I apologize it has taken me so long to get to this, I want to let you all know I am working on this.

  8. #8
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default partial solution

    I noticed that what webopius posted is useful depending on what the condition of products you are gong to be selling. If everything you are selling is new then you don't need to change the sql query. I will show you what I changed to your existing feed.googlebase.xml.config file to get it working with google.

    I changed only the feed.googlebase.xml.config file found in wwwroot/Admin/XmlPackages/ moving down the page did the following changes.

    Like what I had mentioned in the first post the g:id
    Code:
              <g:id>
    		  	    <xsl:value-of select="productid" />
    		      </g:id>
    Then I fixed the descriptions so that it first strips the html out of product descriptions and I also had it cut off descriptions that are too long. This is how I did this:
    Code:
              <description>
                <xsl:choose>
                  <xsl:when test="$VariantFroogleDescription!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($VariantFroogleDescription), 1, 500)" disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:when test="$ProductFroogleDescription!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($ProductFroogleDescription), 1, 500)" disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:when test="$VariantDescr!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($VariantDescr), 1, 500)" disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="substring(aspdnsf:StripHtml($ProductDescr), 1, 500)" disable-output-escaping="yes" />
                  </xsl:otherwise>
                </xsl:choose>
              </description>
    Google recommended limiting the descriptions characters from 500 to 1000, so that is what that substring() function is doing.

    Next I added g:condition, since we are only selling new items I minimalized it to only adding this:
    Code:
    		      <g:condition>New</g:condition>
    *Now if you are selling new, used, or refurbished you would want to use webopius' post

    Lastly, I added g:mpn or at least a bit more depth to it. I wanted it to give some sort of value here so I made it check first for the manufacturer's part number if no value then try to use the SKU if still nothing then use the productid. Here is how I did that:
    Code:
              <g:mpn>
    		  	    <xsl:choose>
    				      <xsl:when test="$ManufacturerPartNumber!=''">
                		      <xsl:value-of select="$ManufacturerPartNumber" />
    				      </xsl:when>
    				      <xsl:when test="SKU!=''">
                		      <xsl:value-of select="SKU" />
    				      </xsl:when>
    				      <xsl:otherwise>
                		      <xsl:value-of select="productid" />
    				      </xsl:otherwise>
    			      </xsl:choose>
              </g:mpn>
    Now we do not have all of our products assigned to categories yet so I have not added:
    g:google_product_category
    g:product_type

    I will be adding those soon though and show you how I do that as well. Now you will see need to double check that google is accepting all of your products. I ran into &amp etc. so you will probably need to do some extra checks either in the config file or you could just remove them from the samplefeed.xml that will be generated.

    I believe I covered everything that I did to get it working, if you run into any issues don't hesitate to ask questions. Good luck!

  9. #9
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    ok, so i did all this and uploaded to google fine but i get this error

    XML formatting error - Error
    Our system encountered an error when processing your data feed. Learn more.
    Examples:
    Line No. Column No.
    4 116

    All seems ok though ?....any ideas ?
    8.0.1.4 W2008R2 64-bit MSSQL2005

  10. #10
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default

    I think I received some similar issues on my upload. Do you have html characters in any of the descriptions? I had to go through and remove basically anything that had & in it. These characters google product feed does not like. How many products are you uploading? You can email me if you like to geoffrey@archerycenter.com, only reason I say that is I am not the best at checking this forum (now that I know you are looking for help, I will try to check more). One last question is it loading some of them and then stoping after a certain point? To see if your feed is going to work, load up firefox and navigate to your feed in the browser. If it is stopping somewhere you can see where at least.

  11. #11
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    It certainly could be HTML within the descriptions. In other feeds, we run the product and variant descriptions through the StripHtml() function, something like this:

    Code:
    <xsl:param name="WebConfigLocaleSetting" select="/root/Runtime/WebConfigLocaleSetting" />
    <xsl:param name="ProductDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(description,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
    Adam

  12. #12
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    Thanks guys....i tried including the striphtml stuff....FF gives me this error
    XML Parsing Error: not well-formed
    Location: http://www.thefreemason.com/rssfeed....nel=googlefeed
    Line Number 1, Column 10:Exception=The variable or parameter 'ManufacturerPartNumber' is either not defined or it is out of scope.<br/>
    ---------^

    Is it wise to post the xml code here for review ?
    8.0.1.4 W2008R2 64-bit MSSQL2005

  13. #13
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Sure, by all means post the full XML (or email it to me and I'll take a look - no charge!).

    Off the top of my head, it sounds like you are using ManufacturerPartNumber as a variable rather than as a field extracted by the SQL statement.

    Just as a test, look in your XML package for $ManufacturerPartNumber and change it to ManufacturerPartNumber without the $

    Adam

  14. #14
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    thnx guys - i have checked it through but i dont see what i am getting wrong

    here you go

    HTML Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- 
    
    ###################################################################################################
    
    ### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2009.  All Rights Reserved.				
    
    	                -->
    <!-- http://www.aspdotnetstorefront.com									
    
    					                -->
    <!-- For details on this license please visit  the product homepage at the URL above.		    
    
                -->
    <!-- THE ABOVE NOTICE MUST REMAIN INTACT.                                                           
    
            -->
    <!-- 
    
    ###################################################################################################
    
    ### -->
    <package displayname="Google Base RSS 2.0 Feed" version="2.1" debug="false" 
    
    includeentityhelper="false">
    	<query name="Products" rowElementName="Product">
    		<sql>
    			<![CDATA[
    			select 
    				p.productid, 
    				p.name, 
    				isnull(pv.name, '') VariantName, 
    				p.description, 
    				p.sename, 
    				p.ImageFileNameOverride, 
    				p.SKU, 
    				isnull(p.FroogleDescription, '') ProductFroogleDescription, 
    				p.SEKeywords,
    				p.ManufacturerPartNumber,
    				pv.price, 
    				isnull(pv.saleprice, 0) saleprice, 
    				isnull(pv.FroogleDescription, '') VariantFroogleDescription, 
    				isnull(pv.description, '') VariantDescr,
    				c.Name as MerchantCategory,
    				m.Name as Manufacturer,
    				pv.Weight
    			from 
    				dbo.product p with (nolock) 
    				join dbo.productvariant pv with (nolock) on p.productid = 
    
    pv.productid
    				join productcategory pc with (nolock) on p.ProductID = pc.ProductID 
    				join category c with (nolock) on pc.CategoryID = c.CategoryID
    				left join ProductManufacturer pm with (nolock) on p.ProductID = 
    
    pm.ProductID
    				left join Manufacturer m with (nolock) on pm.ManufacturerID = 
    
    m.ManufacturerID
    			where 
    				p.IsSystem=0 
    				and p.deleted = 0 
    				and p.published = 1 
    				and p.ExcludeFromPriceFeeds = 0 
    				and pv.isdefault = 1
    			]]>
    		</sql>
    	</query>
    	<PackageTransform>
    		<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    
    xmlns:aspdnsf="urn:aspdnsf"   xmlns:g="http://base.google.com/ns/1.0" exclude-result-
    
    prefixes="aspdnsf">
    			<xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" 
    
    indent="no" />
    
    			<xsl:param name="EntityName">
    				<xsl:value-of select="/root/QueryString/entity" />
    			</xsl:param>
    
    			<xsl:param name="ShowInGrid">true</xsl:param>
    			<xsl:param name="GridCols">4</xsl:param>
                <xsl:param name="UseDescr" select="aspdnsf:AppConfig
    
    ('Froogle_UseDescriptionsIfFroogleDescEmpty')" />
    
                <xsl:param name="LocaleSetting" select="/root/Runtime/LocaleSetting" />
    			<xsl:param name="WebConfigLocaleSetting" 
    
    select="/root/Runtime/WebConfigLocaleSetting" />
    
    			<xsl:template match="/">
                    <rss version="2.0">
                        <channel>
                            <title><xsl:value-of select="aspdnsf:AppConfig('StoreName')" /></title>
                            <link><xsl:value-of select="/root/System/StoreUrl" /></link>
                            <description><xsl:value-of select="aspdnsf:AppConfig('RSSChannelDescr')" 
    
    /></description>
                            <language><xsl:value-of select="$WebConfigLocaleSetting" /></language> 
                            <pubDate><xsl:value-of select="/root/System/CurrentDateTime" /></pubDate>
                            <lastBuildDate><xsl:value-of select="/root/System/CurrentDateTime" 
    
    /></lastBuildDate>
                            <xsl:apply-templates select="/root/Products/Product" />
                        </channel>
                    </rss>
                </xsl:template>
    			
    			<xsl:template match="Product">
    				<xsl:param name="SKU" select="aspdnsf:GetMLValue(SKU)"></xsl:param>
    				<xsl:param name="ProductID" select="aspdnsf:GetMLValue
    
    (ProductID)"></xsl:param>
    				<xsl:param name="ProductName" select="aspdnsf:GetMLValue
    
    (name)"></xsl:param>
                    <xsl:param name="ProductVariantName" select="aspdnsf:GetMLValue
    
    (VariantName)"></xsl:param>
                    <xsl:param name="ProductDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue
    
    (description,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="VariantDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue
    
    (variantdescr,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="ProductFroogleDescription" select="aspdnsf:StripHtml
    
    (aspdnsf:GetMLValue(ProductFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
    		<xsl:param name="VariantFroogleDescription" select="aspdnsf:StripHtml
    
    (aspdnsf:GetMLValue(VariantFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="ItemImage" select="aspdnsf:ProductImageUrl(productid, 
    
    ImageFileNameOverride, SKU, 'medium', 1)"></xsl:param>
    				<xsl:param name="MerchantCategory" select="aspdnsf:GetMLValue
    
    (MerchantCategory)"></xsl:param>
    				<xsl:param name="Keywords" select="aspdnsf:GetMLValue
    
    (SEKeywords)"></xsl:param>
    				<xsl:param name="Manufacturer" select="aspdnsf:GetMLValue
    
    (Manufacturer)"></xsl:param>
    				<xsl:param name="MPN" select="aspdnsf:GetMLValue
    
    (ManufacturerPartNumber)"></xsl:param>
    				<xsl:param name="Weight" select="aspdnsf:GetMLValue
    
    (Weight)"></xsl:param>
    				<item>
    				<g:id>
    			<xsl:value-of select="productid" />
    			</g:id>
    					<sku>
    						<xsl:value-of select="$SKU" />
    					</sku>
                        <title>
    						<xsl:value-of select="$ProductName" />              
    
          
    					</title>
                        <link>
    						<xsl:value-of select="/root/System/StoreUrl" 
    
    /><xsl:value-of select="aspdnsf:ProductLink(productid, sename, 0, '')" />                   
    					</link>
                         <description>
                <xsl:choose>
                  <xsl:when test="$VariantFroogleDescription!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($VariantFroogleDescription), 1, 
    
    500)" disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:when test="$ProductFroogleDescription!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($ProductFroogleDescription), 1, 
    
    500)" disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:when test="$VariantDescr!=''">
                    <xsl:value-of select="substring(aspdnsf:StripHtml($VariantDescr), 1, 500)" 
    
    disable-output-escaping="yes" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="substring(aspdnsf:StripHtml($ProductDescr), 1, 500)" 
    
    disable-output-escaping="yes" />
                  </xsl:otherwise>
                </xsl:choose>
              </description>
                        <g:image_link>
                            <xsl:if test="not(contains($ItemImage, 'nopicture'))">
                                <xsl:value-of select="$ItemImage" />
                            </xsl:if>
    					 </g:image_link>
    					<g:price>
    						<xsl:value-of select="format-number(price, 
    
    '###0.00')" />
    					</g:price>
    					<g:saleprice>
    						<xsl:value-of select="format-number(saleprice, 
    
    '###0.00')" />
    					</g:saleprice>
    					<g:id>
    					<xsl:value-of select="productid"/>
    					</g:id>
    					<merchantcategory>
    						<xsl:value-of select="$MerchantCategory" />		
    
    		
    					</merchantcategory>
    										<brand>
    						<xsl:value-of select="$Manufacturer" />
    					</brand>
    					<g:price>
                <xsl:choose>
                  <xsl:when test="number(saleprice)=0">
                    <xsl:value-of select="format-number(price, '###0.00')" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="format-number(saleprice, '###0.00')" />
                  </xsl:otherwise>
                </xsl:choose>
              </g:price>
    					 <g:mpn>
    		  	    <xsl:choose>
    				      <xsl:when test="ManufacturerPartNumber!=''">
                		      <xsl:value-of select="ManufacturerPartNumber" />
    				      </xsl:when>
    				      <xsl:when test="SKU!=''">
                		      <xsl:value-of select="SKU" />
    				      </xsl:when>
    				      <xsl:otherwise>
                		      <xsl:value-of select="productid" />
    				      </xsl:otherwise>
    			      </xsl:choose>
              </g:mpn>
              <g:condition>New</g:condition>
    									</item>
    			</xsl:template>			
    		</xsl:stylesheet>
    	</PackageTransform>
    </package>
    8.0.1.4 W2008R2 64-bit MSSQL2005

  15. #15
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    I installed and ran your XML and just had to make a change to the description block to get it to run in Chrome and Firefox:

    Code:
    <description>
    	<xsl:choose>
    		<xsl:when test="$VariantFroogleDescription!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantFroogleDescription, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:when test="$ProductFroogleDescription!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductFroogleDescription, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:when test="$VariantDescr!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantDescr, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:otherwise>
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductDescr, 1, 500))" disable-output-escaping="yes" />
    		</xsl:otherwise>
    	</xsl:choose>
    </description>
    You'd already called StripHtml() when the params were being created so I removed this. Then I added a call to HtmlEncode which seemed to resolve the browser parsing issues.
    Adam

  16. #16
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    ok great - now i can submit ok thanks.

    The only issue i get now is that i have multiple entries for the same products - not sure why this is happening - thoughts ?

    Also need to make sure 'saleprice' is used instead for 'price' if the sales price has a value - can you help here ?

    Thanks very musg so far guys

    ttfn
    8.0.1.4 W2008R2 64-bit MSSQL2005

  17. #17
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Duplicates of the same products sounds like it might be a problem with the SQL - (sorry if you're using my SQL!). My gut feeling is that it's returning multiple rows of the same product, but each of these rows has a different category match because of the join to ProductCategory if you have the same product in more than one category.

    Sale Price vs Price code used in our feed is:

    Code:
             <g:price>
                <xsl:choose>
                  <xsl:when test="number(saleprice)=0">
                    <xsl:value-of select="format-number((price), '###0.00')" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="format-number((saleprice), '###0.00')" />
                  </xsl:otherwise>
                </xsl:choose>
              </g:price>

  18. #18
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    Ok, so more progress made thank you. 3 remaining issues

    1) The duplicate items are all excluded, even the first of the duplicates is excluded. This happens when one of the products is mapped to several categories. Can we filter somehow ?...not sure the sql is correct (??)

    2) We need to provide prices which include VAT - in our backend, we have net prices that are being extracted. Can we uplift the price in the xml package by 20% (the VAT level) ?

    3) We need to include an ISBN number (gtin) for our book products - any thoughts on where to store this value in the product data....in "Extension Data (User Defined Data)" ?....then how would we extract this ?

    ...almost fixed code below !

    HTML Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- ###################################################################################################### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2009.  All Rights Reserved.					                -->
    <!-- http://www.aspdotnetstorefront.com														                -->
    <!-- For details on this license please visit  the product homepage at the URL above.		                -->
    <!-- THE ABOVE NOTICE MUST REMAIN INTACT.                                                                   -->
    <!-- ###################################################################################################### -->
    <package displayname="Google Base RSS 2.0 Feed" version="2.1" debug="false" includeentityhelper="false">
    	<query name="Products" rowElementName="Product">
    		<sql>
    
    			<![CDATA[
    			select 
    				p.productid, 
    				p.name, 
    				isnull(pv.name, '') VariantName, 
    				p.description, 
    				p.sename, 
    				p.ImageFileNameOverride, 
    				p.SKU, 
    				isnull(p.FroogleDescription, '') ProductFroogleDescription, 
    				p.SEKeywords,
    				p.ManufacturerPartNumber,
    				pv.price, 
    				isnull(pv.saleprice, 0) saleprice, 
    				isnull(pv.FroogleDescription, '') VariantFroogleDescription, 
    				isnull(pv.description, '') VariantDescr,
    				c.Name as MerchantCategory,
    				m.Name as Manufacturer,
    				pv.Weight
    			from 
    				dbo.product p with (nolock) 
    				join dbo.productvariant pv with (nolock) on p.productid = pv.productid
    				join productcategory pc with (nolock) on p.ProductID = pc.ProductID 
    				join category c with (nolock) on pc.CategoryID = c.CategoryID
    				left join ProductManufacturer pm with (nolock) on p.ProductID = pm.ProductID
    				left join Manufacturer m with (nolock) on pm.ManufacturerID = m.ManufacturerID
    			where 
    				p.IsSystem=0 
    				and p.deleted = 0 
    				and p.published = 1 
    				and p.ExcludeFromPriceFeeds = 0 
    				and pv.isdefault = 1
    			]]>
    		</sql>
    	</query>
    	<PackageTransform>
    		<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aspdnsf="urn:aspdnsf"   xmlns:g="http://base.google.com/ns/1.0" exclude-result-prefixes="aspdnsf">
    			<xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="no" />
    
    			<xsl:param name="EntityName">
    				<xsl:value-of select="/root/QueryString/entity" />
    			</xsl:param>
    
    			<xsl:param name="ShowInGrid">true</xsl:param>
    			<xsl:param name="GridCols">4</xsl:param>
                <xsl:param name="UseDescr" select="aspdnsf:AppConfig('Froogle_UseDescriptionsIfFroogleDescEmpty')" />
    
                <xsl:param name="LocaleSetting" select="/root/Runtime/LocaleSetting" />
    			<xsl:param name="WebConfigLocaleSetting" select="/root/Runtime/WebConfigLocaleSetting" />
    
    			<xsl:template match="/">
                    <rss version="2.0">
                        <channel>
                            <title><xsl:value-of select="aspdnsf:AppConfig('StoreName')" /></title>
                            <link><xsl:value-of select="/root/System/StoreUrl" /></link>
                            <description><xsl:value-of select="aspdnsf:AppConfig('RSSChannelDescr')" /></description>
                            <language><xsl:value-of select="$WebConfigLocaleSetting" /></language> 
                            <pubDate><xsl:value-of select="/root/System/CurrentDateTime" /></pubDate>
                            <lastBuildDate><xsl:value-of select="/root/System/CurrentDateTime" /></lastBuildDate>
                            <xsl:apply-templates select="/root/Products/Product" />
                        </channel>
                    </rss>
                </xsl:template>
    			
    			<xsl:template match="Product">
    				<xsl:param name="SKU" select="aspdnsf:GetMLValue(SKU)"></xsl:param>
    				<xsl:param name="ProductID" select="aspdnsf:GetMLValue(ProductID)"></xsl:param>
    				<xsl:param name="ProductName" select="aspdnsf:GetMLValue(name)"></xsl:param>
                    <xsl:param name="ProductVariantName" select="aspdnsf:GetMLValue(VariantName)"></xsl:param>
                    <xsl:param name="ProductDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(description,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="VariantDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(variantdescr,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="ProductFroogleDescription" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(ProductFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
    		<xsl:param name="VariantFroogleDescription" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(VariantFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
                    <xsl:param name="ItemImage" select="aspdnsf:ProductImageUrl(productid, ImageFileNameOverride, SKU, 'medium', 1)"></xsl:param>
    				<xsl:param name="MerchantCategory" select="aspdnsf:GetMLValue(MerchantCategory)"></xsl:param>
    				<xsl:param name="Keywords" select="aspdnsf:GetMLValue(SEKeywords)"></xsl:param>
    				<xsl:param name="Manufacturer" select="aspdnsf:GetMLValue(Manufacturer)"></xsl:param>
    				<xsl:param name="MPN" select="aspdnsf:GetMLValue(ManufacturerPartNumber)"></xsl:param>
    				<xsl:param name="Weight" select="aspdnsf:GetMLValue(Weight)"></xsl:param>
    				<item>
    				<g:id>
    			<xsl:value-of select="productid" />
    			</g:id>
    					<sku>
    						<xsl:value-of select="$SKU" />
    					</sku>
                        <g:title>
    						<xsl:value-of select="$ProductName" />                    
    					</g:title>
                        <link>
    						<xsl:value-of select="/root/System/StoreUrl" /><xsl:value-of select="aspdnsf:ProductLink(productid, sename, 0, '')" />                   
    					</link>
                         <g:description>
    	<xsl:choose>
    		<xsl:when test="$VariantFroogleDescription!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantFroogleDescription, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:when test="$ProductFroogleDescription!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductFroogleDescription, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:when test="$VariantDescr!=''">
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantDescr, 1, 500))" disable-output-escaping="yes" />
    		</xsl:when>
    		<xsl:otherwise>
    		<xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductDescr, 1, 500))" disable-output-escaping="yes" />
    		</xsl:otherwise>
    	</xsl:choose>
    </g:description>
                        <g:image_link>
                            <xsl:if test="not(contains($ItemImage, 'nopicture'))">
                                <xsl:value-of select="$ItemImage" />
                            </xsl:if>
    					 </g:image_link>
    					<g:price>
                <xsl:choose>
                  <xsl:when test="number(saleprice)=0">
                    <xsl:value-of select="format-number((price), '###0.00')" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="format-number((saleprice), '###0.00')" />
                  </xsl:otherwise>
                </xsl:choose>
              </g:price>
    					
    					<g:id>
    					<xsl:value-of select="productid"/>
    					</g:id>
    					<g:product_type>
    						<xsl:value-of select="$MerchantCategory" />				
    					</g:product_type>
    					<g:brand>
    						<xsl:value-of select="$Manufacturer" />
    					</g:brand>
    			<g:mpn>
    		  	    <xsl:choose>
    				      <xsl:when test="ManufacturerPartNumber!=''">
                		      <xsl:value-of select="ManufacturerPartNumber" />
    				      </xsl:when>
    				      <xsl:when test="SKU!=''">
                		      <xsl:value-of select="SKU" />
    				      </xsl:when>
    				      <xsl:otherwise>
                		      <xsl:value-of select="productid" />
    				      </xsl:otherwise>
    			      </xsl:choose>
              </g:mpn>
              <g:condition>New</g:condition>
    									</item>
    			</xsl:template>			
    		</xsl:stylesheet>
    	</PackageTransform>
    </package>
    Last edited by mikemurphy; 09-06-2011 at 11:07 AM.
    8.0.1.4 W2008R2 64-bit MSSQL2005

  19. #19
    DotNetDevelopments is offline Senior Member
    Join Date
    Jul 2008
    Location
    Harlow / Essex / UK
    Posts
    619

    Default

    Quote Originally Posted by mikemurphy View Post
    2) We need to provide prices which include VAT - in our backend, we have net prices that are being extracted. Can we uplift the price in the xml package by 20% (the VAT level) ?

    3) We need to include an ISBN number (gtin) for our book products - any thoughts on where to store this value in the product data....in "Extension Data (User Defined Data)" ?....then how would we extract this ?
    In answer to them two question if you want the quick and easy way to add VAT to your feed just do *1.2 on the price/sale price which will add on 20%.

    For the ISBN number we had the same issue with barcodes for our products needed to be in gtin. As we do not have any products that are downloads we have simply used download location to hold barcodes/ISBN etc. It holds more than enough characters and is easy to call and update.

    Regards to duplicates you would have to use a distinct inside your sql to ensure you only call each product once.

    We are currently selling a google base feed that sends all variants and deals with the taxonomy issues for under £50, this feed also correctly handles VAT and multistore. If you want to know more about that just email us sales@dotnetdevelopments.co.uk.
    =====
    Version (Code/DB): AspDotNetStorefront MSx 9.1.0.1/9.1.0.0
    Execution Mode: 64 Bit
    Dot Net Developments - E-commerce By Experience

  20. #20
    mikemurphy is offline Senior Member
    Join Date
    Mar 2006
    Location
    United Kingdom
    Posts
    207

    Default

    umpphh !....i'm stumped here now. To sum up these are the things needed to sort the google feed.

    1) Include the first product from the list of duplicates (same product in multiple categories)

    2) Include a gtin value for each product (i thought about extention data field ??)

    Any help would be appreciated
    8.0.1.4 W2008R2 64-bit MSSQL2005

  21. #21
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default

    Hey Mike, if you would email me your feed I would be happy to take a look at what we have so far. I might be able to help you with all this. geoffrey@archerycenter.com

  22. #22
    gmaniac is offline Member
    Join Date
    Jul 2010
    Location
    Missouri
    Posts
    59

    Default

    After many emails between Mike and I, this is what we have come up with:

    feed.googlebase.xml.config

    Code:
    forum<?xml version="1.0" encoding="utf-8" ?>
    <!-- ###################################################################################################### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2009.  All Rights Reserved.					                -->
    <!-- http://www.aspdotnetstorefront.com														                -->
    <!-- For details on this license please visit  the product homepage at the URL above.		                -->
    <!-- THE ABOVE NOTICE MUST REMAIN INTACT.                                                                   -->
    <!-- ###################################################################################################### -->
    <package displayname="Google Base RSS 2.0 Feed" version="2.1" debug="false" includeentityhelper="false">
      <query name="Products" rowElementName="Product">
        <sql>
    
          <![CDATA[
    			select
    				p.productid, 
    				p.name, 
    				isnull(pv.name, '') VariantName, 
    				p.description, 
    				p.sename, 
    				p.ImageFileNameOverride, 
    				p.SKU, 
    				isnull(p.FroogleDescription, '') ProductFroogleDescription, 
    				p.SEKeywords,
    				p.ManufacturerPartNumber,
    				pv.price, 
    				isnull(pv.saleprice, 0) saleprice, 
    				isnull(pv.FroogleDescription, '') VariantFroogleDescription, 
    				isnull(pv.description, '') VariantDescr,
    				c.Name as MerchantCategory,
    				m.Name as Manufacturer,
    				pv.Weight
    			from 
    				dbo.product p with (nolock) 
    				join dbo.productvariant pv with (nolock) on p.productid = pv.productid
    				inner join productcategory pc with (nolock) on p.ProductID = pc.ProductID
    				inner join category c with (nolock) on pc.CategoryID = c.CategoryID
    				left join ProductManufacturer pm with (nolock) on p.ProductID = pm.ProductID
    				left join Manufacturer m with (nolock) on pm.ManufacturerID = m.ManufacturerID
    			where 
    				p.IsSystem=0 
    				and p.deleted = 0 
    				and p.published = 1 
    				and p.ExcludeFromPriceFeeds = 0 
    				and pv.isdefault = 1
    				and c.ParentCategoryID = 0
    			order by p.productid
    			]]>
        </sql>
      </query>
      <PackageTransform>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aspdnsf="urn:aspdnsf"   xmlns:g="http://base.google.com/ns/1.0" exclude-result-prefixes="aspdnsf">
          <xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="no" />
    
          <xsl:param name="EntityName">
            <xsl:value-of select="/root/QueryString/entity" />
          </xsl:param>
    
          <xsl:param name="ShowInGrid">true</xsl:param>
          <xsl:param name="GridCols">4</xsl:param>
          <xsl:param name="UseDescr" select="aspdnsf:AppConfig('Froogle_UseDescriptionsIfFroogleDescEmpty')" />
    
          <xsl:param name="LocaleSetting" select="/root/Runtime/LocaleSetting" />
          <xsl:param name="WebConfigLocaleSetting" select="/root/Runtime/WebConfigLocaleSetting" />
    
          <xsl:template match="/">
            <rss version="2.0">
              <channel>
                <title>
                  <xsl:value-of select="aspdnsf:AppConfig('StoreName')" />
                </title>
                <link>
                  <xsl:value-of select="/root/System/StoreUrl" />
                </link>
                <description>
                  <xsl:value-of select="aspdnsf:AppConfig('RSSChannelDescr')" />
                </description>
                <language>
                  <xsl:value-of select="$WebConfigLocaleSetting" />
                </language>
                <pubDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </pubDate>
                <lastBuildDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </lastBuildDate>
                <xsl:apply-templates select="/root/Products/Product" />
              </channel>
            </rss>
          </xsl:template>
    
          <xsl:template match="Product">
            <xsl:param name="SKU" select="aspdnsf:GetMLValue(SKU)"></xsl:param>
            <xsl:param name="ProductID" select="aspdnsf:GetMLValue(ProductID)"></xsl:param>
            <xsl:param name="ProductName" select="aspdnsf:GetMLValue(name)"></xsl:param>
            <xsl:param name="ProductVariantName" select="aspdnsf:GetMLValue(VariantName)"></xsl:param>
            <xsl:param name="ProductDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(description,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
            <xsl:param name="VariantDescr" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(variantdescr,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
            <xsl:param name="ProductFroogleDescription" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(ProductFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
            <xsl:param name="VariantFroogleDescription" select="aspdnsf:StripHtml(aspdnsf:GetMLValue(VariantFroogleDescription,$WebConfigLocaleSetting,'FALSE'))"></xsl:param>
            <xsl:param name="ItemImage" select="aspdnsf:ProductImageUrl(productid, ImageFileNameOverride, SKU, 'medium', 1)"></xsl:param>
            <xsl:param name="MerchantCategory" select="aspdnsf:GetMLValue(MerchantCategory)"></xsl:param>
            <xsl:param name="Keywords" select="aspdnsf:GetMLValue(SEKeywords)"></xsl:param>
            <xsl:param name="Manufacturer" select="aspdnsf:GetMLValue(Manufacturer)"></xsl:param>
            <xsl:param name="MPN" select="aspdnsf:GetMLValue(ManufacturerPartNumber)"></xsl:param>
            <xsl:param name="Weight" select="aspdnsf:GetMLValue(Weight)"></xsl:param>
            
    
              <item>
                <g:id>
                  <xsl:value-of select="productid" />
                </g:id>
                <sku>
                  <xsl:value-of select="$SKU" />
                </sku>
                <g:title>
                  <xsl:value-of select="$ProductName" />
                </g:title>
                <link>
                  <xsl:value-of select="/root/System/StoreUrl" />
                  <xsl:value-of select="aspdnsf:ProductLink(productid, sename, 0, '')" />
                </link>
                <g:description>
                  <xsl:choose>
                    <xsl:when test="$VariantFroogleDescription!=''">
                      <xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantFroogleDescription, 1, 500))" disable-output-escaping="yes" />
                    </xsl:when>
                    <xsl:when test="$ProductFroogleDescription!=''">
                      <xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductFroogleDescription, 1, 500))" disable-output-escaping="yes" />
                    </xsl:when>
                    <xsl:when test="$VariantDescr!=''">
                      <xsl:value-of select="aspdnsf:HtmlEncode(substring($VariantDescr, 1, 500))" disable-output-escaping="yes" />
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="aspdnsf:HtmlEncode(substring($ProductDescr, 1, 500))" disable-output-escaping="yes" />
                    </xsl:otherwise>
                  </xsl:choose>
                </g:description>
                <g:image_link>
                  <xsl:if test="not(contains($ItemImage, 'nopicture'))">
                    <xsl:value-of select="$ItemImage" />
                  </xsl:if>
                </g:image_link>
                <g:price>
                  <xsl:choose>
                    <xsl:when test="number(saleprice)=0">
                      <xsl:value-of select="format-number((price), '###0.00')" />
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="format-number((saleprice), '###0.00')" />
                    </xsl:otherwise>
                  </xsl:choose>
                </g:price>
                <g:id>
                  <xsl:value-of select="productid"/>
                </g:id>
                <g:product_type>
                  <xsl:value-of select="$MerchantCategory" />
                </g:product_type>
                <g:brand>
                  <xsl:value-of select="$Manufacturer" />
                </g:brand>
                <g:mpn>
                  <xsl:choose>
                    <xsl:when test="ManufacturerPartNumber!=''">
                      <xsl:value-of select="ManufacturerPartNumber" />
                    </xsl:when>
                    <xsl:when test="SKU!=''">
                      <xsl:value-of select="SKU" />
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="productid" />
                    </xsl:otherwise>
                  </xsl:choose>
                </g:mpn>
                <g:condition>New</g:condition>
              </item>
    
          </xsl:template>
        </xsl:stylesheet>
      </PackageTransform>
    </package>
    Now we need help on one last thing. Whenever a product is in multiple categories/mappings it lists each as a separate item, making duplicate products. Does anyone know of a check that can be ran to stop this from happening? I know there are several ways of doing this just like most things, through; SQL query, in the config file using xsl, or even run something the generated xml. We just can't seem to get it to work correctly, any help is appreciated.

    Would also like to mention, for those of you that need to add tax yourself. Here is what we came up with:
    Code:
    <g:tax>
      <g:rate>
          <xsl:choose>
              <xsl:when test="number(saleprice)=0">
                  <xsl:value-of select="format-number((price * 1.2), '###0.00')" />
              </xsl:when>
              <xsl:otherwise>
                  <xsl:value-of select="format-number((saleprice * 1.2), '###0.00')" />
              </xsl:otherwise>
          </xsl:choose>
      </g:rate>
    </g:tax>
    This was set at 1.2 because mike needed each product at 20% VAT/tax.

  23. #23
    usascholar is offline Member
    Join Date
    Jan 2010
    Posts
    64

    Default

    If you don't care about the category too much, you can replace the 'from' including all the tables in the SQL with this, just stop at the 'Where' clause, don't overwrite the 'where' in the SQL, everything above it up to the 'From' is fine to overwrite:



    Code:
    			from 
    				dbo.product p with (nolock) 
    				join dbo.productvariant pv with (nolock) on p.productid = pv.productid
    				join (Select ProductID, MIN(CategoryID) as CategoryID from productcategory group by ProductID) pc on p.ProductID = pc.ProductID 
    				join category c with (nolock) on pc.CategoryID = c.CategoryID
    				left join ProductManufacturer pm with (nolock) on p.ProductID = pm.ProductID
    				left join Manufacturer m with (nolock) on pm.ManufacturerID = m.ManufacturerID
    Note, it will show only the category with the lowest CategoryID for the product. But it kills the duplicates.

    Cheers
    A