discount — implement per-customer item or order discounts
| Attribute | Pos. | Req. | Default | Description |
|---|---|---|---|---|
| code | Yes | |||
| discount_space | space | ||||
| subtract | ||||
| level | ||||
| interpolate | 0 | interpolate input? | ||
| reparse | 1 | interpolate output? | ||
| hide | 0 | Hide the tag return value? |
The tag is used to implement per-customer discounts. Discounts can be applied to individual items, groups of items, or total orders.
The tag accepts Perl code in its body. Two special variables,
$q and $s, are available and
represent item quantity and base price.
Perl variables can be shared among [calc] blocks
and the [discount] tag within the same page, allowing for
greater flexibility. See the section called “EXAMPLES”.
For an introduction and theory behind item discounts, please see the discount glossary entry.
Example: Straight 20% discount on all items
[discount ALL_ITEMS] $s * .8 [/discount]
Or the same as above, with named attributes:
[discount code=ALL_ITEMS] $s * .8 [/discount]
Example: Discount of 25% for an individual item
To take 25% off of item SKU 00-342, use:
[discount 00-342] $s * .75 [/discount]
Example: Discount of 25% for an individual item, only if quantity ordered is 1
[discount 00-342] $q == 1 ? $s * 0.75 : $s [/discount]
Example: Resetting discounts
To reset a discount, simply set it to the empty string:
[discount ALL_ITEMS][/discount]
Example: Dynamic discounts using Perl
Perl code can, of course, be used to apply the discounts. Sometimes,
this needs to include some pre-processing which you need to do outside
the [discount] tag. You can freely do this within the [calc] tag,
as the values will be retained and visible inside [discount]. For
each item ordered, this example gives a 10% discount for a minimum quantity
of 2, with 5% more for each "extra quantity" (but up to a maximum discount of
30%):
[calc]
[item-list]
$totalq{"[item-code]"} += [item-quantity];
[/item-list]
return '';
[/calc]
[item-list]
[discount code="[item-code]"]
return ($s) if $totalq{"[item-code]"} == 1;
return ($s * .70) if $totalq{"[item-code]"} > 6;
return ($s * ( 1 - 0.05 * $totalq{"[item-code]"} ));
[/discount]
[/item-list]
Example: Applying discount to a specific "instance" within ordered quantity
Here is an example of a special discount for item code
00-343 which sets the price of the
second "instance" ordered to 0.01:
[discount 00-343] return $s if $q == 1; my $p = $s/$q; my $t = ($q - 1) * $p; $t .= 0.01; return $t; [/discount]
Example: Displaying the discount amount received
If you want to display the discount amount to the user, simply use the
item-discount tag:
[item-list] Discount for [item-code]: [item-discount] [/item-list]
Example: Displaying the total discount
When you want to display the total discount for an item, you need to
use [calc]:
[item-list]
Total discount applied to [item-code] is: [currency][calc]
[item-discount noformat=1] * [item-quantity]
[/calc][/currency]
[/item-list]
Example: Using wholesale price for special promotions
In the following example, items with modifier "promotion" receive the price defined in products:wholesale instead of products:price.
[perl tables='products']
my %seen = ();
foreach $item (@{$Items}) {
next unless $item->{promotion};
next if $seen{$item->{code}}++;
my $promo_price = $Tag->data('products','wholesale',$item->{code});
$Session->{discount}->{$item->{code}} = "$promo_price * \$q";
}
[/perl]
Interchange 5.9.0:
Source: code/SystemTag/discount.coretag
Lines: 66
# Copyright 2002-2007 Interchange Development Group and others
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. See the LICENSE file for details.
#
# $Id: discount.coretag,v 1.7 2007-03-30 23:40:49 pajamian Exp $
UserTag discount Order code
UserTag discount AddAttr
UserTag discount attrAlias space discount_space
UserTag discount hasEndTag
UserTag discount PosNumber 1
UserTag discount Version $Revision: 1.7 $
UserTag discount Routine <<EOR
# Sets the value of a discount field
sub {
my($code, $opt, $value) = @_;
# API compatibility
if(! ref $opt) {
$value = $opt;
$opt = {};
}
if (! ($::Discounts
and $Vend::Session->{discount_space}
and $Vend::Session->{discount}
and $Vend::DiscountSpaceName)) {
$::Discounts
= $Vend::Session->{discount}
= $Vend::Session->{discount_space}{ $Vend::DiscountSpaceName = 'main' }
||= ($Vend::Session->{discount} || {});
}
my $dspace;
if ($Vend::Cfg->{DiscountSpacesOn} and $dspace = $opt->{discount_space}) {
$dspace = $Vend::Session->{discount_space}{$dspace} ||= {};
}
else {
$dspace = $::Discounts;
}
if($opt->{subtract}) {
$value = <<EOF;
my \$tmp = \$s - $opt->{subtract};
\$tmp = 0 if \$tmp < 0;
return \$tmp;
EOF
}
elsif ($opt->{level}) {
$value = <<EOF;
return (\$s * \$q) if \$q < $opt->{level};
my \$tmp = \$s / \$q;
return \$s - \$tmp;
EOF
}
$dspace->{$code} = $value;
delete $dspace->{$code}
unless defined $value and $value;
return '';
}
EOR