# Friday, 05 November 2010

When uCommerce was introduced to the world at Codegarden ‘09 one of the things we demoed was how to build simple inventory management using the API and pipelines.

The great thing about pipelines is that they’re very easy to extend so we didn’t think to actually include the inventory tasks; until now that is.

What does it do

The pipeline tasks are pretty simple and do one thing: During checkout one task looks for a field on your product definition called “InventoryOnHand” if found decrements that field with the quantity ordered by the customer. It’s that easy.

Now inventory management wouldn’t be complete if it didn’t support returns as well. So a second task is configured to run as part of the order processing flow in the backend of uCommerce. If an order is moved to a cancelled state the task looks for that same field once more and increments “InventoryOnHand” with the quantities found on each order line.

Setting it up

As mentioned the inventory tasks “DecrementInventoryOnHand” and “IncrementInventoryOnHand” looks for a field called “InventoryOnHand”. So you need to add to your product definitions for inventory management to kick in. You’re free to have the field only on some product and not on others. The tasks will adapt to whatever the case might be.

One thing to note is that if you’re operating with variants you want to add the “InventoryOnHand” field as a variant property otherwise uCommerce won’t pick it up.

If you don’t use variants just leave Variant Property off.

uCommerce-add-inventory-on-hand-field

Managing Inventory Levels

With the new field in place you can now manage inventory levels on products or variants as you would any other product property.

uCommerce-manage-inventory-on-hand-field

Cancelled Orders

The store owner might decide to cancel an order in which case the quantites ordered need to be returned as inventory. IncrementInventoryOnHand handles this for you.

uCommerce-inventory-return-order

Pipelines

Here’s what the pipelines look like in case you were wondering.

Checkout pipeline

uCommerce-inventory-checkout-pipeline

ToCancelled pipeline

uCommerce-inventory-to-cancelled-pipeline

Wrap Up

That’s it. With two pretty simple tasks uCommerce now has simple inventory management built right in.

posted on Friday, 05 November 2010 14:50:41 (Romance Standard Time, UTC+01:00)  #    Comments [0] Trackback
# Monday, 01 November 2010

Any good e-commerce solution lets the store owner stay in contact with customers. One of the most well established ways of doing this is using the tried and true e-mail.

A strength of the integration between uCommerce and Umbraco is that Umbraco is particularly good at building nice looking pages so we thought, “why not use this to build e-mails as well?”, so that’s what we did. The great thing about this approach is that you don’t have to learn some obscure templating language to style your e-mails, you simply build your e-mail content like you would build any other page in your solution using XSLT or .NET user control, whichever suits you the best.

Steps Involved in Sending E-mail

To send e-mail you’ll need to:

  • Add the types of e-mails you’ll be working with in uCommerce
  • Set up a profile for your store to use
  • Configure the actual e-mails and their templates using Umbraco
  • Configure your store to use that profile
  • And finally trigger the e-mail from XSLT, a pipeline, or .NET

Adding a New E-mail Type

uCommerce employs the notion of E-mail Types, which are your basic kinds of e-mails that you’re working with. Out of the box a single type is supplied called “order confirmation”, but you can configure your own types as needed.

Other types might include “Welcome new customer”, “Thank you signing up to the newsletter”, or more business-like type e-mails like “Your items are shipping” or “Invoice”.

uCommerce-email-types

To set up a new e-mail type you need to go to Settings => E-mail => Types, right click Types, and click Create.

uCommerce-create-new-email-type

Add an E-mail Profile

“What’s an E-mail Profile and why do we need one?”, you might ask.

uCommerce supports multiple stores in a single installation and these stores might vary wildly in look and feel so we needed a way to set up multiple instances of the same e-mails on a per store basis to match that same look and feel from store on e-mails across different stores, e.g. an invoice for Store A might have a different look and feel than an invoice for Store B. Thus the notion of an E-mail Profile was introduced to group e-mail instances together for use on individual stores.

As you can see from the screenshot below the profile has an e-mail instance associated per e-mail type created previously. The difference being that for an E-mail Profile we’re dealing with an actual e-mail while an E-mail Type is a placeholder. The system basically ensures that we’re dealing with the same e-mail setup across all stores and makes it easier to deal with in code.

The process of creating a new profile is the same as you just used to create an E-mail Type.

uCommerce-email-profile

Create the E-mail Content in Umbraco

As mentioned previously e-mail is generated using Umbraco using content nodes, templates, macros, and/or user controls. uCommerce comes with a single Umbraco page out of the box: Order Confirmation, but really you can use any content node in Umbraco.

Each e-mail is language enabled so if you need multiple language variations of your e-mail you can set up a content node for each language you wish to support.

uCommerce-email-content-generated-by-umbraco

The template of your content node can be used to load information particular to the e-mail you’re sending by using macros. By use of a little magic uCommerce will provide the content page with a query string parameter named “orderGuid”, which will give you context information to load data.

Lets say that we’re building an order conformation e-mail and assume that we’re receiving the order guid in our query string. The code to load data would look as follows:

<!-- The query string param will always be 'orderGuid', but may contain additional parameters like a customer number or product id -->
<xsl:variable name="orderGuid" select="umbraco.library:RequestQueryString('orderGuid')"/>
<xsl:variable name="cart" select="CommerceLibrary:GetPurchaseOrder($orderGuid)"/>
<!-- code for formatting the contents of the $cart variable -->

Configure Contents of E-mail

Going back to uCommerce you need to specify which content node uCommerce is to use when generating the e-mail.

First you’ll set up the basics of the e-mail such as the name the e-mail is coming from and sender address and optionally whether the e-mail is to CC or BCC’d to anyone, e.g. stores owners like to get an e-mail notification when new orders roll in and this is the perfect use case for CC and BCC.

Sending-email-with-ucommerce-basics

Next up you’ll configure the multilingual pieces of the e-mail like the subject and the contents of the e-mail, which you set up in a earlier step.

Sending-email-with-ucommerce-configure-email-contents

Select the template in Umbraco using the content picker. Please note that this might be any content node in Umbraco; OrderConfirmation is used only as an example.

Sending-email-with-ucommerce-select-template

Configure Your Store to use an E-mail Profile

Once you’re happy with the e-mails in your installation you’re ready to tell your store to use those e-mails. To do so go to Product Catalog => <Your Store> and select your E-mail Profile.

With this step completed uCommerce will know which e-mail and template to select when you ask it to send a particular e-mail type in a given store. More on that in the next step.

uCommerce-configure-store-to-use-email-profile

Send the E-mail

Now you’re ready to tie it all together and send the e-mail to the customer. As with most APIs in uCommerce you can go with either XSLT or .NET when you want to trigger the e-mail. Use whatever makes sense in your particular scenario.

Using XSLT you can use the following to trigger our order confirmation template from before:

<xsl:variable name="orderGuid" select="CommerceLibrary:GetBasket()/purchaseOrder/@orderGuid"/>
<xsl:variable name="result" select="SendEmail('OrderConfirmation', $orderGuid)"/>

The XSLT extension “SendEmail” used above actually uses a class called EmailService to do its thing.

You can leverage this same class in .NET or pipeline yourself with the following code:

// Get the services required for sending e-mails
var emailService = ObjectFactory.Instance.Resolve<IEmailService>();
var localizationContext = ObjectFactory.Instance.Resolve<ILocalizationContext>();
 
// Find the relevant e-mail profile for the current store
var emailProfile = SiteContext.Current.CatalogContext.CurrentCatalogGroup.EmailProfile;
 
// Load information for e-mail personalization
var purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
 
// Set up personalization parameters - params will be passed to
// the configured e-mail template
var queryStringParameters = new Dictionary<string, string>();
queryStringParameters.Add("orderGuid", purchaseOrder.OrderGuid.ToString());
queryStringParameters.Add("customerId", purchaseOrder.Customer.CustomerId.ToString());
 
// Send e-mail
emailService.Send(localizationContext, 
                    emailProfile, 
                    "OrderConfirmation", 
                    new MailAddress(purchaseOrder.BillingAddress.EmailAddress),
                    queryStringParameters);

Please note that both examples assume that you’ve added a billing address to the basket prior to sending e-mail. Keep in mind that uCommerce uses standard .NET SMTP to send the e-mail so you will have to configure the SMTP server you want to use in web.config.

As of uCommerce 1.1.1.0 you can use a standard pipeline task to send e-mails. Simply edit the relevant pipeline configuration and add SendEmailTask to the flow. When uCommerce 1.1.1.0 is installed OrderConfirmation is added as a default. If you need to send other e-mail types you see how to configure them by taking a look at /umbraco/ucommerce/Checkout.config.

You can tell uCommerce to send a different type of e-mail by specifying an e-mail type name as shown in the screenshot below. Just replace “OrderConfirmation” with the name of your e-mail type; this is the name that you used when you created your e-mail types in a prior step.

uCommerce-configure-send-email-pipeline-task

With that you’ve sent your first e-mail with uCommerce.

Wrap Up

The process of sending e-mail with uCommerce does require a couple of steps to get going, however, in return you get the full power of Umbraco as a content management system to fully style your e-mails thus avoiding to have to learn some arcane templating system.

In addition you can even take advantage of some more advanced macros within uCommerce. Think of the value of sending out your order confirmation e-mail, not only with the details of the order, but with added information about related items to each item bought or special offers tailored to the customer.

This is the value of having Umbraco and uCommerce handle your store e-mails.

posted on Monday, 01 November 2010 17:02:38 (Romance Standard Time, UTC+01:00)  #    Comments [0] Trackback
# Monday, 18 October 2010

uCommerce comes with built-in support for PayPal using Website Payments Standard for authorizing new payments and Website Payments Pro for capturing, voiding, and refunding payments in the backend. This guide will walk you through getting uCommerce to work with PayPal for payment processing.

Authorization is available for all plans with PayPal. If you wish to acquire (capture), refund, or cancel payments PayPal requires you to upgrade your account to either Premier or Business.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “Paypal”.

clip_image001[14]

Click the newly created node and selected “PayPal” in the Service drop down list. Fill out the rest of the required information, like where it’s available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image003[14]

That’s everything in the uCommerce interface.

Settings in PayPal Administration Panel

Optional: Encrypted Website Payments

We recommend that “Encrypted Website Payments” is used, so the data sent to PayPal can’t be tampered with. This are some steps involved but again, it’s a security risk not to use this feature.

Getting OpenSSL for windows

OpenSSL is an open source tool for Windows, which is used to generate certificates. You will need to install it to generate the PayPal encryption certificates. Visit http://www.slproweb.com/products/Win32OpenSSL.html and download ”Win32 OpenSSL Light”.

Generating the keys

Open a command prompt and go to the bin directory under the installation directory.

clip_image004[14]

To create the private certificate type: “openssl genrsa –out private-key.pem 1024” and press [Enter].

clip_image005[14]

For the public certificate type: “openssl req –new –key private-key.pem –x509 –days 365 –out public-cert.pem”

Now it will ask you to enter some information, you can just skip them by pressing [Enter].

clip_image006[14]

Now we need to create the p12 file. Type the following in the prompt: “openssl pkcs12 –export –in public-cert.pem –inkey private-key.pem –out my_pkcs12.p12” followed by [Enter].

clip_image007[14]

Uploading the public key to PayPal

Log into PayPal and go to the profile settings.

clip_image009[14]

Click the “Encrypted Payment Settings”.

clip_image011[14]

Start by downloading the “PayPal Public Certificate” by clicking the download button marked with number 1. Next click the “Add” button marked number 2 on the page.

clip_image013[14]

Select the file and click “Add”.

clip_image015[14]

Copying the certificates

In the previously step you create 3 files and downloaded 1:

· paypal_cert_pem.txt – downloaded – PayPal public certificate

· private-key.pem – created – private key

· public-cert.pem – created – public key

· my_pkcs12.p12 – created – p12 exchange key

Copy the files to a directory where your uCommerce installation can get access to them. You will most likely have installed umbraco under: “C:\inetpub\umbraco”. A good place for them would be in the uCommerce configuration directory would be: “C:\inetpub\umbraco\umbraco\UCommerce\Configuration” together with the PayPal.config file.

Rejecting unencrypted messages

Log into the PayPal administration panel and click on “Profile”.

clip_image017[14]

On the profile page click the “Website Payment Preferences”.

clip_image019[14]

Scroll down to “Encrypted Website Payments” and make sure the radio button “Block Non-encrypted” are selected. Scroll down to the button and click “Save”.

clip_image021[14]

Editing the PayPal.config File

Now we need to edit the PayPal.config file.

You will find the PayPal.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\PayPal.config”. Usually “rootdir” is c:\inetpub.

clip_image022[14]

Some of the below information are found in the PayPal administration panel, so start by logging in if you haven’t done so already.

Optional: Finding privateCertificatePath, publicPayPalCertificatePath, privateCertificatePassword and useEncryption

If you earlier in this guide turned “Encrypted Website Payments” on, this step needs to be completed.

privateCertificatePath and publicPayPalCertificatePath

If you used the default names earlier in this guide, path of the two files should work out of the box. If you customized them, reflect the changes here.

privateCertificatePassword

Password entered when you created the p12 file. This can be an empty password, but recommended with a password if you are on a shared host.

useEncryption

Set this to “True” used you are using “Encrypted Website Payments”.

Optional: Finding apiUsername, apiPassword, and apiSignature

apiUsername, apiPassword, and apiSignature are all used to access the PayPal remote API to do Acquire, Refund, and Cancel.

Log into you PayPal account and make sure your account is verified.

clip_image024[14]

Click on “My Account”, then “Profile” and at last “API Access”

clip_image025[14]

On the “API Access” page, Click the “Request API credentials” link.

clip_image027[14]

Make sure “Request API signature” is selected, and then click the “Agree and Submit” button.

clip_image029[14]

Here you will find the “API Username”, “API Password” and “Signature”.

clip_image030[14]

Finding debug

If set to “True”, it will prompt you to click a button before posting the information to “PayPal” otherwise it will do an autosubmit. When running in production, you will have this set to “False”.

Finding sandbox

If testing the ingration with a developer account set this to “True” otherwise “False” at a production site.

Finding returnMethod

Leave it at default.

Finding business

Next we need to find your PayPal ID or an email address associated with your PayPal account. Again, click on “My Account”, then “Profile” and then “Email”.

clip_image031[14]

Here you can see your “Business” account name. Its usually your email address used, when you signed up for the PayPal account. I have only one, but you could have multiple.

clip_image032[14]

Finding notifyUrl

Leave this at “(auto)” if in doubt.

Finding paymentAction

What paymentaction to take.

· Sale - Finale sale, instant capture.

· Authorization - Authorization for a final sale, to be captured later.

· Order - Just place the order, but authorize & capture later. In most cases you you want “Authorization”.

Finding return

Url the user is returned to after successfully authorizing her credit card.

Finding cancelReturn

Url the user is returned to if she cancels a purchase.

Excecuting a pipeline on callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “PayPal” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'PayPal'

or just edit it manually in SQL Server Management Studio.

clip_image033[14]

Now the default piplline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image035[14]

ToCompletedOrder.config

clip_image037[14]

FAQ

· Test mode – Make sure test mode if turned off when going live.

· Environment – Make sure this setting is set to “Live” when in production.

posted on Monday, 18 October 2010 13:04:02 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback

uCommerce comes with built-in support for DIBS payments. This guide will walk you through getting uCommerce to work with DIBS for payment processing.

Authorization is available for all plans with DIBS. If you wish to acquire (capture), refund, or cancel payments DIBS requires you to purchase the “Integration(API)” add-on.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “DIBS”.

clip_image001

Click the newly created node and select “DIBS” in the Service drop down list. Fill out the rest of the required information, like where it’s available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image002

That’s everything in the uCommerce interface.

Settings in DIBS Administration Panel

Changes needed in the DIBS administration panel, so it will work with uCommerce.

Configure MD5 Control Setting

On the Menu on the left side, click “Integration –> MD5 Keys”. Make sure that “Perform MD5 control” is checked. If not, check it and click “Update”.

clip_image004

Configure Return Values

uCommerce performs validation of the payment information when DIBS performs the callback. To verify that the payment wasn’t tampered with you’ll need to configure DIBS to include some additional information as part of the callback.

clip_image001[1]

Editing the DIBS.config File

Now we need to edit the DIBS.config file.

You will find the DIBS.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\DIBS.config”. Usually “rootdir” is c:\inetpub.

clip_image005

Some of the below information are found in the DIBS administration panel, so start by logging in you aren’t already.

Finding testMode

If set to “True”, test mode is enabled and you can that it works. Test credit card information from DIBS can be found here: 5. Your own test.

Finding debug

If set to “True” you will be prompted to click a button before posting the information to “DIBS” otherwise it will do an autosubmit using Javascript. When running in production, you will want this set to “False”.

Finding login

Used if you want to use the remote API to do authorization, capture and cancel. This is the same login used for the DIBS administration panel

Finding password

Only used when doing remote API. This is the password used when logging into the DIBS administration panel

Finding callbackUrl

Leave this at “(auto)” if in doubt.

Finding acceptUrl

Url the user is returned to after successfully authorizing her credit card.

Finding cancelUrl

Url the user is returned to if she cancels a purchase.

Finding merchant

On the Menu on the left, click “Setup –> Edit profile”, here you will find the Merchant ID.

clip_image006

Finding useMd5

True/False indicating weather to use Md5. Its recommended to use Md5 for security reasons.

Finding key1 and key2

The two keys found in the administration panel. On the Menu on the left, click “Integration –> MD5 Keys”, here you will find k1 and k2 which correspond to key1 and key2. Also make sure that “Perform MD5 control” are checked. If not, mark it and click “Update”.

Please note that the configuration files are subject to standard XML limitations. If your MD5 key contains the following characters they must be HTML encoded for .NET to be able to read the value:

For < write &lt;
For & write &amp;
For ' write &#39;
For " write &quot;

Given an MD5 key containing the & symbol you’d replace it to look like this: Before &P]ij|&4jNixCA%zZ è After &amp;P]ij|&4jNixCA%zZ
clip_image007

Excecuting a Pipeline on Callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “DIBS” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'DIBS'

or just edit it manually in SQL Server Management Studio.

clip_image008

Now the default pipeline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image010

ToCompletedOrder.config

clip_image012

FAQ

· Test mode – Make sure test mode if turned off when going live.

posted on Monday, 18 October 2010 12:40:59 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback

uCommerce comes with built-in support for ePay payments. This guide will walk you through getting uCommerce to work with ePay for payment processing.

Authorization is available for all plans with ePay, i.e. Light, Pro, and Business. If you wish to acquire (capture), refund, or cancel payments ePay requires you to buy the Business plan.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “ePay”.

clip_image002

Click the newly created node and select “ePay” in the Service drop down list. Fill out the rest of the required information, like where its available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image003

That’s everything in the uCommerce interface.

Settings in ePay Administration Panel

Changes needed in the ePay administration panel, so it will work with uCommerce.

Unikt orderID, MD5 sikkerhedstjek & callback setting

On the Menu on the left, click “Indstillinger–> Betalingssystemet”, then you should get a view like the one below. These are the settings we recommend. Make a random key out of some digits/characters.

clip_image004

On the same page you need to enter the domain that the callbacks is made to. This include all subdomains.

clip_image005

Optional: Webservice setting if you need to Acquire, Cancel, and Refund

1. Now on the menu to the left, go to “API / Webservices –> Adgang”

2. Set a password if you are using a shared hosting environment

3. At the bottom type in the “IP address” of the webhost accessing the webservice. This needs to be the external ip address

4. Click “Opret IP-adresse” to save it

clip_image006

Editing the ePay.config File

Now we need to edit the ePay.config file.

You will find the ePay.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\ePay.config”. Usually “rootdir” is c:\inetpub.

clip_image007

Some of the below information are found in the ePay administration panel, so start by logging in you aren’t already.

Finding debug

If set to “True” you will be prompted to click a button before posting the information to “ePay” otherwise it will do an autosubmit using Javascript. When running in production, you will want this set to “False”.

Finding callback

Leave this at “(auto)” if in doubt.

Finding acceptUrl

Url the user is returned to after successfully authorizing her credit card.

Finding declineUrl

Url the user is returned to if she cancels a purchase.

Finding merchantNumber

The “Indløsningsnummer” is unique for your account. This can be found in the menu “Indstillinger -> Betalingssystemet”. Also make sure that “Test mode” is not active, like it is on the picture below, if you’re setting up a production environment.

clip_image008

Optional: Finding pwd if you need to Acquire, Cancel, or Refund

Password used for the webservice, if using a shared host. This can be found in the menu “API / Webservices -> Adgang”.

clip_image009

Finding useMd5

True/False indicating weather to use Md5. Its recommended to use Md5 for security reasons.

Finding key

The Md5 key set in the administration panel.

This can be found in the menu “Indstillinger–> Betalingssystemet”.

clip_image010


Executing a Pipeline on Callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “ePay” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'ePay'

or just edit it manually in SQL Server Management Studio.

clip_image011

Now the default piplline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image013

ToCompletedOrder.config

clip_image015

FAQ

· Test mode – Make sure test mode if turned off when going live.

posted on Monday, 18 October 2010 11:43:44 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Wednesday, 13 October 2010

The uCommerce Catalog Foundation holds all the catalog information in your installation and as such serves as the most important foundation in uCommerce. This post will give you an idea of one of the most basic building blocks of the Catalog Foundation: Product Definitions… but first some basics.

Products, Product Families, and Variants. Oh My!

Before we get into the nitty gritty of things we need to get the terminology right so we agree on what’s what.

Products are pretty straight forward they represent a single product in the system with no variants associated.

Product Families are pretty much the same as a product but differ in that they’ve got variants associated with them, hence the product family.

Variants represents a single product much like a stand alone product, but they cannot stand by themselves. Variants are always associated with a product family.

uCommerce supports both products and product families and the good news is you don’t have to go with one over the other. You simply decide on a per product basis whether or not to support variants. So you might have some products be stand alone products and others be product families. Whatever works for your scenario.

Product Definitions

Product Definitions 2Before you can start using catalogs you need to perform some setup to determine the data you’ll be working with, i.e. the taxonomy of your site, the various types of products you’ll support in the site, and finally your pricing scheme.

Product definitions are the most fundamental building blocks of the uCommerce Catalog Foundation. If you’re familiar with Umbraco think of them as Document Types for products. Basically a product definition determines what data you’re working with in uCommerce, both via the UIs and the APIs.

Each product definition in uCommerce represents a different type of product available through your store. Say you’re selling Software and Shirts as in the screenshot below. Software requires a completely different set of data to sell from a Shirt. Notice that Software has different properties from the Shirt.

With product definitions you can tailor uCommerce to your client’s needs.

Adding a New Product Definition

uCommerce supports as many product definitions as you need. Simply right click the Product Definitions node and click create to add a new definition. Each of the product definitions must be named uniquely so you can find it later on.

Adding New Properties to Product Definitions

You can add new properties by right clicking the product definition and clicking Create. Just as you would do when creating a new content node in Umbraco. As you can see the product definition needs a name which will be your key for reference the product definition from code as well the identifier for the product type.

The product family check box indicates whether the product definition allows variants or not. A product family is basically a product with a bunch variants associated with it while a non-product family (product) represent just a single product.

uCommerce Product Definition Create New Property

Once created you’ll have the opportunity to change the meta data of the property to suit your needs.

uCommerce Product Definitions Property Details 

Multilingual Properties

If you need to maintain the data of the property in multiple languages you can tick off the multilingual check box. This will give you a field per language configured in Umbraco.

uCommerce Multilingual Property Definition

If you specify a property to be multilingual the property will show up under the multilingual tabs when you go and edit products.

uCommerce Product Editor Multilingual Properties

Display on Website

A true/false value which is set on the property when accessed via the API.

uCommerce Display on Site Property Definition

Variant Properties

Determines whether the property should be a variant property that you maintain under a product family. If one or more exist the product will turn into a product family automatically and enable you to create multiple variants associated with the product family.

uCommerce Variant Property Definition

Setting the property as a variant property will add the Variants tabs to the editor to any product based on the product definition and will enable you to create variations of a product as part of a product family.

uCommerce Variant Editor

Render in Editor

Sometimes you need data that you don’t want the user to edit. Ticking this check box will tell uCommerce not to render this property as part of the editor UI essentially giving you meta data that you can use and maintain from the API without having to worry about the user tampering with it.

uCommerce Render in Editor Property Definition

Data Types

Each of the properties created in the previous paragraphs are based on data types, which you select when you create new ones. uCommerce comes with a number of built-in data types such as ShortText, LongText, Number, Boolean, Enum, and Image.

uCommerce DataType Property Definition 

Data types include string, number, bool, and enum which is a special type which enables you to predefine a list of values allowed for the user to select, e.g. colors, sizes, basically data with a finite number of options to choose from.

uCommerce Data Type Editor

Validation Expressions

Data types can have validation expressions associated with them to validate user input when editing in the product editor. A validation expression is a standard regular expression evaluated whenever a user clicks the save button.

uCommerce Data Type Validation Expression

In Conclusion

The Product Definition is the secret sauce which makes the uCommerce Catalog Foundation extremely powerful enabling you to model the reality you face be it as a developer creating an e-commerce solution for a client or for yourself.

An important aspect about a product definition is that you can change your mind whenever you please. If you start out without variants nothing is holding you back from moving your properties around even after you start creating products based on that product definition. uCommerce will simply reflect the changes you need without you having to create you products from scratch.

posted on Wednesday, 13 October 2010 21:17:46 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Thursday, 02 September 2010

When working in the uCommerce Admin tool it can be useful to be able to add your own custom nodes some in the trees, e.g. a new node under Product Catalog, Orders, Analytics, or Settings. This post describes how to achieve this.

The uCommerce tree handlers are using the standard Umbraco extension point for creating new trees. You can learn more about that in the excellent Umbraco.tv episode Adding a Custom tree.

uCommerce-UI-extension-1-New-Node

Finding the Extension Point

uCommerce comes with a bunch of tree handlers for managing all aspects of the uCommerce Foundations. Each tree handler deals with a separate root node in the uCommerce tree so depending on which tree you want to insert your custom node in you’ll need a different tree handler.

The tree handlers are called Load<whatever> where the whatever is the actual tree that it’s dealing with. All handlers are found in the assembly called UCommerce.Umbraco.dll which contains the integration pieces for Umbraco.

Handlers include:

Product Catalog tree – UCommerce.Umbraco.Menu.LoadCatalog
Orders tree– UCommerce.Umbraco.Menu.LoadOrders
Analytics tree– UCommerce.Umbraco.Menu.LoadAnalytics
Settingstree – UCommerce.Umbraco.Menu.LoadSettings

 

uCommerce-UI-extension-2-Tree-Handlers

Overriding the Default uCommerce Tree Handler

When you’ve found the handler you want to extend you need to  derive from the uCommerce class. In my case I’m extending the Product Catalog handler so I will derive from the LoadCatalog class.

To add your own node your need to override the method called Render(XmlTree tree) on the tree handler. This method is responsible for actually rendering the tree and will be triggered by Umbraco once configured to do so later on.

Please note that Umbraco isn’t exactly forthcoming with error messages which crop up during development of a tree handler so you’ll have to whip out the Sherlock Holmes thinking cap to find some of the issues which crop up. Especially Javascript for your Action will cause you grief.

public class MyCustomTreeHandler : LoadCatalog
{
    // Constructor is required by base type
    public MyCustomTreeHandler(string application) : base(application)
    {   
    }
 
    public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
    {
        base.Render(ref tree);
 
        XmlTreeNode node = XmlTreeNode.Create(this);
 
        string nodeId = "MyCustomNode";
        // Unique id of the node, can be used to store information about a data object being displayed on a particular node
        node.NodeID = nodeId;
 
        // Text to display on the node itself
        node.Text = "My Custom Node";
 
        // Action trigged by mouse click
        node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MyPage.htm';"); 
 
        node.Icon = "folder.png";
        node.OpenIcon = "folder.png";
 
        // The node type refers to a config file with Umbraco
        // which specifies additional config for a particular node
        // like dialogs and available right click actions
        // ~/umbraco/config/create/UI.xml
        node.NodeType = "my_custom_node_type";
 
        // Available right click actions as per UI.xml
        node.Menu = new List<IAction>(new IAction[] { ActionNew.Instance, ContextMenuSeperator.Instance, ActionDelete.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance });
 
        // Indicates whether the nodes is expandable
        node.HasChildren = false;
 
        // Source is used to perform async calls
        // uCommerce provides an abstraction which works for both Umbraco 4 and 4.5
        // Notice that the nodeId is reused for this call
        node.Source = GetVersionSafeTreeServiceUrl(nodeId);
 
        tree.Add(node);
    }
}

With the following code the node shows up in the tree. Interestingly the custom node turns up as a subnode to every single node in the catalog system, which isn’t what we’re after. We’d like to be able to insert a node anywhere in the tree, but just that one time.

Read on to find out what’s going in.

Determining Where You are in the uCommerce Tree

uCommerce trees are different from Umbraco trees in the sense that a single tree works with many different types of nodes. For example a catalog consists of product catalog groups (the store level), catalogs, and categories. To help you figure out where you are there are two properties you can ask: CurrentId and CatalogNodeType.

When uCommerce builds its tree ids are consistently built up in the format catalogNodeTypeName_ObjectId. This helps uCommerce determine which internal type we’re working with, e.g. a catalog group, a catalog, or a category, and which data object is currently in play.

To insert our node in a specific location we can ask CatalogNodeType what the type of the node currently being rendered is thus enabling us to only insert the custom node in a specific location in the tree.

For my example I’m inserting the node on the same level as the product catalog groups by inserting the following piece of code in the Render method of the tree handler:

public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
{
    base.Render(ref tree);
    
    if (CurrentNodeType != CatalogNodeType.Root) return;
    
    ...
}

Enabling Child Nodes for a Custom Node

Should you need child nodes for your new node that’s absolutely possible as well. Some additional plumbing is needed to determine which nodes to load for a particular super node.

This is where the Node.Source property comes into play. You’ll have seen it configured on our custom node already like so node.Source = GetVersionSafeTreeServiceUrl(nodeId);.

Basically Umbraco loads child nodes on the fly by requesting a back end URL which is called TreeDataService.ashx. Among the parameters passed to this handler is the nodeKey which tells you the sub tree being requested.

uCommerce-UI-extension-5-Tree-Data-Service

To make sure that we only generate child nodes for our MyCustomNode a check to determine which node is being requested is required as a single handler does all the work for the entire tree. For that to work we have to refactor our code a bit to support the sub nodes.

The Render method is still our main entry point from Umbraco so it has to act as an check point which will determine what needs to be rendered.

public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
{
    // Make sure to only render the default nodes at the root
    // and not under our custom node
    if (NodeKey != "MyCustomNode")
        base.Render(ref tree);
 
    XmlTreeNode node = null;
 
    // If the NodeKey passed by Umbraco is our custom id
    // we know that we need to render subnodes for our
    // custom node
    if (NodeKey == "MyCustomNode")
    {
        node = XmlTreeNode.Create(this);
        node.NodeID = "MyCustomSubnode";
        node.Text = "My Custom Subnode";
        node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MySubPage.htm';");
        node.Icon = "folder.png";
        node.OpenIcon = "folder.png";
        node.NodeType = "my_custom_node_type";
        node.HasChildren = false;
    }
    // If we're at the root of the catalog
    // we render the custom node
    else if (CurrentNodeType == CatalogNodeType.Root)
    {
        node = RenderMyCustomNode();
    }
    else return;
 
    // Add the rendered content to the tree
    tree.Add(node);
}

Final Code

Final code with support for a custom node under Product Catalog and child nodes for that looks like this:

using System;
using System.Collections.Generic;
using UCommerce.Umbraco.Menu;
using umbraco.cms.presentation.Trees;
using umbraco.interfaces;
using umbraco.BusinessLogic.Actions;
 
namespace MyUCommerceApp.Umbraco
{
    public class MyCustomTreeHandler : LoadCatalog
    {
        // Constructor is required by base type
        public MyCustomTreeHandler(string application)
            : base(application)
        {
        }
 
        public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
        {
            // Make sure to only render the default nodes at the root
            // and not under our custom node
            if (NodeKey != "MyCustomNode")
                base.Render(ref tree);
 
            XmlTreeNode node = null;
 
            // If the NodeKey passed by Umbraco is our custom id
            // we know that we need to render subnodes for our
            // custom node
            if (NodeKey == "MyCustomNode")
            {
                node = XmlTreeNode.Create(this);
                node.NodeID = "MyCustomSubnode";
                node.Text = "My Custom Subnode";
                node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MySubPage.htm';");
                node.Icon = "folder.png";
                node.OpenIcon = "folder.png";
                node.NodeType = "my_custom_node_type";
                node.HasChildren = false;
            }
            // If we're at the root of the catalog
            // we render the custom node
            else if (CurrentNodeType == CatalogNodeType.Root)
            {
                node = RenderMyCustomNode();
            }
 
            else return;
 
            tree.Add(node);
        }
 
        public XmlTreeNode RenderMyCustomNode()
        {
            XmlTreeNode node = XmlTreeNode.Create(this);
 
            string nodeId = "MyCustomNode";
 
            // Unique id of the node, can be used to store information about a data object being displayed on a particular node
            node.NodeID = nodeId;
 
            // Text to display on the node itself
            node.Text = "My Custom Node";
 
            // Action trigged by mouse click
            node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MyPage.htm';");
 
            // Images are picked up from ~/umbraco/images/umbraco
            node.Icon = "folder.png";
            node.OpenIcon = "folder.png";
 
            // The node type refers to a config file with Umbraco
            // which specifies additional config for a particular node
            // like dialogs and available right click actions
            // ~/umbraco/config/create/UI.xml
            node.NodeType = "my_custom_node_type";
 
            // Available right click actions as per UI.xml
            node.Menu = new List<IAction>(new IAction[] { ActionNew.Instance, ContextMenuSeperator.Instance, ActionDelete.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance });
 
            // Indicates whether the nodes is expandable
            node.HasChildren = true;
 
            // Source is used to perform async calls to load children of the node
            // uCommerce provides an abstraction which works for both Umbraco 4 and 4.5
            // Notice that the nodeId is reused for this call
            node.Source = GetVersionSafeTreeServiceUrl(nodeId);
            return node;
        }
    }
}

Configuring Your Custom Tree Handler with Umbraco

To replace the uCommerce tree handler with your own you need to open up the Umbraco database and look for the table called umbracoAppTree.

This table specifies the piece of code which builds a given tree and which app it’s associated with. The default uCommerce config will some like this:

uCommerce-UI-extension-3-Configure-Tree-Handler-with-Umbraco

The fields in question are called treeHandlerAssembly and treeHandlerType, which contains the name of the DLL which contains your new class and the name of the class which will handle the tree.

With the custom tree handler in place the configuration will now look like this:

uCommerce-UI-extension-4-Configure-Tree-Handler-with-Umbraco

In Summary

You can hook into almost any aspect of the uCommerce Admin to replace or extended the existing UIs thanks to the flexibility of Umbraco and the custom extensions built on top.

Working with the uCommerce trees is much the same process as the default Umbraco approach although you will have to deal with different types of nodes in a single tree.

With this extension in place you’re free to load your own webform and do whatever you want with it.

posted on Thursday, 02 September 2010 12:29:45 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Friday, 27 August 2010

uCommerce holds rich information about each product in the system with the ability to customize the product schema to customer needs. This flexibility comes at a cost though as the database schema to hold both the product information and the meta information can be quite difficult to grok.

This posts highlights the tables used for both the products and variants themselves.

Product schema

Product table
Product and the variants for a given product. Variants are associated with the product family by using the ParentProductId found in the table. Products (without variants) and product families (with variants) will have a null values in the ParentProductId column, which can be useful for querying the system.

ProductProperty table
Invariant product properties are stored in this table meaning any property not configured as Multi lingual in the uCommerce backend.

Invariant product properties

 

ProductDescription and ProductDescriptionProperty tables

Whenever multi lingual properties come into play this table stores the header for each language. Say you configure Umbraco to support English and German two rows will be inserted per product to store display name, short- and long description, but more importantly this table acts as the main hub for additional multilingual properties on a product.

Each multilingual property value stored for a product is stored in the ProductDescriptionProperty table as such is very similar to the ProductProperty table described above.

Multilingual product properties


PriceGroupPrice table

Each product in uCommerce may hold multiple prices which are stored in PriceGroupPrice. The convoluted name is an indication of the link to a price group. Prices are stored the same way regardless of product and variants due to the fact that essentially a product and variant is the same thing, ParentProductId notwithstanding.

PriceGroup table

Usually you’ll configure the price groups you need in uCommerce Admin, but you still have to link up new prices with a price group to be able to add a new price for a product, either via .NET or SQL.

uCommerce price groups UI

In conclusion the uCommerce product schema holds all your custom data and can be populated from external sources either via .NET code or SQL directly to the tables. Regardless of the approach you select the schema is important to know even from a .NET perspective because the uCommerce entities reflect the data schema closely to make the disconnect between the data models as tiny as possible.

posted on Friday, 27 August 2010 07:44:13 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Friday, 28 May 2010

One of the questions I’ve come across a couple of times with uCommerce is using the LINQ API to query products by custom properties added to a product definition.

Here’s how:

var q = from product in Product.All()
  where product.ProductProperties.Where(property => 
    (property.ProductDefinitionField.Name == "MyProperty" && property.Value == "MyPropertyValue") 
    || (property.ProductDefinitionField.Name == "MyOtherProperty" && property.Value == "MyotherPropertyValue")).Count() == 2
    && product.ParentProductId == null
  select product;
posted on Friday, 28 May 2010 15:07:28 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback