<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A danish blog about Javascript and Webdevelopment</title>
	<atom:link href="http://rune.gronkjaer.dk/en-US/feed/" rel="self" type="application/rss+xml" />
	<link>http://rune.gronkjaer.dk/en-US</link>
	<description>Rune Grønkjær</description>
	<lastBuildDate>Tue, 15 May 2012 07:51:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Tea Commerce Master product</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/09/08/tea-commerce-master-product/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/09/08/tea-commerce-master-product/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 09:31:00 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[xslt]]></category>
		<category><![CDATA[ecommerce]]></category>
		<category><![CDATA[languages]]></category>
		<category><![CDATA[umbraco]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=473</guid>
		<description><![CDATA[This blog post will explain how Master products works in Tea Commerce.]]></description>
			<content:encoded><![CDATA[This blog post will explain how Master products works in Tea Commerce.
<h2>What is a Master Product in Tea Commerce? </h2>
First and foremost you must understand that Tea Commerce products are just ordinary content nodes in Umbraco. The nodes have a number of custom properties which is the content of the node. Umbraco structures the nodes in xml which makes it possible for nodes to inherit properties from nodes further up the tree.
<h3>Product variants </h3>
For product nodes, this means that you can make product variants to a product node. This is used in <a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">the Tea Commerce Starter Kit</a>, where some products have variants. <br /> <br />
As you can see in Figure 1 below there is a red and a blue variant under &#8220;Product A1&#8243;. It allows you to leave the main product contain the bulk of product information, so the variants just need information about stock condition, product name and possibly other properties that differ on the variants from the main product. The arrow indicates how variants inherit from their main product.
<h4>Fig. 1 &#8211; Variants in Tea Commerce </h4>
<img src="http://www.teacommerce.dk/blogmedia/images/normal-variants.png" alt="Variants in Tea Commerce" class="illustration" />
<h3>Tea Commerce Master Product</h3>
With a Tea Commerce Master product we move on and makes a product inherit from a product that is placed somewhere else in the content tree. This type of setup we use in <a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">the Tea Commerce Multilanguage Kit</a>. <br /> <br />
Figure 2 shows how the inheritance would be if the red variant had a master product attached. In figure 3 you can see how it is done without variants.
<h4> Fig. 2 &#8211; Master product and variants in Tea Commerce </h4>
<img src="http://www.teacommerce.dk/blogmedia/images/variants-masterproduct.png" alt="Master product and variants in Tea Commerce" class="illustration" />
<h4> Fig. 3 &#8211; Master product without variants in Tea Commerce </h4>
<img src="http://www.teacommerce.dk/blogmedia/images/masterproduct-no-variants.png" alt="Master product without variants in Tea Commerce" class="illustration" />
<h2>How to setup Tea Commerce Master products</h2>
To get your products to use a Master product, you must set up a couple of things in Tea Commerce and Umbraco. To see an example of how it looks when Master products are set up correctly, try to install <a href = "http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit . aspx ">the Tea Commerce Multilanguage Kit</a> which uses the Master products.
<h3>1. The product Document Type </h3>
The products must have a Master product property for selecting an Umbraco node. This property we can call &#8220;Master Product&#8221; and give it the alias &#8220;masterProduct.&#8221; Its type must be something that can give us the ID of the product master node. The type may well be a plain text field, but a Content Picker or a UComponents Multi Node tree picker would be preferable for the user. The latter is especially good because it can restrict user options.
<h3>2. Set up the Tea Commerce section </h3>
Now you go to &#8220;General Settings&#8221; in the Tea Commerce section. Here you write the alias of the property we just created in the field &#8220;Master product property alias&#8221;. Now Tea Commerce knows what to look for, to find the products Master product.
<h3>3. Choose a Master product on one of your products </h3>
Now you create a master product and then create a product that is pointing down at the Master product with its &#8220;masterProduct&#8221; property.
<h3>4. Print product info on your product page </h3>
Now we just need to write the information of the product on the website&#8217;s product page. To retrieve a property from the product the Tea Commerce xslt library have a method called GetProperty that gets the job done for you. GetProperty takes two parameters, the first being the product node itself and the other is the alias of the property you wish to fetch.
<h2>How Tea Commerce Master products works</h2>
To date Tea Commerce have three scenarios in which Master products are used. One is the before mentioned GetProperty method. The second is another library method called GetStock, which is used to retrieve the stock level for a product. The third scenaro, in which Master products are used, is when a product is added to the cart and Tea Commerce is adding product information to the new order line. <br /> <br />
Common to all three is the way Tea Commerce will attempt to retrieve information from the product. Based on the setup in Figure 2 we can explain it this way:
<ol>
<li>We query after e.g. the property &#8220;productPrice&#8221; on the product &#8220;Red&#8221;, with the library method GetProperty.</li>
<li>Tea Commerce will first query the node &#8220;Red&#8221; itself. If it has a property called &#8220;productPrice&#8221; and the property is not blank the search stops right here. </li>
<li>If nothing was found the search is continued up through the node tree starting at the node &#8220;Red&#8221;. Now it will then search through, the node &#8220;Product A1&#8243; but also &#8220;Category A&#8221;, &#8220;Products&#8221;, etc. The search is done by xpathing the Umbraco cached XML, so performance is kept high.</li>
<li>If Tea Commerce still have not found anything it will find &#8220;Red&#8221;&#8216;s Master product and based on this will do the same search up through the tree, hopefully finding what it was asked. </li>
</ol>
<h2>What is the use of Tea Commerce Master products? </h2>
<h3>Language localization of Tea Commerce products </h3>
The whole idea with Master products in Tea Commerce, has always been to make it easy to language localize your products. The idea in this situation is to let the Master products contain all the information about the product that is not language specific. That way you will not have to enter this information again and again, in all languages, which could cause big problems with keeping data consistent. At the individual product focus can lie on typing texts in the language you are working on. You may read more about this in <a href="http://rune.gronkjaer.dk/blog/?p=968"> this blog post about languages, countries and currencies </a>.
<h3>One product in multiple categories</h3>
You can also use Master products to position the same product in several categories. You will be able to create all products outside the regular content tree and then create lightweight products that just link down to a master product. The lightweight products does not hold any product information and Tea Commerce will then retrieve all information from their master product.
<h2>A concrete example </h2>
In the example below, I will get a product name, stock and price from a product. The example uses variants like in Figure 2 and to be sure that I get a variant to start with, I choose the variant that I know is a leaf node. A leaf node is one of the outer nodes of the tree. If I&#8217;m already on one of the variants this variant is chosen. If I&#8217;m on the main product, the first variant will be selected. If there is no variants, the main product get elected.
<h4>Example of the use of Master products </h4>
<pre class="brush: xslt">
<xsl:template match="Product">
  <!-- Get the variant. -->
  <xsl:variable name="variant" select="./descendant-or-self::Product [not(child::Product)][1]"/>

  <!-- Use GetProperty to get the productName property value -->
  <xsl:variable name="productName" select="teacommerce:GetProperty($variant, 'productName')" />

  <!-- Use GetStock to fetch the stock of the product -->
  <xsl:variable name="stock" select="teacommerce:GetStock($variant)" />

  <!-- Use GetProperty to get the price of the product and FormatPriceNoSymbol to format it nicely -->
  <xsl:variable name="price" select="teacommerce:FormatPriceNoSymbol(teacommerce:GetProperty($variant, 'productPrice'))" />
</xsl:template>
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/09/08/tea-commerce-master-product/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tea Commerce server side validation</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/08/18/tea-commerce-server-side-validation/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/08/18/tea-commerce-server-side-validation/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 10:48:42 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[xslt]]></category>
		<category><![CDATA[umbraco]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=482</guid>
		<description><![CDATA[Tea Commerce is all about great design and a cool javaScripts. For this reason it is easy to forget the need for server side validation of customer data. To place an order, a user would have put something in his cart, but he may also need to enter some specific data about himself or the order. In most cases common javascript validation will be sufficient, but JavaScript validation can be cheated. If it is important to collect valid data, server side validation will be needed.]]></description>
			<content:encoded><![CDATA[Tea Commerce is all about great design and a cool javaScripts. For this reason it is easy to forget the need for server side validation of customer data. To place an order, a user would have put something in his cart, but he may also need to enter some specific data about himself or the order. In most cases common javascript validation will be sufficient, but JavaScript validation can be cheated. If it is important to collect valid data, server side validation will be needed.
<h2>The scenario for server side validation in Tea Commerce </h2>
Basically I intend to validate step 2 of the cart process, where, in most cases, customer information is entered. My solution must make sure to check whether the data is filled out correctly, whenever the customer tries to go to a step beyond step 2.<br /> <br />
There must also be taken into account localization of the cart. This means that I do not want to hard code any IDs in my server side code. I also need to check whether there is an order and the order has associated order lines. If the order does not validate, I will send people back to the step that failed validation.
<h2>How to do server side validation in Tea Commerce </h2>
Server side validation is not standard in Tea Commerce. Luckily the Tea Commerce .NET API gives us plenty of options to do it ourselves. There is undoubtedly lots of ways to solve the problem. However, I have chosen to do it with an Umbraco XSLT library extension, which have the oportunity to redirect the customers to other pages. <br /> <br />
I will therefore make an Umbraco  XSLT library method that can be called from any of the xslt&#8217;s. More specifically, it should be called on the steps that come after step 2, and send the customer back if validation fails.
<h2>The Umbraco XSLT library extension</h2>
There is not much to write about this and I will let the code and the embedded comments speak for themselves. However, I can give you this checklist with the things you must handle before it will work. The code for everything is found a little further down.
<ol>
<li>
Build a dll with the Umbraco library extension and upload it to the bin folder
</li>
<li>
Register your XSLT extension in the file /config/xsltExtensions.config
</li>
<li>
Make the method call in your xslt&#8217;s. Remember that the new extension must be registered in the xslt itself. New xslt&#8217;s automatically get your extension inserted into the xsl:stylesheet tag. You can make a new one and copy the entire top of that if you have allready made your cart xslt&#8217;s
</li>
</ol>
<h4> Full XSLT library extension code </h4>
<pre class="brush: csharp">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TeaCommerce;
using TeaCommerce.Data;

namespace ServersideValidation {
  public class Library {

    public Library() {
      //This has to be here, because of the way umbraco runs xslt extension
    }

    public static string ValidateOrder( int currentStepId, int cartStep2Id ) {
      try {
        //Test to make sure we are not logged in at the back end
        var test = HttpContext.Current.CurrentHandler as umbraco.BasePages.UmbracoEnsuredPage;
        if ( test == null ) {

          //Get the order
          Order order = TeaCommerce.Razor.TeaCommerce.GetOrder();

          //If there is no order we redirect to step 1 of the cart
          if ( order == null || order.OrderLines.Count() == 0 )
            HttpContext.Current.Response.Redirect( umbraco.library.NiceUrl( cartStep2Id ) + "?validate=false", true );

          //If the current step is not step 1 we validate the data on that step
          if ( currentStepId != cartStep2Id ) {
            //Get the values we must validate
            string firstName = order.GetPropertyValue( "firstName" ),
                  lastName = order.GetPropertyValue( "lastName" ),
                  streetAddress = order.GetPropertyValue( "streetAddress" ),
                  zipCode = order.GetPropertyValue( "zipCode" ),
                  city = order.GetPropertyValue( "city" ),
                  email = order.GetPropertyValue( "email" );

            //Simple validation of the values
            if ( string.IsNullOrEmpty( firstName ) ||
                 string.IsNullOrEmpty( lastName ) ||
                 string.IsNullOrEmpty( streetAddress ) ||
                 string.IsNullOrEmpty( zipCode ) ||
                 string.IsNullOrEmpty( city ) ||
                 string.IsNullOrEmpty( email ) ) {
              //Go back to step 1 if validation fails
              HttpContext.Current.Response.Redirect( umbraco.library.NiceUrl( cartStep2Id ) + "?validate=false", true );
            }
          }
        }
      } catch ( Exception ex ) {
        return ex.Message;
      }
      return string.Empty;
    }
  }
}
</pre>
<h4>The registration in Umbraco&#8217;s /config/xsltExtensions.config file</h4>
<pre class="brush: xml">
<?xml version="1.0" encoding="utf-8"?>
<XsltExtensions>
  <ext assembly="/TeaCommerce" type="TeaCommerce.Library" alias="teacommerce"></ext>
  <ext assembly="/ServersideValidation" type="ServersideValidation.Library" alias="ServersideValidation"></ext>
</XsltExtensions>
</pre>
<h4>The method call in cartStep03.xslt (And presumably in subsequent steps)</h4>
<pre class="brush: xml">
&lt;xsl:template match="/">
<!-- I have chosen to use a dictionary item to save the id of the step 2 page -->
&lt;xsl:variable name="step2PageId" select="umbraco.library:GetDictionaryItem('step2PageId')"/>
&lt;xsl:value-of select="ServersideValidation:ValidateOrder($currentPage/@id, $step2PageId)" />
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/08/18/tea-commerce-server-side-validation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Analytics e-commerce</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/08/10/google-analytics-e-commerce/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/08/10/google-analytics-e-commerce/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 06:06:24 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[xslt]]></category>
		<category><![CDATA[ecommerce]]></category>
		<category><![CDATA[umbraco]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=478</guid>
		<description><![CDATA[Do you know who your paying customers on your site is? And do you have an overview of what and how much they buy? To know this, you need to know how your customers move on your website. Google Analytics provides, as standard lots of opportunities to explore your users' behavior, but with a few additions to Google analytics and your shop, you will have even more knowledge.]]></description>
			<content:encoded><![CDATA[Do you know who your paying customers on your site is? And do you have an overview of what and how much they buy? To know this, you need to know how your customers move on your website. Google Analytics provides, as standard lots of opportunities to explore your users&#8217; behavior, but with a few additions to Google analytics and your shop, you will have even more knowledge. <br /> <br />
In this blog post I will show how you can use the Google Analytics E-commerce function. It&#8217;s not that hard, and gives you lots of new statistic data.
<h2>What can I use Google Analytics e-commerce for? </h2>
Google Analytics e-commerce will be used to track the trade that occurres on your website. You can see how well your site converts users for sale and how much they buy. Where it might be really interesting is that e-commerce statistics also become intertwined with the usual statistics on the website. In this blog post I will not go through all the possibilities, but write how you&#8217;re going to collect the data to have them.
<h2>Tea Commerce and Google Analytics e-commerce </h2>
To collect statistics on your users&#8217; purchases on your shop, we have set up two things. Firstly, the e-commerce part  of Google Analytics needs to be activated. The second thing will be to insert a piece of code in Google&#8217;s tracking JavaScript in your e-commerce website.
<h3>Setting up Google Analytics e-commerce </h3>
To turn on Google Analytics e-commerce you need to go to the settings for your websites Google Analytics. Google explains it pretty well on <a href="http://www.google.com/support/analytics/bin/answer.py?answer=55528" title="How do I track e-commerce transactions?"> this page </a>, but below I have just
repeated what should be done.
<h4>How do I track e-commerce transactions?</h4>
<ol>
<li>
Sign in to your account.
</li>
<li>
Click Edit next to the profile you&#8217;d like to enable.
</li>
<li>
On the Profile Settings page, click Edit next to Main Website Profile Information.
</li>
<li>
Change the E-Commerce Website radio button from No to Yes.
</li>
</ol>
Once you&#8217;ve done this a new menu item called &#8220;E-Commerce&#8221; will be available underneath your website&#8217;s other statistics in Google Analytics. There will also be Ecommerce tabs in different parts of the normal statistics. Of course there are no data yet. They will first be collected when you&#8217;ve done the following.
<h2>Tracking your e-commerce orders </h2>
Now we need to insert some JavaScript into the normal tracking script from google. The starting point should hopefully be something like what you see below and it will probably be in the header of the website. I have inserted a comment where our tracking code to the e-commerce will be placed.
<h4> Google analytics standard tracking code </h4>
<pre class="brush: js">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-3982655-28']);
_gaq.push(['_trackPageview']);

/* INSERT E-COMMERCE TRACKING HERE */

(function () {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</pre>
<br /><br/>
Now we need to generate the JavaScript that will provide information about the order. We must ensure that it only appears when the user has completed his order and we must send various information about the order and its order lines. Google has written great deal of documentation on the subject, of course, and <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingEcommerce.html" title="Google code Ecommerce Tracking"> you can read it here</a>.
<h3>Generating the Tea Commerce order data with XSLT </h3>
I made a piece of code that can be used in all Tea Commerce webshops. Just be sure to check my aliases against your own. Create a new xslt file and macro called &#8220;googleEcommcereTracking.xslt&#8221; and paste the following in the template tag. Remember that the right ID on the confirmation page, which is in the first &#8220;if&#8221; condition.
<h4> Tea Commerce Google Analytics e-commerce tracking code </h4>
<pre class="brush: xslt">
<!-- Only write the script if we are on the order confirmation page -->
<xsl:if test="$currentPage/@id = 1174">
  <!-- The finalized order -->
  <xsl:variable name="order" select="teacommerce:GetFinalizedOrderXml()" />
  <!-- If theres no order, theres no point in continueing -->
  <xsl:if test="$order != ''">
    <!-- General information about the order -->
    _gaq.push(['_addTrans',
      '<xsl:value-of select="$order/@id" />',           // order ID - required
      'runeswebshop.com',  // affiliation or store name
      '<xsl:value-of select="$order/@totalPriceWithoutVAT" />', // total - required
      '<xsl:value-of select="$order/@totalVAT" />',             // tax
      '<xsl:value-of select="$order/shipping/@feeWithoutVAT" />',// shipping
      '<xsl:value-of select="$order/properties/city" />',        // city
      '',                                                        // state or province
      '<xsl:value-of select="$order/properties/country" />'      // country
    ]);
    <!-- Loop the order lines -->
    <xsl:for-each select="$order/orderLine">
     // add item might be called for every item in the shopping cart
     // where your ecommerce engine loops through each item in the cart and
     // prints out _addItem for each
    _gaq.push(['_addItem',
      '<xsl:value-of select="$order/@id" />',               // order ID - required
      '<xsl:value-of select="properties/productNumber" />', // SKU/code - required
      '<xsl:value-of select="properties/productName" />',   // product name
      '<xsl:value-of select="umbraco.library:GetXmlNodeById(@nodeId)/ancestor-or-self::ProductCategory/@nodeName" />',   // category or variation
      '<xsl:value-of select="@unitPriceWithoutVAT" />',     // unit price - required
      '<xsl:value-of select="@quantity" />'                 // quantity - required
    ]);
    </xsl:for-each>
    _gaq.push(['_trackTrans']); //submits transaction to the Analytics servers
  </xsl:if>
</xsl:if>
</pre>
<br /><br/>
Now we just have to insert our new macro in the Google Analytics tracking code in the websites header. The tracking code will now look as follows.
<h4>Tracking Code with e-commerce tracking macro </h4>
<pre class="brush: js">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-3982655-28']);
_gaq.push(['_trackPageview']);

<umbraco:Macro Alias="GoogleEcommcereTracking" runat="server"></umbraco:Macro>

(function () {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</pre>
<br /><br />
That should do it. When we now run a test order and reaches the order confirmation, the google tracking code should look like the below. On all other pages, the tracking code will look just as usual. Now, your webshop will start collecting data and you will not miss out on some great statistics.
<h4>Google Analytics tracking code on the order confirmation page</h4>
<pre class="brush: js">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-3982655-15']);
_gaq.push(['_setDomainName', 'none']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);


_gaq.push(['_addTrans',
      '56',                 // order ID - required
      'runeswebshop.com',   // affiliation or store name
      '10400.0000000000',   // total - required
      '2600.00000000000000',// tax
      '0.00000',            // shipping
      'Herning',            // city
      '',                   // state or province
      '1'                   // country
    ]);


// add item might be called for every item in the shopping cart
// where your ecommerce engine loops through each item in the cart and
// prints out _addItem for each
_gaq.push(['_addItem',
      '56',                                 // order ID - required
      '8040000065',                         // SKU/code - required
      'Vedligeholdelsesfrit havemøbelsæt',  // product name
      'Havemøbler',                         // category or variation
      '8000.0',                             // unit price - required
      '1'                                   // quantity - required
    ]);


// add item might be called for every item in the shopping cart
// where your ecommerce engine loops through each item in the cart and
// prints out _addItem for each
_gaq.push(['_addItem',
      '56',           // order ID - required
      '1130000001',   // SKU/code - required
      'RENSDYRSKIND', // product name
      'Interiør',     // category or variation
      '1200.0',       // unit price - required
      '2'             // quantity - required
    ]);

_gaq.push(['_trackTrans']); //submits transaction to the Analytics servers


(function () {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/08/10/google-analytics-e-commerce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tea Commerce languages, countries and currencies</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/07/15/tea-commerce-languages-countries-and-currencies/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/07/15/tea-commerce-languages-countries-and-currencies/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 13:01:06 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[lande]]></category>
		<category><![CDATA[sprog]]></category>
		<category><![CDATA[umbraco]]></category>
		<category><![CDATA[valuta]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=462</guid>
		<description><![CDATA[Countries, currencies and languages have a very central function in Tea Commerce and it is important
to understand how they work. I will list the most important knowledge them below.]]></description>
			<content:encoded><![CDATA[These three concepts have a very central function in Tea Commerce and it is important
to understand how they work. I will list the most important knowledge them below.
<h2>
  How does countries work in Tea Commerce?</h2>
<ul>
  <li>When a new order is created the country of this order is set to the default country.</li>
  <li>You can change the country of the order via the JavaScript API or the .NET API
    at any time you wish.</li>
  <li>Contries holds a lot default information for the order including currency, shipping method, payment method and VAT group.</li>
</ul>
<h2>
  How does currencies work in Tea Commerce?</h2>
<ul>
  <li>When a new order is created the order currency is automatically set to the standard-currency
    on the orders current country. </li>
  <li>You can always change the orders currency via JavaScript API or. NET API. </li>
  <li>To be able to change to a specific currency, the currency must be available in
    the current country. This is done one each currency in the Tea Commerce section.
  </li>
  <li>Whenever you change the country, Tea Commerce will check if the current currency
    is allowed in the NEW country.
    <ul>
      <li>If the currency IS allowed in the new country, the currency stays the way it is.
      </li>
      <li>If the currency IS NOT allowed in the country, the order&#8217;s currency is changed
        to the default currency of the new country. </li>
    </ul>
  </li>
</ul>
<h2>
  What is languages in Tea Commerce?</h2>
<ol>
  <li>To get the most out of languages in Tea Commerce, you must use a setup like the
    one in <a title="Download the Tea Commerce Multilanguage Kit" href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">
      Tea Commerce Multilanguage Kit</a></li>
  <li>Languages have nothing to do with countries or currencies!</li>
  <li>The order&#8217;s umbracoLanguage consists of an ID that matches one of the Languages
    set up in umbraco&#8217;s &#8220;Settings&#8221;</li>
  <li>Everytime a product is added to the order the umbracoLanguage of the order is
    set automatically.</li>
  <li>When setting the umbracoLanguage Tea Commerce will start with the product node
    and look up the content tree to find the first node with a hostname attached.</li>
  <li>As there can be more than one hostname on the node, Tea Commerce will first try
    and find one that matches the hostname currently used.</li>
  <li>If it cannot find a match, it will just take the first one available.</li>
  <li>The language of the hostname will then be added to the order.</li>
  <li>If no language is found whatsoever, the language will be set to 0 and the order
    will just run without a language.</li>
</ol>
<p>
  How does languages work in Tea Commerce?</p>
<ol>
  <li>It&#8217;s all about localization. If you have a multilanguageshop, using a setup like
    the one in our <a title="Download the Tea Commerce Multilanguage Kit" href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">
      Tea Commerce Multilanguage Kit</a>, there will be products in different language.</li>
  <li>Every product have a master product which holds all the basic product information.
    The products themselves holds all the language specific information.</li>
  <li>When a product is added to the order, the products master product is first found.</li>
  <li>Then all the products linked to that master product is found</li>
  <li>Tea Commerce will then add order line properties, from all the language specific
    products and, to the order line.</li>
  <li>Any product that does not have a language will be will just be added with a language
    = 0 which mean default information.</li>
  <li>When the order is requested by the JavaScript or the xslt Tea Commerce will merge
    the information into a full list of properties.</li>
  <li>Properties with a language will overwrite those without a language</li>
  <li>This means that you end up with language specific order line properties</li>
  <li>Whenever you change the orders umbracoLanguage, the order line properties will
    change acordingly</li>
</ol>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/07/15/tea-commerce-languages-countries-and-currencies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading to Tea Commerce 1.4</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/06/29/upgrading-to-tea-commerce-1-4/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/06/29/upgrading-to-tea-commerce-1-4/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 11:53:48 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[Blog post]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=450</guid>
		<description><![CDATA[SORRY! We are doing it again! We have once and for all, following requests from you wonderful people in the Umbraco community, refactored the JavaScript API. What we&#8217;ve done now is to create a settings object that can be extended indefinitely. First upgrade Tea Commerce Go and download Tea Commerce at our Umbraco. Then install [...]]]></description>
			<content:encoded><![CDATA[SORRY! We are doing it again! We have once and for all, following requests from you wonderful people in the Umbraco community, refactored the JavaScript API. What we&#8217;ve done now is to create a settings object that can be extended indefinitely. <br /> <br />
<h2>First upgrade Tea Commerce</h2>
Go and download <a href="http://our.umbraco.org/projects/website-utilities/tea-commerce">Tea Commerce at our Umbraco</a>. Then install it as you do any package in Umbraco. Tea Commerce will update itself without you having to do anything else. After that you need to fix your own JavaScript files, where you use the Tea Commerce API. Below you can read about how.
<h2> All Tea Commerce&#8217;s Kit has been updated </h2>
All the Kit&#8217;s have been updated to use the new configuration of the Tea Commerce JavaScript API, so you will be able to download and look at them.
<ul>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multi Language Starter Kit</a></li>
</li>
</ul>
<h2> JavaScript API documentation has been updated </h2>
<a href="http://rune.gronkjaer.dk/en-US/2010/11/16/tea-commerce-javascript-api/">The JavaScript API documentation </a> have been updated to show how to use the new API. So here you can find info about all methods that are not mentioned in this blog post.
<h2> What has changed? </h2>
In short, we moved all the voluntary parameters into a setting objects on ALL methods. You should be aware of the following parameters if you use them.
<ul>
<li>
umbracoLanguageId
</li>
<li>
async
</li>
<li>
successfn
</li>
<li>
errorfn
</li>
<li>
dataType
</li>
<li>
properties
</li>
</ul>
<h2> A few examples </h2>
Below I have included a few examples of how you can easily correct your method calls. Notice that I use two different approaches in the two examples, to add the settings object. Both options can be used in all methods.
<h4>addOrderLine</h4>
<pre class="brush: js">
//BEFORE 1.4
TeaCommerce.addOrderLine(productid, quantity, true, function (data) {
    //Success function content
  }, function (data) {
    //Error function content
  }
);

//AFTER 1.4
TeaCommerce.addOrderLine(productid, quantity,
  {
  async: true,
  successfn: function (data) {
    //Success function content
  },
  errorfn: function (data) {
    //Error function content
  }
});
</pre>
<h4>removeOrderLine</h4>
<pre class="brush: js">
//BEFORE 1.4
TeaCommerce.removeOrderLine(productId, true, function (data) {
    //Success function content
  }
);

//AFTER 1.4
var settings = {
  async: true,
  successfn: function (data) {
    //When the server answers we update the orderline in the UI
    removeOrderLineFromUI(orderlineEle);
  } 
}
TeaCommerce.removeOrderLine(productId, settings);
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/06/29/upgrading-to-tea-commerce-1-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading to Tea Commerce 1.3</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/06/10/upgrading-to-tea-commerce-1-3/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/06/10/upgrading-to-tea-commerce-1-3/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 10:21:38 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[xslt]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[languages]]></category>
		<category><![CDATA[umbraco]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=432</guid>
		<description><![CDATA[This blog post describes how you can update your Tea Commerce ecommerce from a pre v1.3 Tea Commerce to a v1.3 +. <br />
Upgrading Your Tea Commerce solution to 1.3 means that you probably should have addressed some of your JavaScript. As you can read in the <a href="http://www.teacommerce.dk/en/documentation/revision-history.aspx"> Tea Commerce revision history </a> a few <strong> breaking changes </strong> have been made in the core JavaScript file. Don't panic... It can be easily solved.]]></description>
			<content:encoded><![CDATA[<h4> UPDATE </h4>
In <strong> Tea Commerce 1.4 </strong>, we have once and for all changed the Tea Commerce JavaScript API. <a href="http://rune.gronkjaer.dk/blog/2011/06/29/opgradering-til-tea-commerce-1-4/"> Read here what to do! </a>
<hr />
This blog post describes how you can update your Tea Commerce ecommerce from a pre v1.3 Tea Commerce to a v1.3 +. <br />
Upgrading Your Tea Commerce solution to 1.3 means that you probably should have addressed some of your JavaScript. As you can read in the <a href="http://www.teacommerce.dk/en/documentation/revision-history.aspx"> Tea Commerce revision history </a> a few <strong> breaking changes </strong> have been made in the core JavaScript file. Don&#8217;t panic&#8230; It can be easily solved.
<h2> Affected Tea Commerce methods </h2>
<ul>
    <li>TeaCommerce.invokeXSLT(xsltFile, nodeId, umbracoLanguageId, async, successfn, errorfn, dataType )</li>
    <li>TeaCommerce.updateOrderLineProperty(nodeId, propertyAlias, propertyValue, umbracoLanguageId, async, successfn, errorfn)</li>
    <li>TeaCommerce.updateUniqueOrderLineProperty( orderLineId, propertyAlias, propertyValue, umbracoLanguageId, async, successfn, errorfn)</li>
    <li>TeaCommerce.updateOrderLineProperties(nodeId, propertyList, umbracoLanguageId, async, successfn, errorfn)</li>
    <li>TeaCommerce.updateUniqueOrderLineProperties(orderLineId, propertyList, umbracoLanguageId, async, successfn, errorfn)</li>
</ul>
The five methods above have been given new signatures. They all need a umbracoLanguageId to language version the order lines. <br /> <br />
<strong> NOTE: </strong> updateUniqueOrderLineProperty and updateUniqueOrderLineProperties have furthermore had their nodeId parameter removed, as there was no need for it. They only need an order line ID for identification.
<h2>How to quickly fix your website </h2>
<h3> 1. Make sure that all your products have an associated domain </h3>
There must be a domain on one node up the node tree in umbraco. The domain has an associated language and with that we are able to get the language and use it. By right clicking on one of your outer nodes (Maybe a root node) and selecting &#8220;Manage Host Names&#8221; you can add a domain.
<h3> 2. Update Tea Commerce to version 1.3 + </h3>
Now you need to update Tea Commerce to version 1.3 +. You can download the latest version <a href="http://our.umbraco.org/projects/website-utilities/tea-commerce"> here </ a>.
<h3> 3. Add the language id to a global JavaScript parameter </h3>
In your master template, we now have to add a global JavaScript parameter with the language id. We need it to send to the above mentioned methods.
<h4> In your header you already have something similar </h4>
<pre class="brush: html">
<script type="text/javascript">
    //Used by invokeXSLT to know which page we are currently on
    var _nodeId = <umbraco:Item field="pageID" runat="server"></umbraco:Item>;
  </script>
</pre>
<h4>Now add an extra line with the variable _languageId</h4>
<pre class="brush: html">
<script type="text/javascript">
    //Used by invokeXSLT to know which page we are currently on
    var _nodeId = <umbraco:Item field="pageID" runat="server"></umbraco:Item>;
    var _languageId = <umbraco:Item field="pageID" runat="server" xslt="teacommerce:GetUmbracoLanguageIdByNodeId({0})"></umbraco:Item>;
  </script>
</pre>
The method &#8220;teacommerce.GetUmbracoLanguageIdByNodeId&#8221; is an xslt extension in Tea Commerce, which can pick up a language id from any node in Umbraco if only step 1 of this tutorial have been completet successfully.
<h3> 4. Edit your JavaScripts </h3>
Now we need to use the _languageId variable from step 3 in your JavaScripts. We need your calls to TeaCommerce to comply with the method signatures as they are listed above. In its simplicity this means that you must send _languageId to the necessary methods. <br />
The example below, is based on the Tea Commerce Starter Kit teaCommerce_Advanced.js. Notice the line with &#8220;invokeXSLT&#8221;, as this is the only line that will be changed. <br /> <br />
<strong> NOTE: </strong> Remember to remove the nodeId from the two affected methods! <br />
<strong> NOTE: </strong> If you want to add an order line property not belonging to a particular language simply send 0 (zero) instead of _languageId.
<h4> Excerpts from The Tea Commerce Starter Kit teaCommerce_Advanced.js </h4>
<pre class="brush: javascript">
/*
When the currency is changed we need to update product prices
all over the page.
To do this, we need to know what xslt's to run to get the desired html.
We have written the name of the xslt's in each xslt, and can fetch it from the html.
*/
function updatePageUI() {
  /*
  All xslt's that can be invoked in this way have information in a div
  with the class "invokeXSLT". For every one of them we update the UI.
  */
  jQuery('div.invokeXSLT').each(function () {
    var invokeXSLT = jQuery(this),
        parent = invokeXSLT.parent(),
        htmlFromServer = TeaCommerce.invokeXSLT(invokeXSLT.text(), _nodeId, false);
    parent.before(htmlFromServer).remove();
  });
}
</pre>
<h4>The same code after it has been corrected</h4>
<pre class="brush: javascript">
/*
When the currency is changed we need to update product prices
all over the page.
To do this, we need to know what xslt's to run to get the desired html.
We have written the name of the xslt's in each xslt, and can fetch it from the html.
*/
function updatePageUI() {
  /*
  All xslt's that can be invoked in this way have information in a div
  with the class "invokeXSLT". For every one of them we update the UI.
  */
  jQuery('div.invokeXSLT').each(function () {
    var invokeXSLT = jQuery(this),
        parent = invokeXSLT.parent(),
        htmlFromServer = TeaCommerce.invokeXSLT(invokeXSLT.text(), _nodeId, _languageId, false);
    parent.before(htmlFromServer).remove();
  });
}
</pre>
<h2> Nice to know </h2>
<h3> What is umbracoLanguageId used for?</h3>
It is used to store the order line&#8217;s properties in all possible languages​​. If you make a shop with more languages the properties ​​will be saved in all languages.
<h3> Why not order properties? </h3>
The observant reader may have noticed that the language ID is only being sent with the order line properties and not the order properties. Order properties are considered general and not presumed to belong to a particular language. <br /> <br />
<strong> TIP: </strong> If you still need to have a order property in several languages​​, you can choose to name your property with the language id. Eg &#8220;name1&#8243; &#8220;name2&#8243; and &#8220;name3 &#8216;, where the figure is the language id. In the rare event that you need it, this solution will do the job.
<h3>How do I access properties in the different languages ?​</h3>
The values ​​you get with your order, be it in JavaScript or XML&#8217;en is only in one language. The language is the order language, which you can access directly on the order with the value umbracoLanguageId in the XML and UmbracoLanguageId in the JavaScript. <br /> <br />
You can change the order language with the new JavaScript method TeaCommerce.setOrderUmbracoLanguage(umbracoLanguageId, async, successfn, errorfn). As soon as you call it, all the property values are ​​changed to the new language.
<h3> Can I have a language-independent order line property </h3>
Yes, the properties automatically added by Tea Commerce are not necessarily tied to a language. In this case, their value is always available, regardless of order languages​​. <br />
If you want to add an order line property not belonging to a particular language simply send 0 (zero) as language ID
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/06/10/upgrading-to-tea-commerce-1-3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Tea Commerce Umbraco Razor</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/05/24/tea-commerce-umbraco-razor/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/05/24/tea-commerce-umbraco-razor/#comments</comments>
		<pubDate>Tue, 24 May 2011 06:50:19 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[ecommerce]]></category>
		<category><![CDATA[razor]]></category>
		<category><![CDATA[umbraco]]></category>
		<category><![CDATA[webshop]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=400</guid>
		<description><![CDATA[Tea Commerce provides an API for your Razor scripts. The methods basically gives you the same functionality available in the XSLT extension API. This blog post gives you a list of methods and their signatures.]]></description>
			<content:encoded><![CDATA[Tea Commerce provides an API for your Razor scripts. The methods basically gives you the same functionality available in the XSLT extension API. This blog post gives you a list of methods and their signatures.
<br /> <br />
As a general rule, all methods returns a Tea Commerce object with all the possibilities of such content. The Methods, properties and their classes are all well commented, so check them out in Visual Studio.
<h2> How to use the Tea Commerce Razor API </h2>
I&#8217;ve written a small example of how to use the API. In the example I write the node name of all order lines in the <br />cart. Note that I have a using on both the Tea Commerce razor and the Tea Commerce Data namespaces. With those two I have access to all the classes I need.<br />
Also note that I use UmbracoLanguageId which is first available in the Multi-Language Version of Tea Commerce v1.3.0.0. Are you running a lower version of Tea Commerce you can safely delete this part of the script.
<pre class="brush: csharp">
@using TeaCommerce.Razor
@using TeaCommerce.Data

Order lines in the cart:
@{
  Order order = TeaCommerce.GetOrder();
  if (order.OrderLines.Count() > 0) {
  <ul>
    @foreach (OrderLine orderline in TeaCommerce.GetOrder().OrderLines) {
      <li>
        @orderline.Properties.Single(p => p.Alias.Equals("nodeName") &#038;&#038; p.UmbracoLanguageId == order.UmbracoLanguageId).Value
      </li>
    }
  </ul>
  }
}
</pre>
<h2>Tea Commerce Razor API</h2>
<pre class="brush: csharp">
namespace TeaCommerce.Razor {
  public class TeaCommerce {

    /// &lt;summary&gt;
    /// Indication if current customer has an order
    /// &lt;/summary&gt;
    public static bool HasOrder()

    /// &lt;summary&gt;
    /// Generates a Json string representing the current order
    /// &lt;/summary&gt;
    public static Order GetOrder()

    /// &lt;summary&gt;
    /// Indication if current customer has an finalized order
    /// &lt;/summary&gt;
    public static bool HasFinalizedOrder()

    /// &lt;summary&gt;
    /// Get the users current finalized order
    /// &lt;/summary&gt;
    public static Order GetFinalizedOrder()

    /// &lt;summary&gt;
    /// Get the users current order
    /// &lt;/summary&gt;
    public static Order GetOrder( long orderId )

    /// &lt;summary&gt;
    /// Gets all available shipping methods filtered by the current country
    /// &lt;/summary&gt;
    public static IEnumerable&lt;ShippingMethod&gt; GetShippingMethods()

    /// &lt;summary&gt;
    /// Gets all available payment methods filtered by the current country
    /// &lt;/summary&gt;
    public static IEnumerable&lt;PaymentMethod&gt; GetPaymentMethods()

    /// &lt;summary&gt;
    /// Gets all available countries
    /// &lt;/summary&gt;
    public static IEnumerable&lt;Country&gt; GetCountries()

    /// &lt;summary&gt;
    /// Gets the current country
    /// &lt;/summary&gt;
    public static Country GetCurrentCountry()

    /// &lt;summary&gt;
    /// Gets all available currencies
    /// &lt;/summary&gt;
    public static IEnumerable&lt;Currency&gt; GetCurrencies()

    /// &lt;summary&gt;
    /// Gets the current currency
    /// &lt;/summary&gt;
    public static Currency GetCurrentCurrency()

    /// &lt;summary&gt;
    /// Formats a price with the current currency's culturename
    /// &lt;/summary&gt;
    /// &lt;param name="price"&gt;The price as a decimal&lt;/param&gt;
    /// &lt;returns&gt;The formatted price as string&lt;/returns&gt;
    public static string FormatPrice( decimal price ) 

    /// &lt;summary&gt;
    /// Formats a price with the chosen culturename
    /// &lt;/summary&gt;
    /// &lt;param name="price"&gt;The price as a decimal&lt;/param&gt;
    /// &lt;param name="cultureName"&gt;A culture name&lt;/param&gt;
    /// &lt;returns&gt;The formatted price as string&lt;/returns&gt;
    public static string FormatPriceWithSpecificCulture( decimal price, string cultureName )

    /// &lt;summary&gt;
    /// Formats a price with the current currency's culturename
    /// No currency symbol will be added
    /// &lt;/summary&gt;
    /// &lt;param name="price"&gt;The price as a decimal&lt;/param&gt;
    /// &lt;returns&gt;The formatted price as string&lt;/returns&gt;
    public static string FormatPriceNoSymbol( decimal price )

    /// &lt;summary&gt;
    /// Formats a price with the chosen culturename
    /// No currency symbol will be added
    /// &lt;/summary&gt;
    /// &lt;param name="price"&gt;The price as a decimal&lt;/param&gt;
    /// &lt;param name="cultureName"&gt;A culture name&lt;/param&gt;
    /// &lt;returns&gt;The formatted price as string&lt;/returns&gt;
    public static string FormatPriceNoSymbolWithSpecificCulture( decimal price, string cultureName )

    /// &lt;summary&gt;
    /// Gets the stock of a specific product
    /// &lt;/summary&gt;
    /// &lt;param name="nodeId"&gt;Node id of the product&lt;/param&gt;
    /// &lt;returns&gt;Will return null if the product does not use stock&lt;/returns&gt;
    public static decimal? GetStock( int nodeId )
  }
}
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/05/24/tea-commerce-umbraco-razor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to make a License webshop</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/04/20/how-to-make-a-license-webshop/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/04/20/how-to-make-a-license-webshop/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 11:38:04 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[license]]></category>
		<category><![CDATA[license webshop]]></category>
		<category><![CDATA[selling your license]]></category>
		<category><![CDATA[umbraco]]></category>
		<category><![CDATA[webshop]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=364</guid>
		<description><![CDATA[Many small or medium-sized developers have created software products they want to sell. Maybe they sell them already, but everything is done manually and they may lose some customers who thought it too difficult to buy or who is not familiar with the product. The solution is often to sell the products through a webshop. The problem is that webshops are often too costly, too cumbersome or simply do not meet the requirements. <br /> <br /> 
In collaboration with <a href="http://anders.burla.dk/">Anders Burla Johansen</a> I have developed an extension to <a href="http://www.teacommerce.dk">Tea Commerce</a>, which makes it easier than easy to get your own license webshop up and running. On this page you can find everything you need to do to make your own license webshop with Tea Commerce and Umbraco. ]]></description>
			<content:encoded><![CDATA[Many small or medium-sized developers have created software products they want to sell. Maybe they sell them already, but everything is done manually and they may lose some customers who think its too difficult to buy or who is not familiar with the product. The solution is often to sell the products through a webshop. The problem is that webshops are often too costly, too cumbersome or simply do not meet the requirements.

In collaboration with <a href="http://anders.burla.dk/">Anders Burla Johansen</a> I have developed an extension to <a href="http://www.teacommerce.dk">Tea Commerce</a>, which makes it easier than easy to get your own license webshop up and running. On this page you can find everything you need to do to make your own license webshop with Tea Commerce and <a href="http://umbraco.com">Umbraco</a>.
<h2>The Goal</h2>
I want to find a simple but effective way to license a piece of software. I will focus on being able to sell licenses for web software, which must be limited to a top level domain. It should be possible with a few adjustments to make licenses that are limited in other ways or that works for e.g. desktop applications. It will be up to the individual developer to customize this blog posts examples for the specific task he / she faces.

I will also create a License Kit package for Umbraco which should provide a simple and good foundation for a license webshop. The License Kit package will act the same way as <a href="http://our.umbraco.org/projects/website-utilities/tea-commerce-starter-kit"> the Tea Commerce Starter Kit</a>. You should be able to install the JavaScript, xslt&#8217;s, document types, etc. that will be needed in the final license webshop.

Once you have gone through this guide you will be left with a shop that can sell yours or others&#8217; licenses. <a href="#tutorialStart"> Go directly to the tutorial </a>
<h2>Assumptions</h2>
Before you get started you must first have a clean Umbraco solution with an <a href="http://www.teacommerce.dk"> installation of Tea Commerce</a>. This tutorial support Umbraco 4.5+ and Tea Commerce 1.2.1.1+.
<h2>The solution</h2>
The solution consists of 4 different products, each of which solves a small part of the problem. You can choose to use all four of them, modify them according to your needs and then you&#8217;ll have a setup that can sell your licenses. One of the products is a package for Umbraco and <a href="http://www.teacommerce.dk/blogmedia/Tea_Commerce_License_Kit_1.1.1.0 .NET 4.0.zip">can be downloaded here</a>. The last three products are assembled in <a href="http://www.teacommerce.dk/blogmedia/TeaCommerce.LicenseKit.Developer.zip"> this Visual Studio Solution </a>. In the following I will briefly review the four products.
<h4>The four products for this tutorial</h4>
<ol>
	<li> <a href="#product1"> License Kit package for Umbraco </a></li>
	<li> <a href="#product2"> Asymmetric-key generator </a></li>
	<li> <a href="#product3"> License generation for Tea Commerce </a></li>
	<li> <a href="#product4"> License check for the product </a></li>
</ol>
<h3 id="product1">License Kit package for Umbraco</h3>
For a quick start, I made <a href="http://www.teacommerce.dk/blogmedia/Tea_Commerce_License_Kit_1.1.1.0 .NET 4.0.zip">the License Kit Package for Tea Commerce and Umbraco </a>. It installs a starter kit on your Umbraco solution and makes sure to do the most basic configuration changes in the Tea Commerce settings.
<h4>With the license kit you get</h4>
<ol>
	<li> Changes to Tea Commerce&#8217;s basic configurations</li>
	<li> Document Types</li>
	<li> Templates</li>
	<li> CSS</li>
	<li> JavaScript</li>
	<li> XSLT&#8217;s and macros</li>
	<li> Pages and product in the content section</li>
</ol>
All targeted a licensed shop and with all the best practices we have found in <a href="http://www.teasolutions.dk">Tea Solutions</a>.

<img class="alignnone size-full wp-image-812" title="Content - Umbraco CMS - licensekit.teacommerce.dk_1302675511201" src="http://rune.gronkjaer.dk/blog/wp-content/uploads/2011/04/Content-Umbraco-CMS-licensekit.teacommerce.dk_1302675511201.png" alt="License Kit Content Tree" width="442" height="354" />

<small>The content tree after installation </small>
<h3 id="product2">Asymmetric-key generator</h3>
Project: <strong> TeaCommerce.LicenseKit.AsymmetricKeyGeneration </strong>

This small project is extremely simple and can be found in the Visual Studio. NET solutions. If you build and run it, it generates two XML files that is saved to the root of your C drive. One file holds the secret private key, the second one holds the not so secret public key. Where and how to use them I will come back to later.
<h3 id="product3">License generation for Tea Commerce</h3>
Project: <strong> TeaCommerce.LicenseKit.Webshop </strong>

This class library is an extension to Tea Commerce, which allows the webshop to generate the licenses. It simply hooks into the event AfterOrderFinalized, which is fired once the order has been paid for and is finalized. In my setup it generates a license file and attaching it to an e-mail which is then send to the customer.

A small LicenseHelper class, that generates the license key, is also to be found in this project. This is where you can change the licensing method.
<h3 id="product4">License check for the product</h3>
Project: <strong> TeaCommerce.LicenseKit.Product </strong>

This project acts as your product. Or it holds the code you will be integrating into your product. In my example the product is a usercontrol that outputs if it is licensed or not. The project includes a LicenseHelper class, which in this case checks for valid licenses. With a single method call, you can check if the product is licensed. This functionality can be added in any .NET product.
<h1 id="tutorialStart" class="entry-title">License webshop Tutorial &#8211; This is it</h1>
Follow these tutorial steps to set up your own shop.
<h3 id="tutorial1">1. Download the stuff to use in this tutorial</h3>
As mentioned above, I have created a License Kit and Anders Burla Johansen have made three. NET projects that can help you get started. You need to download.

<ol>
	<li> <a href="http://www.teacommerce.dk/blogmedia/Tea_Commerce_License_Kit_1.1.1.0 .NET 4.0.zip"> Tea Commerce License Kit package for Umbraco </a></li>
	<li> <a href="http://www.teacommerce.dk/blogmedia/TeaCommerce.LicenseKit.Developer.zip"> LicenseKit projects (. NET VisualStudio solution) </a></li>
</ol>
<h3 id="tutorial2">2. Install License Kit Packages</h3>
You install the License Kit as you do any other Umbraco package. Remember that you must install this package on a clean <a href="http://umbraco.com">Umbraco</a> installation where you have already installed <a href="http://our.umbraco.org/projects/website-utilities/tea-commerce">Tea Commerce v1.2.1.1+</a>.

After installation, you can check if it works by adding a license to the cart and complete the order. At present, it will NOT generate any license files. You will be able to see that the order goes through as it should, and we now just need to generate the license files.
<h3 id="tutorial3">3. Generate a private/public key pair</h3>
Now we need to generate a private/public key pair. To do this, start the solution that you just downloaded, in Visual Studio 2010. The project TeaCommerce.LicenseKit.AsymmetricKeyGeneration have the functionality you need. Running the project will save two xml files to your C drive.

One file is your private key, the second is your public key. The private key file must be copied into your web shops App_Data folder. Then type the name of the file on the product&#8217;s &#8220;License Key Private Key File&#8221; property in the Umbraco content. I&#8217;ve already written the default name, so unless you change the name of the file, you need not do more.

We do not need the public-key file yet. It will be <a href="#tutorial5"> copied into your product later</a>.

<strong>NOTE:</strong> For each of your products you will need to generate a unique key pair, as mentioned above. That way, you can not reuse a license between two different products.
<h4>The theory behind</h4>
To protect your product copyrights we are creating a product license, which the product will be able to recognize. By signing the license with our private key we can verify it with our public key. That way we can read the contents of the license in our product and make sure that the product is licensed. The method is relatively safe since it will be difficult to break the encryption without the private key. It is simple because the product does not need to check against a web service to be authenticated.
<h4>Settings you can change</h4>
You can choose to change a few things in this project. The most important thing is that you get the two generated keys. What you call the files or where and how to store them is subordinate.

<strong> NOTE: </strong> Please note that if you change the private key file name or location on your webserver, you will also need to change it in the <a href="#tutorial4"> TeaCommerce.LicenseKit.Webshop project </a> where it reads the file.

<strong> NOTE: </strong> your private key MUST be secure. It must, therefore, under no circumstances be downloadable from the web shop. Therefore we have chosen to store it in the App_Data directory, which is secured by the IIS.
<h3 id="tutorial4">4. Extending the webshop</h3>
Now we need to make our webshop generate licenses. To do this, we have built the TeaCommerce.LicenseKit.Webshop project. The DLL you get by building the project should be uploaded to the webshop&#8217;s bin folder. Basically, this is enough. Now your webshop can generate licenses.

The small extension will also generate an email in which the license keys are attached. The email body will be generated with Tea Commerce&#8217;s own InvokeXSLT which is used to retrieve the contents of a specific xslt file. You can edit the xslt file and write a decent text or whatever you want.

You can now test if it works by running another order through. As long as the website has access to an SMTP server, it will now send an email with the license keys.
<strong> NOTE: </strong> Remember that there is a reference to the Tea Commerce DLL TeaCommerce.Data in this project. It must be the same version as the one you have on the web shop.
<h4>The Theory behind</h4>
The project has a LicenseHelper class. This is the one that generates the license keys with your private key, which it obviously needs to have access to.

A text that can be pulled out and used to verify the license, will be saved in the license. In this text I have pasted the domain that the user enters when he adds the license to the cart. In front of the domain is prefixed &#8220;0001&#8243;. This is a device designed to ensure that we can generate other types of licenses in the future. This could e.g. be a server license with the prefix &#8220;0002&#8243;. The idea is that the product must check this four-digit number and then know which method it must <a href="#tutorial5"> use to check the license </a>.
<h4>Settings you can change</h4>
You can change several parameters in this project.
<ul>
	<li> E-mail &#8211; You can change as much as you want on the email being sent. In the example we have hardcoded the subject, send, etc., but you can retrieve this information from other sources if you like.</li>
	<li> E-mail body &#8211; The name of the xslt file is hardcoded. You can change this or find another way to generate the e-mail body.</li>
	<li> Private key file name &#8211; In this example the name of this file comes from the product node where it has been entered. You could also hard code the location or find another way to link a product along with its private key. The important thing is to keep the private key secure. The way I&#8217;ve done it is safe, but also flexible, as you could easily create new licensed products.</li>
	<li> The name of the license file &#8211; Right now I call the license file for &#8220;[productName]-[domain].lic&#8221;. You can call it anything, as we check all *.lic files to find a proper license, in the product project.</li>
	<li> Private key &#8211; You can choose to move or rename your private key file.</li>
	<li> productSaltLength &#8211; Must just fit with the salt that is used to decrypt the license.</li>
</ul>
<h3 id="tutorial5">5. Check the license in your product</h3>
Now we have a license key to be tested. For convenience, you can choose to test it directly on the webshop site. In the .NET solution there is a TeaCommerce.LicenseKit.Product project, which will make it up for your product.

The first thing you do is copy the contents of your public key xml file, located in <a href="#tutorial3">the root of your C drive</a>.

In the LicenseHelper class the public key content must be deployed in the constant &#8220;publicLicenseKey&#8221;.

Once you&#8217;ve done this, rebuild your project and copy the DLL into the bin folder and LicenseCheckTest.ascx into the usercontrols folder. The LicenseCheckTest.ascx is &#8220;your product&#8221; that we will now use on the site. You do this by creating a new macro and choose LicenseCheckTest.ascx in the usercontrol dropdown. Click &#8220;Use in editor&#8221; to be able to insert the macro in the content of one of your pages.

Now open the page you just put the new macro on. If it says &#8220;Domain is licensed&#8221; you have done everything correctly. If not, just check the previous steps in this tutorial again. You probably did something wrong <img src='http://rune.gronkjaer.dk/en-US/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> 
<h4>The theory behind</h4>
In LicenseCheckTest.ascx.cs you can see how easy the license check is done in the product itself. LicenseHelper.HasLicense() returns true if there exists a valid license. Where and how you use this method in your product is entirely up to you.

In the LicenseHelper class you can see how the check will be made. Once the class is initialized the licenses are saved in a static variable, from which they can be retrieved later.

The HasLicense method is checking the stored licenses against the domain of the site and returns true as soon as a match is found.

Note that there is a switch/case in which we investigate what type of license we are checking. In this the license is handled according to it&#8217;s prefix number.
<h4>Settings you can change</h4>
<ul>
	<li> publicLicenseKey &#8211; The public key is hardcoded into the project, but you could store it on the server as a file. Depending on the situation it is convenient to keep it in the code though, as everything will be in one place.</li>
	<li> productSaltLength &#8211; Must fit with the length of the salt that is used to encrypt the license.</li>
	<li> Location of the license file &#8211; In this example we place it in the bin folder. It may be placed wherever you like as long LicenseHelper can get to its contents.</li>
</ul>
<h2>Many thanks to</h2>
My colleagues <a href="http://anders.burla.dk/"> Anders Burla Johansen </a> and Morten Vejhe. Anders for his huge work with the license helpers and Morten for his knowledge about all the weird stuff. Thanks to <a href="http://blog.mattbrailsford.com/">Matt Brailsford</a> as well for testing this tutorial.
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/04/20/how-to-make-a-license-webshop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New website for Jensen&#8217;s Foods</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/04/16/new-website-for-jensens-foods/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/04/16/new-website-for-jensens-foods/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 13:33:50 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[Image Viewer]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[umbraco]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=371</guid>
		<description><![CDATA[Just recently <a href="http://jensensfoods.dk/"> Jensen's Foods new website</a> went online. The company based in Struer, Denmark have had large ambitions for the new website and has also had the will to put resources into it. It has therefore been a very exciting site to set up. Besides a good cooperation with <a href="http://jensensfoods.dk/"> Jensen's Foods</a>, it's been a pleasure to work with <a href="http://happyadvertising.dk/"> Happy Advertising </a>, who has been responsible for the design of the site.]]></description>
			<content:encoded><![CDATA[Just recently <a href="http://jensensfoods.dk/"> Jensen&#8217;s Foods new website</a> went online. The company based in Struer, Denmark have had large ambitions for the new website and has also had the will to put resources into it. It has therefore been a very exciting site to set up. Besides a good cooperation with <a href="http://jensensfoods.dk/"> Jensen&#8217;s Foods</a>, it&#8217;s been a pleasure to work with <a href="http://happyadvertising.dk/"> Happy Advertising </a>, who has been responsible for the design of the site.
<h2> Large ambitions </h2>
Jensen&#8217;s Foods wanted a site without blind alleys. They wanted the user to always have the opportunity to move forward to new and interresting content wherever on the site he / she may be. They also wanted to allow users to share the site&#8217;s content with their friends and colleagues via social media. <br /> <br />
That kind of linking content requires much of both the system, as well as individuals who must maintain it. It takes time to merge the site along the length and breadth and the system should preferably make the job easy.
<h2> The solution </h2>
The new website should of course be created in <a href="http://umbraco.com/"> Umbraco CMS</a>. Both because it is a great CMS for a developer, but also because it would allow to make the linking of the contents. Additionally you can get a long string of extension packages for Umbraco. Some free and a few that cost money. <br /> <br />
In our analysis for Jensen&#8217;s Foods, we proposed to create a series of boxes in the right column of the website. It would be those boxes which had to tie the site together by linking to content related to the page you&#8217;re standing on. The boxes would be used on the frontpage as well, where they link to the most popular or relevant content. <br /> <br />
With help from Umbraco CMS, I could make it easy to add and remove boxes on the pages as well as on the front. I decided that all pages could &#8220;be&#8221; a box. All pages would be able to have a title, a picture and a small text to be used in the box. In the right column you choose  some pages, so as to appear as boxes. When you click on the box it links to that page. All pages can then be a box, and all pages can be linked to a number of boxes that is displayed in right column. <br /> <br />
The system is the same for ordinary pages, recipes, as well as products. With a few clicks, Jensen&#8217;s Foods can now put a recipe on the frontpage, on a product page and in a plain text page and from there the sites users can now find the recipe. The boxes have been introduced over the entire site and will hopefully encourage users to spend even more time on the site.
<h2> Products and Recipes </h2>
Products and recipes are a big part of Jensen&#8217;s Foods content on the website. For both types of content they&#8217;ve had a super imagery that has been important to show to the user. I have used my <a href="http://rune.gronkjaer.dk/en-US/image-viewer/"> jQuery Image Viewer Plugin </a>, to display images in large formats. The advantage of jQuery Image Viewer is that it can display the image in as large a format the users screen permits. So everyone will have an optimal experience.
<h3> ImageGen</h3>
It has been important for me to turn it into a manageable task to maintain the website. Therefore, we ensured that all graphics related to products and recipes would be in the same proportions. That way I could let them upload a single image and then reuse the image anywhere else on the site. To make the different sizes of the images I have used the super <a href="http://our.umbraco.org/projects/website-utilities/imagegen"> ImageGen</a> package for Umbraco. ImageGen resizes the images and caches them for next time. It is a great tool, and for a small fee you get an extended license that opens up even more possibilities.
<h3> Social Media </h3>
Recipes and Products can be shared in all the usual social media. This is done using the now very recognizable <a href="http://www.addthis.com/"> AddThis </a> bookmarking service. It allows you to focus on some social media, but also gives the user the option to choose from a wide range of other social media. I use it because it&#8217;s easy, well made and free.
<h2> Image Bank </h2>
We have set up an image bank to publish Jensen&#8217;s Foods press photos. Actually a quite ordinary task but Umbraco has again been able to do maintenance easy and convenient. The Image Bank is made so Jensen&#8217;s Foods only need to put the images into Umbraco&#8217;s media archive. Then I fetches them automatically with xslt and lists them on the page. With the ability to add extra data to the images in the media archive Jensen&#8217;s Foods can add a link and a text to all images. Once again this chains content together across the normal boundaries. I have used ImaeGen in the image bank to generate a smaller version of all images.
<h2> Contour </h2>
Jensen&#8217;s Foods has so far two forms on the website. Both are made with <a href="http://umbraco.com/products/more-add-ons/contour"> Umbraco&#8217;s own product &#8211; Contour</a>. Countour is a large and flexible system to generate forms. The possibilities are good for styling the forms as needed. It is also easy to use, so Jensen&#8217;s Foods will have the opportunity to maintain or create new forms.
<h2> Google SiteSearch </h2>
The search functionality on Jensen&#8217;s Foods is implemented with Google SiteSearch. I have put together a small JavaScript to support Google SiteSearch. This made it possible to send keywords in the querystring and still view a search result page. This was needed as Jensen&#8217;s Foods wanted a search box at the top of the design on all pages. Use the search input the javascript automatically sends the user to the search page and initialize the search. Google Site Search is a powerful tool that makes Google&#8217;s search algorithms available directly on the website. Users will easily be able to find all content on the site.]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/04/16/new-website-for-jensens-foods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tea Commerce dynamic VAT</title>
		<link>http://rune.gronkjaer.dk/en-US/2011/04/12/tea-commerce-dynamic-vat/</link>
		<comments>http://rune.gronkjaer.dk/en-US/2011/04/12/tea-commerce-dynamic-vat/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 11:06:27 +0000</pubDate>
		<dc:creator>Rune Gronkjaer</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[Tea Commerce]]></category>
		<category><![CDATA[Umbraco]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[e-handel]]></category>
		<category><![CDATA[event model]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[manipulation]]></category>
		<category><![CDATA[moms]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[umbraco]]></category>
		<category><![CDATA[VAT]]></category>

		<guid isPermaLink="false">http://rune.gronkjaer.dk/en-US/?p=312</guid>
		<description><![CDATA[If you want to sell good or services in several countries you might need to have a flexible VAT setup. During implementation of our own Tea Commerce webshop, where we will sell our Tea Commerce Licenses, I have developed a piece of code that changes the VAT depending on certain criteria. The criterias in this case is base on the danish laws and regulations.]]></description>
			<content:encoded><![CDATA[If you want to sell good or services in several countries you might need to have a flexible VAT setup. During implementation of our own Tea Commerce webshop, where we will sell our Tea Commerce Licenses, I have developed a piece of code that changes the VAT depending on certain criteria. The criterias in this case is base on the danish laws and regulations.<br /> 
<h2>VAT scenarios</h2> 
In our scenario the webshop is registered in Denmark and we have the following options, based on knowledge of the customer&#8217;s country, and VAT number. 
<ol> 
<li> 
The customer is from Denmark and must therefore pay the Danish VAT in any case.
</li> 
<li> 
The customer is from an EU country and does not have a valid VAT number. The customer will have to pay Danish VAT.
</li> 
<li> 
The customer is from an EU country and have a valid VAT number. The customer will not pay VAT.
</li> 
<li> 
The customer is from a country outside the EU and therefore need not pay VAT.
</li> 
</ol> 
<h2>Note the following</h2> 
In my solution I use an official web service from the European Parliament to check the tax numbers, which customers enter. For anyone interested in using the web service, here&#8217;s the address: http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl. 
<br /> <br /> 
I choose to sign up for two <a href="http://rune.gronkjaer.dk/en-US/2010/11/26/how-to-use-the-tea-commerce-events/">Tea Commerce events</a> where I have the ability to manipulate the order. One is &#8220;CountryChanged&#8221; which of course must be used each time choosing a new country. Each change of land should I make validation since you have to match it up with the entered VAT number. <br /> <br /> 
The second is &#8220;OrderPropertiesUpdated&#8221;. Here do I only make the validation whenever there are changes to the Properties &#8220;companyVATNo&#8221;. This checking is important for performance when called to the web service could be very expensive and could make the experience of the site worse.
<br /><br />
I found a list of most countries of the world and imported them into Tea Commerce. <a href="http://www.teacommerce.dk/media/4818/allthemcountries.csv">Here&#8217;s a csv with the countries.</a> I marked the official European Union countries, which I used to create an auxillary table with all the European Union country ID&#8217;s. This way I can make a simple lookup when checking the countries.
<h4>The full example</h4>
<pre class="brush: csharp">
using System.Collections.Generic;
using System.Linq;
using TeaCommerce.Data;
using TeaCommerce.Data.Extensibility;
using TeaCommerce.WebShop.Integration.DB;
using umbraco;

namespace TeaCommerce.WebShop.Integration {
  public class LicenseExtension : ITeaCommerceExtension {

    const long danishVATGroupId = 1;
    const long noVATGroupId = 2;

    /// <summary>
    /// Initialize wil automatically be run by Tea Commerce on apllication load.
    /// Any events you want to hook into is done here.
    /// </summary>
    public void Initialize() {
      //The only custom thing we want to do happens after the order has been finalized
      WebshopEvents.OrderPropertiesUpdated += WebshopEvents_OrderPropertiesUpdated;
      WebshopEvents.CountryChanged += WebshopEvents_CountryChanged;
    }

    void WebshopEvents_CountryChanged( Order order, Country country ) {
      ValidateAndSetVat( order );
    }

    void WebshopEvents_OrderPropertiesUpdated( Order order, IEnumerable&lt;OrderProperty&gt; properties ) {
      OrderProperty vatProperty = properties.SingleOrDefault( p => p.Alias.Equals( "companyVATNo" ) );
      if ( vatProperty != null )
        ValidateAndSetVat( order );
    }

    #region Private methods

    /// <summary>
    /// Checks the VAT number in the european unions own database
    /// </summary>
    /// <param name="vatNumber">The customer VAT number</param>
    /// <param name="countryCode">The customers country code</param>
    /// <returns>true if the VAT number is a valid (EUROPEAN only)</returns>
    private bool CheckVatNumber( string vatNumber, string countryCode ) {
      bool isValid = false;
      string name = string.Empty, address = string.Empty;
      if ( !vatNumber.Equals( string.Empty ) &#038;&#038; !countryCode.Equals( string.Empty ) ) {
        CheckVatService.checkVatRequest cvr = new CheckVatService.checkVatRequest( countryCode, vatNumber );
        CheckVatService.checkVatPortTypeClient cvptc = new CheckVatService.checkVatPortTypeClient();
        cvptc.checkVat( ref countryCode, ref vatNumber, out isValid, out name, out address );
      }
      return isValid;
    }

    /// <summary>
    /// Validates the order country and VAT number and sets the VAT group accordingly
    /// </summary>
    private void ValidateAndSetVat( Order order ) {
      if ( order.Country.CountryCode.ToLower().Equals( "dk" ) ) {
        //We are in Denmark and 25% VAT is applicable
        order.VATGroupId = danishVATGroupId;
      } else {
        //The country is not Denmark. Where is it?
        using ( TeaCustomDataContext dc = new TeaCustomDataContext( GlobalSettings.DbDSN ) ) {
          if ( dc.Tea_EuropeanCountries.Any( ec => ec.CountryId == order.CountryId ) ) {
            //The country is a member of the European Union and we need to check the VAT number
            OrderProperty vatProperty = order.Properties.SingleOrDefault( p => p.Alias.Equals( "companyVATNo" ) );

            if ( vatProperty != null &#038;&#038; CheckVatNumber( vatProperty.Value, order.Country.CountryCode ) )
              //We are in Europe and the customer has a valid VAT number - 0% VAT is applicable
              order.VATGroupId = noVATGroupId;
            else
              //We are in Europe and the customer does not have a valid VAT number - 25% VAT is applicable
              order.VATGroupId = danishVATGroupId;

          } else {
            //The country is NOT a member of the European Union - 0% VAT is applicable
            order.VATGroupId = noVATGroupId;
          }
        }

      }
      order.Save();
    }
    #endregion
  }
}
</pre>
<h2>Tea Commerce links</h2>
<ul>
<li><a href="http://www.teacommerce.dk">Official Tea Commerce Website</a></li>
<li><a href="http://www.teacommerce.dk/en/documentation.aspx" alt="List of all Tea Commerce Documentation pages" title="List of all Tea Commerce 
Documentation pages">Tea Commerce Documentation</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-multilanguage-starter-kit.aspx">Tea Commerce Multilanguage Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-starter-kit.aspx">Tea Commerce Starter Kit</a></li>
<li><a href="http://www.teacommerce.dk/en/products/tea-commerce-demo-webshop.aspx">Tea Commerce Demo Webshop</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://rune.gronkjaer.dk/en-US/2011/04/12/tea-commerce-dynamic-vat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

