Adding prices to products

Evance supports a number of price based features for each Product. In addition to a single current price, a product may have a list price, recommended retail price and volume/quantity based pricing.

A product might not have a price. You can determine if it does with the Product.hasPrice property.


<?ev if (product.hasPrice) { ?>
    ...
<?ev } ?>

The first prices you will need to cater for are:

  • Recommended Retail Price (RRP)
    RRP is optional and is not applicable to all businesses. Your theme should determine whether the RRP has been set.
    Access to RRP is available with the Product.rrp property.

  • List Price
    A product will always have a list price if it has a current price. However, its list price becomes relevant when a product is on offer (i.e. the current price is lower than its list price). The list price is available via the Product.listPrice property. You can determine if list price is relevant via the Product.isOffer property.

  • Current Price
    The current price of a product is available via the Product.price property.


<?ev if (product.hasPrice) { ?>
    
    <div class="product-pricing">
        <?ev if (product.price) { ?>
            <ul>
                <!-- Recommended Retail Price -->
                <?ev if (product.rrp) { ?>
                <li>RRP {{ product.rrp }}</li>
                <?ev } ?>
                
                <!-- List Price -->
                <?ev if (product.isOffer) { ?>
                <li>WAS {{ product.listPrice }}</li>
                <?ev } ?>
                
                <!-- Current Price -->
                <li>{{ product.price }}</li>
            </ul>
        <?ev } ?>
    </div>
    
<?ev } ?>


Supporting price mechanisms

Price mechanisms determine how a product's sale price is calculated when added to cart. Fortunately, a product may only support a single price mechanism which makes it easier to display. In short, a price mechanism is either based on a unit of time, or not.

  • Buy (default)
    Product is a one-off purchase based on a unit of quantity.
    Determined using the Product.isBuy property.

  • Hire
    Product is rented for a fixed term with its price based on units of time (per day, week, month or year).
    For example a product may have a price of £10 per month.
    Determined using the Product.isHire property.

The simplest way to cater for this is determining if the price mechanism is not Product.isBuy.


    ...
    
    <!-- Current Price -->
    {{ product.price }}
    
    <!-- Price Mechanism -->
    <?ev if (!product.isBuy) { ?>
        per {{ product.priceUnit }}
    <?ev } ?>
    
    ...


Prices including or excluding tax

Evance allows websites to show prices either inclusive or exclusive of sales tax (VAT). For international websites with multiple locales, this preference may differ per locale. You can determine if the price includes tax by default using the Product.includesTaxproperty. 

Generally, it is preferable to indicate a price excludes tax with "+VAT" suffix (or similar). Evance offers a convenient Product.priceSuffix property as the preferred method for this purpose.


    ...
    
    <!-- Current Price -->
    {{ product.price }}
    
    <!-- Tax message -->
    {{ product.priceSuffix }}
    
    <!-- Price Mechanism -->
    <?ev if (!product.isBuy) { ?>
        per {{ product.priceUnit }}
    <?ev } ?>
    
    ...

You may also decide to show prices both including tax and excluding tax. This may achieved via the Price.includingTax() and Price.excludingTax()methods respectively.


    ...
    
    <!-- Current Price Inc.Tax -->
    {{ product.price.includingTax() }} Inc. VAT
    
    <!-- Current Price Exc.Tax -->
    {{ product.price.excludingTax() }} Exc. VAT
    
    ...


Multi-currency

The preferred method to support multi-currency is via Evance's multi-locale system (requires a Premium plan). This displays prices to website visitors in the currency appropriate to the website's current locale. In this scenario you do not need to implement any multi-currency support within your theme.

However, there may be scenarios where you wish to offer multiple currencies in countries where multiple currencies are recognised.


    ...
    
    <!-- Current Price Native Currency -->
    {{ product.price }}
    
    <!-- Current Price converted to USD -->
    {{ product.price.toMoney().convertTo('USD') }}
    
    ...


Lowest quantity based price

Each product supports quantity/volume pricing. For example, quantity of 1 at £10 each and a quantity of 5 or more at £9 each. In this scenario £9 is the lowest price available and this will be reflected in the Product.price property. You can determine if this is the case using the Product.isFromPrice property.


    ...
    
    <!-- Current Price -->
    
    <?ev if (product.isFromPrice) { ?>
        from
    <?ev } ?>
    
    {{ product.price }}
    
    ...


Available on Github

The code examples above are incomplete for easy reading. A more complete example of an EVML product price partial for most theme requirements is now available on Github.

View on Github


Quantity based pricing

You can determine if a Product has quantity/volume based pricing with the Product.hasVolumePricing() method.

A complete list of a Product's volume prices is available from the Product.volumePricing() method, which returns an Object based on Product.priceUnit. Each property contains an Array of ProductPrice objects.


    
    <?ev if (product.hasVolumePricing()) { ?>
        <?ev if (product.isBuy) { ?>
            
            Quantity pricing
            <ul>
            <?ev for (var volumePricing of product.volumePricing().each) { ?>
                <li>
                {{ volumePricing.quantity }} or more at {{ volumePricing.price }} each
                </li>
            <?ev } ?>
            </ul>
            
        <?ev } else { ?>
            
            <?ev for (var unit in product.volumePricing()) { >
            
                Prices per {{ unit }}
                <ul>
                <?ev for (var volumePricing of product.volumePricing()[unit]) { ?>
                    <li>
                        {{ volumePricing.quantity }} or more at {{ volumePricing.price }}
                        
                        Minimum of {{ volumePricing.minUnits }} {{ unit }}s
                    </li>
                <?ev } ?>
                </ul>
            <?ev } ?>
            
        <?ev } ?>
    <?ev } ?>