Cookbook/Pricing

= Modeling Price Information =

This page describes how the GoodRelations ontology for e-commerce can be used to model price information. Such can be embedded using the W3C RDFa syntax into Web pages and will be crawled and used by next generation Web search engines.

One of the design principles of GoodRelations (*) is that


 * simple things should be simple to express, while
 * complex things should be possible to model without tweaking or extending the vocabulary.

On this page, we demonstrate how the established GoodRelations elements can be used to expose fine-granular price information like

"We lease our boats for 24 USD per 6 hours for 0-3 days, and for 75 USD per day for any longer rental."

(*) Wikiquote attributes this principle to Alan Kay.

Exposing GoodRelations rich meta-data can be as simple as this:

Minimal Example: RDFa Syntax
But when you have more fine-grained data available on your end, you will likely expose that full level of detail on the Web.

= Preliminaries =

RDFa and Microdata Examples
The examples below are all in Turtle syntax, which is more human-readable and easier to maintain than RDFa or Microdata. You can always get an RDFa or Microdata variant of a code example using the free tool at
 * http://rdf-translator.appspot.com/

Prefixes
First, we have to define the prefixes used in the examples:

Simple Offer
Next, let's model a simple offer to sell potatoes. Note: The actual object being offered (i.e. the potatoes) can (and should) be described in more detail. See the other GoodRelations recipes for examples. This recipe focuses on modeling the pricing.

= Pricing =

Example: 1 USD per piece
The UN/CEFACT Common Code for "piece" or "item" is "C62".

Example: 4 USD per kilogram
The UN/CEFACT Common Code for "kilogram" is "KGM".

Example: Price given in per liter, kg, meter, ...
There are two different ways of modeling this, and both are supported by GoodRelations:

1. You can e.g. say that you offer salt or red wine and that the price is USD 1 per 10 g or 1 l.

2. You can say that you offer exactly 10g of salt or 1 l of red wine, but maybe accept this offer multiple times.

In case, you model it using gr:hasUnitOfMeasurement attached to the gr:UnitPriceSpecification.

Example: 1 l of Bordeaux red wine for 1 USD/liter This approach works only if the price is related to a standard unit (C62, INH, LTR, GRM, ...). So you can say that the price is 1 USD / liter (unit code: LTR), but this way, you cannot say that it is 1 USD per 10 gram or per ten liters.

If you want to say something like "USD 1 per 10 g", you must


 * create a gr:SomeItems node representing some objects / some amount of the good,
 * add this to a gr:Offering with gr:includesObject and a gr:TypeAndQuantityNode with 10 g as the quantity
 * set the price to 1 USD per 1 piece (code for piece:C62) of this offer (because one piece of this gr:SomeItems instance means 10 g).

Example: Table salt for 1 USD / 10 g

Case 1: The price per unit is reduced for ADDITIONAL items beyond a certain minimum quantity
Example: Something costs 4 USD per kilogram up to 5 kilogram, 3 USD for any quantity beyond that. If you buy 9 kilogram, you will have to pay


 * 5 kg * 4 USD for the first 5 kg PLUS
 * 4 kg * 3 USD for the additional 4 kg

The total will be 32 USD.

GoodRelations pattern: Simply attach multiple instances of gr:UnitPriceSpecification to the gr:Offering and constrain their validity using non-overlapping gr:hasEligibleQuantity and gr:hasUnitOfMeasurement properties, i.e., two unit price specifications, one for 0..5 kg, and one for everything beyond 5 kg. Since there is no way to indicate "greater than", we have to use "5.00000001"^^xsd:float in the example below. You have to link from the offering to both price specifications now. Simply change


 * gr:hasPriceSpecification foo:price.

to


 * gr:hasPriceSpecification foo:price1, foo:price2.

So the offer node will look as follows:

Case 2: The price per unit is reduced for ALL items beyond a certain minimum quantity
Example: Something costs 4 USD per kilogram for purchases of up to 5 kilogram 3 USD for any quantity beyond that. If you buy 9 kilogram, you will have to pay


 * 9 kg * 3 USD = 27 USD

GoodRelations pattern: You have to use two gr:Offering instances in this case, one for quantities up to 5 kg and one for quantites beyond 5 kg. So in this second scenario, you constrain the validity of the two offers using non-overlapping gr:hasEligibleQuantity and gr:hasUnitOfMeasurement properties. Since there is no way to indicate "greater than", we have to use "5.00000001"^^xsd:float in the example below. Important: Don't forget to use gr:offers to link from the company (gr:BusinessEntity) to BOTH offers (gr:Offering) now:

Seasonal Discounts and Special Offers
Simply attach multiple gr:UnitPriceSpecification instances to the gr:Offering and constrain their temporal validity using gr:validFrom and gr:validThrough.

Example: 4 USD per kilogram, 3 USD from May 1 - June 30, 2010 Same as in the previous example, you have to link from the offering to both price specifications now.

Change


 * gr:hasPriceSpecification foo:price.

to


 * gr:hasPriceSpecification foo:price1, foo:price2.

Billing Increments
The property gr:billingIncrement with a domain of gr:UnitPriceSpecification and a range of xsd:float allows indicating the smallest billable unit of an item.

Examples:


 * Price 2 euro per hour, billing in units of 15 minutes
 * The price be 4 USD per kilogram of potatoes, but the billing will be based on the quantity rounded up to the next multiple of 100 grams.

The UN/CEFACT Common Code for "kilogram" is "KGM", that for gram is "GRM". Note that you have to use the same unit for the billing increment and the unit of measurement for the price reference, so either you express this as 4 USD per kilogram with an increment of 0.1 kilograms or as a price of 0.004 USD per gram with a billing increment of 100 grams. Important: The billing increment specifies only the rounding steps for determining the billable quantity. The price is given per unit of measurement. For instance, the example above expresses that the price is 4 USD per kilogram and not 4 USD per 0.1 kilograms.

Price Ranges
Sometimes, the price can only be given as an interval, depending on characteristics of the actual item or the buying party. Simply use gr:hasMaxCurrencyValue and gr:hasMinCurrencyValue for the upper and lower bounds instead of gr:hasCurrencyValue. An RDFS-style reasoner will expand gr:hasCurrencyValue to two matching gr:hasMinCurrencyValue and gr:hasMaxCurrencyValue statements anyway. When querying, you should process gr:hasMinCurrencyValue and gr:hasMaxCurrencyValue instead of gr:hasCurrencyValue, unless you want to ignore offers that give ranges only.

Indicating List Prices
You can indicate retails prices as recommended by the supplier etc. using the gr:priceType property. This attribute can be used to distinguish multiple different gr:UnitPriceSpecification instances for the same offer. It supersedes the former gr: isListPrice property. The following values are recommended:


 * SRP: "suggested retail price" - applicable for all sorts of a non-binding retail price recommendations, e.g. such published by the manufacturer or the distributor. This value replaces the former gr:isListPrice property.
 * INVOICE: The invoice price, mostly used in the car industry - this is the price a dealer pays to the manufacturer, excluding rebates and charges.

The absence of this property marks the actual sales price.

Car Rental: 25 USD / day plus 1 USD per mile
You can combine multiple gr:UnitPriceSpecification instances that are valid in combination. For example, a rental car business might say that the price for a particular rental car is 25 USD per day plus 1 USD per mile.

Note that the UN/CEFACT Common Code for "day" is "DAY", that for "car mile" is "1A". Also note that the gr:BusinessFunction for rental is gr:LeaseOut. Note: The vehicles being offered can (and should) be described in more detail. See the other GoodRelations recipes for examples. This recipe focuses on modeling the pricing.

Cancellation Rules
GoodRelations does not provide a means for modeling cancellation policies and fees in detail, but you can easily attach them using to the gr:UnitPriceSpecification node.

= Complex Examples =

Boat Rental: 24 USD / 6 hours for 0-3 days, 75 USD per day for any longer rental
Note that the price information "24 USD per 6 hours" must be translated into 24/6 = 4 USD per hour and a billing increment of 6.0 hours. The UN/CEFACT Common Code for "hour" is "HUR".