.\" Automatically generated by Pod::Man version 1.15
.\" Wed May 5 11:41:22 2004
.\"
.\" Standard preamble:
.\" ======================================================================
.de Sh \" Subsection heading
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Ip \" List item
.br
.ie \\n(.$>=3 .ne \\$3
.el .ne 3
.IP "\\$1" \\$2
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. | will give a
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used
.\" to do unbreakable dashes and therefore won't be available. \*(C` and
.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<>
.tr \(*W-|\(bv\*(Tr
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
'br\}
.\"
.\" If the F register is turned on, we'll generate index entries on stderr
.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and
.\" index entries marked with X<> in POD. Of course, you'll have to process
.\" the output yourself in some meaningful fashion.
.if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. nr % 0
. rr F
.\}
.\"
.\" For nroff, turn off justification. Always turn off hyphenation; it
.\" makes way too many mistakes in technical documents.
.hy 0
.if n .na
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
.bd B 3
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ======================================================================
.\"
.IX Title "ic_ecommerce 8"
.TH ic_ecommerce 8 "Interchange 5.2.0" "2004-05-05" "Interchange"
.UC
.SH "NAME"
ic_ecommerce \- Interchange Ecommerce Functions
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
.SH "THE ORDER PROCESS"
.IX Header "THE ORDER PROCESS"
Interchange has a completely flexible order basket and checkout
scheme. The foundation demo presents a common use of this process,
in the directory pages/ord \*(-- the files are:
.PP
.Vb 3
\& basket.html The order basket displayed by default
\& checkout.html The form where the customer enters their billing
\& and shipping info
.Ve
.RS 4
.RS 8
.Ip "" 12
and in the directory etc:
.Sp
.Vb 1
\& receipt.html The receipt displayed to the customer
.Ve
.RE
.RS 8
.RE
.RE
.RS 4
.RE
.PP
It is not strictly necessary to display an order basket when an item
is ordered. If you specify a different page to be displayed that is
fine, but most customers will be confused if you don't give them an
indication that the order operation has succeeded.
.PP
Any order basket is an \s-1HTML\s0 \s-1FORM\s0. It will have a number of
variables on it. At the minimum it must have an [item-list] to loop
through the items, and the quantity of each item must be set in
some place on that form. Any valid Interchange tags may be used on the
page, and you may use multiple item lists if necessary.
.Sh "How to order an item"
.IX Subsection "How to order an item"
Interchange can either use a form-based order or a link-based order to
place an item in the shopping cart. The link-based order uses the
special [order item-code] tag:
.Ip "[order code]" 4
.IX Item "[order code]"
named attributes:
.Sp
.Vb 2
\& [order code="sku" quantity="n"* href="page"* cart="cartname"* base="table"*]
\& * = optional parameters
.Ve
Expands into a hypertext link which will include the specified code in
the list of products to order and display the order page. \fBcode\fR
should be a product \s-1SKU\s0 listed in one of the \*(L"products\*(R" tables, and is
the only required parameter. \fBquantity\fR may be specified if more than
one (the default) of the item should be placed in the cart. \fBhref\fR
allows some page other than the default order page to be displayed
once the item has been added to the cart. \fBcart\fR selects the shopping
cart the item will be placed in. The optional argument \fBbase\fR
constrains the order to a particular products file \*(-- if not
specified, all tables defined as products files will be searched in
sequence for the item.
.Sp
Example:
.Sp
.Vb 1
\& Order a [order TK112]Toaster today.
.Ve
Note that this is the same as:
.Sp
.Vb 1
\& Order a [page order TK112]Toaster today.
.Ve
You can change frames for the order with:
.Sp
.Vb 1
\& Order a Toaster today.
.Ve
.Ip "[/order]" 4
.IX Item "[/order]"
Expands into . May be used to give the order tag the appearance of
being a container tag, but neither necessary nor recommended.
.PP
To order with a form, you set the form variable mv_order_item to
the item-code/SKU and use the refresh action:
.PP
.Vb 3
\&
.Ve
You may batch select whole groups of items:
.PP
.Vb 2
\&
.Ve
Items that have a quantity of zero (or blank) will be skipped, and
only items with a positive quantity will be placed in the basket.
.PP
You may also specify attributes like size or color at time of order
(see \fIHow to set up an order button\fR).
.Sh "How to set up an order link"
.IX Subsection "How to set up an order link"
On a product display page, use:
.PP
.Vb 1
\& [order 00-0011]Order the Mona Lisa
.Ve
If coming from a search results or on-the-fly page, you may use the
generated [item-code] thusly:
.PP
.Vb 1
\& [order [item-code]]Order [item-field name]
.Ve
Bear in mind that if you have not reached the page via a search or
on-the-fly operation, [item-code] means nothing and will cause an
error.
.Sh "How to set up an order button"
.IX Subsection "How to set up an order button"
Interchange can order via form submission as well. This allows you to
order a product (or group of products) via a form button. In its
simplest form, it is:
.PP
.Vb 5
\&
.Ve
The default quantity is one. An initial quantity may be set by the
user by adding an mv_order_quantity variable:
.PP
.Vb 1
\& Number to order:
.Ve
You can order multiple items by stacking the variables:
.PP
.Vb 6
\&
.Ve
Initial size or color may be set as well, provided \fIUseModifier\fR is
set up properly:
.PP
.Vb 1
\&
.Ve
If the order is coming from a generated flypage, loop list, or search
results page, you can get a canned select box from the
[item-accessories size] or [item-accessories size] tag. See
\&\fIItem Attributes\fR.
.Sh "How to set up an on-the-fly item"
.IX Subsection "How to set up an on-the-fly item"
If you enable the catalog directive \fIOnFly\fR, setting it to the name
of a subroutine (or possibly a UserTag) that can handle its calls,
then Interchange will add items to the basket that are not in the
product database. Interchange supplies an internal onfly
subroutine, which will work according to the examples given below.
.PP
In catalog.cfg:
.PP
.Vb 1
\& OnFly onfly
.Ve
If your item code is not to be named mv_order_item then you must
perform a rename in the Autoload routine.
.PP
A basic link can be generated like:
.PP
.Vb 5
\& Order item 000101
.Ve
The form parameter value mv_order_fly can contain any number of
fields which will set corresponding parameters in the item attributes.
The fields are separated by the pipe (|) character and contain
value-parameter pairs separated by an = sign. (These are URL-encoded
by the [area ...] or [page ...] tag, of course.) You can set a
size, color, or any other parameter.
.PP
The special attribute mv_price can be used in conjunction with the
CommonAdjust atom $ to set the price for checkout and display.
.PP
The [item-list] sub-tag [item-description], when used with an
item-list, will use the item attribute description to display in
the basket. Note that [item-field description] or [item-data
products description] will \s-1NOT\s0 work, as both of these tags reference
an actual field value for a record in the products table \- not
applicable for on-the-fly items. Similarly, an attempt to generate a
flypage for an on-the-fly item ([page 000101], for example) will
fail, resulting in the display of the SpecialPage \fBmissing\fR.
.PP
If you wish to set up a UserTag to process on-the-fly items, it should
accept a call of
.PP
.Vb 1
\& usertag(mv_item_code, mv_item_quantity, mv_order_fly)
.Ve
The mv_item_code and mv_order_fly parameters are required to
trigger Interchange's add_item routine (along with mv_todo=refresh
to set the action).
.PP
The item will always act as if SeparateItems or
mv_separate_items is set.
.PP
Multiple items can be ordered at once by stacking the variables. If
there is only one mv_order_item instance, however, you can stack
the mv_order_fly variable so that all are concatenated together as
with the | symbol. So the above example could be done as:
.PP
.Vb 6
\& [area form="
\& mv_todo=refresh
\& mv_order_item=000101
\& mv_order_fly=description=An on-the-fly item
\& mv_order_fly=price=100.00
\& "]
.Ve
Multiple items would need multiple instances of mv_order_item with
a corresponding mv_order_fly for each mv_order_item. You can
order both 000101 and 000101 as follows:
.PP
.Vb 2
\& [area form="
\& mv_todo=refresh
.Ve
.Vb 2
\& mv_order_item=000101
\& mv_order_fly=description=An on-the-fly item|price=100.00
.Ve
.Vb 3
\& mv_order_item=000102
\& mv_order_fly=description=Another on-the-fly item|price=200.00
\& "]
.Ve
The following two forms correspond to the above two examples, in
order, with the slight refinement of adding a quantity:
.PP
.Vb 8
\&
.Ve
.Vb 12
\&
.Ve
.Sh "Order Groups"
.IX Subsection "Order Groups"
Interchange allows you to group items together, making a master item
and sub-items. This can be used to delete accessories or options when
the master item is deleted. In its simplest form, you order just one
master item and all subsequent items are sub-items.
.PP
.Vb 7
\&
.Ve
If you wish to stack more than one master item, then you must define
mv_order_group for \fBall\fR items, with either a 1 value (master) or 0
value (sub-item). A master owns all subsequent sub-items until the
next master is defined.
.PP
.Vb 12
\&
.Ve
When the master item 00\-0011 is deleted from the basket,
00\-0011a will be deleted as well. And when 19\-202 is deleted, then
99\-102 will be deleted from the basket.
.PP
\&\s-1NOTE:\s0 Use of checkboxes for this type of thing can be hazardous, as
they do not pass a value when unchecked. It is preferable to use
radio groups or select/drop-down widgets. If you must use checkboxes,
be sure to explicitly clear mv_order_group and mv_order_item
somewhere on the page which contains the form:
.PP
.Vb 2
\& [value name=mv_order_group set='']
\& [value name=mv_order_item set='']
.Ve
The attributes mv_mi and mv_si are set to the group and sub-item
status of each item. The group, contained in the attribute mv_mi,
is a meaningless yet unique integer. All items in a group will have
the same value of mv_mi. The attribute mv_si is set to 0 if the
item is a master item, and 1 if it is a sub-item.
.Sh "Basket display"
.IX Subsection "Basket display"
The basket \fIpage\fR\|(s) are where the items are tracked and adjusted by the
customer. It is possible to have an unlimited number of basket pages.
It is also possible to have multiple shopping carts, as in buy or
sell. This allows a basket/checkout type of ordering scheme, with
custom order pages for items which have many accessories.
.PP
The name of the page to display can be configured in several ways:
.Ip "1." 4
Set the SpecialPage order to the page to display when an item is
ordered.
.Ip "2." 4
Use the \f(CW\*(C`[order code=item page=page_name] Order it! \*(C'\fR form of
order tag to specify an arbitrary order page for an item.
.Ip "3." 4
If already on an order page, set the mv_orderpage, mv_nextpage,
mv_successpage, or mv_failpage variables.
.PP
The following variables can be used to control cart selection and page
display:
.Ip "mv_cartname" 4
.IX Item "mv_cartname"
The shopping cart (default is main) to be used for this order
operation.
.Ip "mv_failpage" 4
.IX Item "mv_failpage"
Page to be displayed on a failed order check (see \fIAdvanced
Multi-level Order Pages\fR)
.Ip "mv_nextpage" 4
.IX Item "mv_nextpage"
Page to display on a return operation.
.Ip "mv_orderpage" 4
.IX Item "mv_orderpage"
Page to be displayed on a refresh.
.Ip "mv_successpage" 4
.IX Item "mv_successpage"
Page to be displayed on a successful order check (see \fIAdvanced
Multi-level Order Pages\fR).
.Ip "mv_order_profile" 4
.IX Item "mv_order_profile"
Order profile to be used if the form action is \fIsubmit\fR (see
\&\fIAdvanced Multi-level Order Pages\fR).
.Sh "Multiple Shopping Carts"
.IX Subsection "Multiple Shopping Carts"
Interchange allows you to define and maintain multiple shopping carts.
One shopping cart \*(-- main, by name \*(-- is defined when the user session
starts. If the user orders item M1212 with the following tag:
.PP
.Vb 1
\& [order code=M1212 cart=layaway] Order this item!
.Ve
the order will be placed in the cart named \fIlayaway\fR. However, by
default you won't see the just-ordered item on the basket page. That
is because the default shopping basket displays the contents of the
\&'main' cart only. So copy the default basket page
(pages/ord/basket.html in the demo) to a new file, insert a [cart
layaway] tag, and specify it as the target page in your [order]
tag:
.PP
.Vb 1
\& [order code=M1212 cart=layaway page=ord/lay_basket] Order this item!
.Ve
Now the contents of the \fIlayaway\fR cart will be displayed. Most of the
\&\s-1ITL\s0 tags that are fundamental to cart display accept a 'cartname'
option, allowing you to specify which cart to be used:
.Ip "[cart cartname]" 4
.IX Item "[cart cartname]"
A 'sticky' setting of the default cart name to use for all subsequent
cart-related tags. Convenient, but you must remember to use [cart
main] to get back to the primary cart! As an alternative, you can
specify the desired cart as a parameter of the other tags. These are
not sticky, referencing the specified cart only for the instance in
which they are called:
.Ip "[item-list cartname]...[/item-list]" 4
.IX Item "[item-list cartname]...[/item-list]"
Iterates over the items in the specified cart \- tags like
[item-quantity] and [item-price] will be evaluated accordingly;
.Ip "[nitems cartname]" 4
.IX Item "[nitems cartname]"
Returns the total number of items in the specified cart;
.Ip "[subtotal cartname]" 4
.IX Item "[subtotal cartname]"
Returns the monetary subtotal for the contents of specified cart;
.Ip "[shipping cartname], [handling cartname], [salestax cartname], [total-cost cartname]" 4
.IX Item "[shipping cartname], [handling cartname], [salestax cartname], [total-cost cartname]"
You get the idea. It is worth noting that tags which summarize cart
contents do not need to be in used concert, or in conjunction with an
[item-list]. For instance, you can display just the grand total for
a cart on the sidebar or bottom of each page, using [total-cost] by
itself, if you wish.
.PP
You can also order items from a form, using the mv_order_item,
mv_cartname, and optional mv_order_quantity variables.
.PP
.Vb 7
\&
.Ve
If you need to utilize an alternative item price in conjunction with
the use of a custom cart, see the section on \fI\s-1PRODUCT\s0 \s-1PRICING\s0\fR for
pricing methods and strategies.
.SH "PRODUCT PRICING"
.IX Header "PRODUCT PRICING"
Interchange maintains a price in its database for every product. The
price field is the one required field in the product database \*(-- it is
necessary to build the price routines.
.PP
For speed, Interchange builds the code that is used to determine a
product's price at catalog configuration time. If you choose to change
a directive that affects product pricing you must reconfigure the
catalog.
.Sh "Simple pricing"
.IX Subsection "Simple pricing"
The simplest method is flat pricing based on a fixed value in the
products database. If you put that price in a field named price,
you don't need to do more. If you want to change pricing based on
quantity, size, color or other factors read on.
.Sh "Price Maintenance with CommonAdjust"
.IX Subsection "Price Maintenance with CommonAdjust"
A flexible chained pricing scheme is available when the
\&\fICommonAdjust\fR directive is set.
.PP
We talk below about a \fICommonAdjust string\fR; it will be defined in
due time.
.PP
A few rules about CommonAdjust, all assuming the \fIPriceField\fR
directive is set to price:
.Ip "1" 4
.IX Item "1"
.PP
If CommonAdjust is set to any value, a valid \fICommonAdjust string\fR
or not, extended price adjustments are enabled. It may also hold the
default pricing scheme.
.Ip "2" 4
.IX Item "2"
.PP
The price field may also hold a \fICommonAdjust string\fR. It takes
precedence over the default.
.Ip "3" 4
.IX Item "3"
.PP
If the value of the CommonAdjust directive is set to a CommonAdjust
string, and the price field is empty or specifically \fI0\fR, then it
will be used to set the price of the items.
.Ip "4" 4
.IX Item "4"
.PP
If no CommonAdjust strings are found, then the price will be 0,
subject to any later application of discounts.
.Ip "5" 4
.IX Item "5"
.PP
If another CommonAdjust string is found as the result of an operation,
it will be re-parsed and the result applied. Chaining is retained; a
fallback may be passed and will take effect.
.PP
Prices may be adjusted in several ways, and the individual actions are
referred to below as \fIatoms\fR. Price atoms may be \fIfinal\fR,
\&\fIchained\fR, or \fIfallback\fR. A final price atom is always applied if it
does not evaluate to zero. A chained price atom is subject to further
adjustment. A fallback price atom is skipped if a previous chained
price was not zero.
.PP
Atoms are separated by whitespace, and may be quoted (although there
should not normally be whitespace in a setting). A chained item ends
with a comma. A fallback item has a leading semi-colon. Final atoms
have no comma appended or semi-colon prepended.
.PP
A \fIsettor\fR is the means by which the price is set. There are eight
different types of price settors. All settors can then yield another
CommonAdjust string.
.PP
It is quite possible to create endless loops, so the maximum number of
initial CommonAdjust strings is set to 16, and there may be only 32
iterations by default before the price will return zero on an error.
(The maximum iterations is specified with the \fILimit\fR directive.)
.PP
\&\fB\s-1NOTE\s0\fR: Common needs are easily shown but not so easily explained;
skip to the examples in the reference below if your vision starts to
blur when reading the next section. 8\-)
.PP
\&\s-1USAGE:\s0 Optional items below have asterisks appended. The asterisk
should not be used in the actual string. Optional \fBbase\fR or \fBtable\fR
always defaults to the active products database table. The
optional \fBkey\fR defaults to the item code except in a special case for
the attribute-based lookup. The \fBfield\fR name is not optional except
in the case of an attribute lookup.
.Ip "N.NN or \-N.NN" 4
.IX Item "N.NN or -N.NN"
where N is a digit. A number which is applied directly; for instance
10 will yield a price of 10. May be a positive or negative number.
.Ip "N.NN%" 4
.IX Item "N.NN%"
where N is a digit. A number which is applied as a percentage of the
\&\fIcurrent\fR price value. May be a positive or negative number. For
example, if the price is 10 and \-8% is applied, the next price value
will be 9.20.
.Ip "table*:column:key*" 4
.IX Item "table*:column:key*"
Causes a straight lookup in a database table. The optional \fBtable\fR
defaults to the main products database table for the item (subject of
course to multiple product files). The \fBcolumn\fR must always be
present. The optional \fBkey\fR defaults to the item code except in a
special case for the attribute-based lookup. The return value is then
re-parsed as another price settor.
.Ip "table*:col1..col5,col10:key*" 4
.IX Item "table*:col1..col5,col10:key*"
Causes a quantity lookup in database table \fBtable\fR (which defaults to
the products database), with a set of comma-separated fields, looked
up by the optional \fBkey\fR. (Key defaults to the item code, of course).
If ranges are specified with .., each column in the sequence will be
used; Therefore
.Sp
.Vb 1
\& pricing:p1,p2,p3,p4,p5,p10:
.Ve
is the same as
.Sp
.Vb 1
\& pricing:p1..p5,p10:
.Ve
Leading non-digits are stripped, and the item quantity is compared
with the numerical portion of the column name. The price is set to the
value of the database column (numeric portion) that is at least equal
to it but doesn't yet reach the next break.
.Sp
\&\s-1WARNING:\s0 If the field at the appropriate quantity level is blank, a
zero cost will be returned from the atom. It is important to have all
columns populated.
.Ip "==attribute:table*:column*:key*" 4
.IX Item "==attribute:table*:column*:key*"
Does an attribute-based adjustment. The attribute is looked up in the
database \fBtable\fR, with the optional \fBcolumn\fR defaulting to the same
name as the \fIvalue\fR of the \fBattribute\fR. If the column is not left
blank, the \fIkey\fR is set to the \fIvalue\fR of the \fBattribute\fR if blank.
.Ip "& \s-1CODE\s0" 4
.IX Item "& CODE"
The leading & sign is stripped and the code is passed to the
equivalent of a [calc] tag. No Interchange tags can be used, but
the &tag_data routine is available, the current value of the price and
quantity are available as \f(CW$s\fR, and the current item (code, quantity,
price, and any attributes) are available as \f(CW$item\fR, all forced to
the package Vend::Interpolate. That means that in a UserTag:
.Sp
.Vb 4
\& $Vend::Interpolate::item is the current item
\& $Vend::Interpolate::item->{code} gives key for current item
\& $Vend::Interpolate::item->{size} gives size for current item (if there)
\& $Vend::Interpolate::item->{mv_ib} gives database ordered from
.Ve
.Ip "[valid Interchange tags]" 4
.IX Item "[valid Interchange tags]"
If the settor begins with a square bracket ([) or underscore, it is
parsed for Interchange tags with variable substitution (but no Locale
substitution). You may define a price in a \fIVariable\fR in this
fashion. The string is re-submitted as an atom, so it may yield yet
another settor.
.Ip "$" 4
Tells Interchange to look in the mv_price attribute of the shopping
cart, and apply that price as the final price, if it exists. The
attribute must be a numerical value.
.Ip ">>word" 4
.IX Item ">>word"
Tells the routine to return word directly as the result. This is
not useful in pricing, as it will evaluate to zero. But when
CommonAdjust is used for shipping, it is a way of re-directing
shipping modes.
.Ip "word" 4
.IX Item "word"
The value of word, which must not match any of the other settors,
is available as a key for the next lookup (only). If the next settor
is a database lookup, and it contains a dollar sign ($) the word
will be substituted; i.e. table:column:$ becomes
table:column:word.
.Ip "( settor )" 4
.IX Item "( settor )"
The value returned by settor will be used as a key for the next
lookup, as above.
.Sh "CommonAdjust Examples"
.IX Subsection "CommonAdjust Examples"
Most examples below use an outboard database table named \fBpricing\fR,
but any valid table including the \fBproducts\fR table can be used. We
will refer to this \fBpricing\fR table:
.PP
.Vb 4
\& code common q1 q5 q10 XL S red
\& 99-102 10 9 8 1 -0.50 0.75
\& 00-343 2
\& red 0.75
.Ve
The simplest case is a straight lookup on an attribute; \fIsize\fR in
this case.
.PP
.Vb 1
\& 10.00, ==size:pricing
.Ve
With this value in the price field, a base price of 10.00 will be
adjusted with the value of the \fIsize\fR attribute. If size for the item
99\-102 is set to \s-1XL\s0 then 1.00 will be added for a total price of
11.00; if it is S then .50 will be subtracted for a total price of
9.50; for any other value of \fIsize\fR no further adjustment would be
made. 00\-343 would be adjusted up 2.00 only for \fI\s-1XL\s0\fR.
.PP
.Vb 1
\& 10.00, ==size:pricing, ==color:pricing
.Ve
This is the same as above, except both size and color are adjusted
for. A color value of red for item code 99\-102 would add 0.75 to the
price. For 00\-343 it would have no effect.
.PP
.Vb 1
\& 10.00, ==size:pricing, ==color:pricing:common
.Ve
Here price is set based on a common column, keyed by the value of the
color attribute. Any item with a color value of red would have 0.75
added to the base price.
.PP
.Vb 1
\& pricing:q1,q5,q10:, ;10.00, ==size:pricing, ==color:pricing:common
.Ve
Here is a quantity price lookup, with a fallback price setting. If
there is a valid price found at the quantity of 1, 5, or 10, depending
on item quantity, then it will be used. The fallback of 10.00 only
applies if no non-zero/non-blank price was found at the quantity
lookup. In either case, size/color adjustment is applied.
.PP
.Vb 1
\& pricing:q1,q5,q10:, ;10.00 ==size:pricing, ==color:pricing:common
.Ve
Removing the comma from the end of the fallback string stops
color/size lookup if it reaches that point. If a quantity price was
found, then size and color are chained.
.PP
.Vb 1
\& pricing:q1,q5,q10:, ;products:list_price, ==size:pricing, ==color:pricing
.Ve
The value of the database column list_price is used as a fallback
instead of the fixed 10.00 value. The above value might be a nice one
to use as the default for a typical retail catalog that has items with
colors and sizes.
.Sh "PriceBreaks, discounts, and PriceAdjustment"
.IX Subsection "PriceBreaks, discounts, and PriceAdjustment"
There are several ways that Interchange can modify the price of a
product during normal catalog operation. Several of them require that
the \fIpricing.asc\fR file be present, and that you define a pricing
database. You do that by placing the following directive in
\&\fIcatalog.cfg\fR:
.PP
.Vb 1
\& Database pricing pricing.asc 1
.Ve
\&\s-1NOTE:\s0 PriceAdjustment is slightly deprecated by CommonAdjust, but will
remain in use at least through the end of Version 3 of Interchange.
.PP
Configurable directives and tags with regard to pricing:
.Ip "\(bu" 4
Quantity price breaks are configured by means of the \fIPriceBreaks\fR
and \fIMixMatch\fR directives. They require a field named specifically
price in the pricing database. The \fBprice\fR field contains a
space-separated list of prices that correspond to the quantity levels
defined in the \fIPriceBreaks\fR directive. If quantity is to be applied
to all items in the shopping cart (as opposed to quantity of just that
item) then the \fIMixMatch\fR directive should be set to \fBYes\fR.
.Ip "\(bu" 4
Individual line-item prices can be adjusted according to the value of
their attributes. See \fIPriceAdjustment\fR and \fICommonAdjust\fR. The
pricing database \fBmust\fR be defined unless you define the
\&\fICommonAdjust\fR behavior.
.Ip "\(bu" 4
Product discounts for individual products, specific product codes, all
products, or the entire order can be configured with the [discount
\&...] tag. Discounts are applied on a per-user basis \*(-- you can gate
the discount based on membership in a club or other arbitrary means.
See \fIProduct Discounts\fR.
.PP
For example, if you decided to adjust the price of T-shirt part number
99\-102 up 1.00 when the size is extra large and down 1.00 when the
size is small, you would have the following directives defined in
:
.PP
.Vb 3
\& Database pricing pricing.asc 1
\& UseModifier size
\& PriceAdjustment size
.Ve
To enable automatic modifier handling, you define a size field in
products.txt:
.PP
.Vb 2
\& code description price size
\& 99-102 T-Shirt 10.00 S=Small, M=Medium, L=Large*, XL=Extra Large
.Ve
You would place the proper tag within your [item-list] on the
shopping-basket or order page:
.PP
.Vb 1
\& [item-accessories size]
.Ve
In the pricing.asc database source, you would need:
.PP
.Vb 2
\& code S XL
\& 99-102 -1.00 1.00
.Ve
If you want to assign a price based on the option, precede the number
with an equals sign:
.PP
.Vb 2
\& code S M L XL
\& 99-102 =9.00 =10 =10 =11
.Ve
\&\s-1IMPORTANT\s0 \s-1NOTE:\s0 Price adjustments occur \s-1AFTER\s0 quantity price breaks,
so the above would negate anything set with the \fIPriceBreaks\fR
directive/option.
.PP
Numbers that begin with an equals sign (=) are used as absolute
prices and are \fIinterpolated for Interchange tags first\fR, so you can
use subroutines to set the price. To facilitate coordination with the
subroutine, the session variables item_code and item_quantity
are set to the code and quantity of the item being evaluated. They
would be accessed in a global subroutine with
\&\f(CW$Vend::Session\fR->{item_code} and
\&\f(CW$Vend::Session\fR->{item_quantity}.
.PP
The pricing information must always come from a database because of
security.
.Sh "Item Attributes"
.IX Subsection "Item Attributes"
Interchange allows item attributes to be set for each ordered item.
This allows a size, color, or other modifier to be attached to a
common part number. If multiple attributes are set, then they should
be separated by commas. Previous attribute values can be saved by
means of a hidden field on a form, and multiple attributes for each
item can be \fIstacked\fR on top of each other.
.PP
The configuration file directive \fIUseModifier\fR is used to set the
name of the modifier or modifiers. For example
.PP
.Vb 1
\& UseModifier size,color
.Ve
will attach both a size and color attribute to each item code that is
ordered.
.PP
\&\fB\s-1IMPORTANT\s0 \s-1NOTE:\s0\fR You may not use the following names for attributes:
.PP
.Vb 1
\& item group quantity code mv_ib mv_mi mv_si
.Ve
You can also set it in scratch with the mv_UseModifier scratch
variable \*(-- [set mv_UseModifier]size color[/set] has the same
effect as above. This allows multiple options to be set for products.
Whichever one is in effect at order time will be used. Be careful, you
cannot set it more than once on the same page. Setting the
mv_separate_items or global directive \fISeparateItems\fR places each
ordered item on a separate line, simplifying attribute handling. The
scratch setting for mv_separate_items has the same effect.
.PP
The modifier value is accessed in the [item-list] loop with the
[item-modifier attribute] tag, and form input fields are placed
with the [modifier-name attribute] tag. This is similar to the way
that quantity is handled, except that attributes can be \*(L"stacked\*(R" by
setting multiple values in an input form.
.PP
You cannot define a modifier name of \fIcode\fR or \fIquantity\fR, as they
are already used. You must be sure that no fields in your forms have
digits appended to their names if the variable is the same name as the
attribute name you select, as the [modifier-name size] variables
will be placed in the user session as the form variables size0, size1,
size2, etc.
.PP
You can use the [loop arg=\*(L"item item item\*(R"] list to reference
multiple display or selection fields for modifiers, or you can use the
built-in [PREFIX-accessories ...] tags available in most
Interchange list operations. The modifier value can then be used to
select data from an arbitrary database for attribute selection and
display.
.PP
Below is a fragment from a shopping basket display form which shows a
selectable size with \*(L"sticky\*(R" setting. Note that this would always be
contained within the [item_list] [/item-list] pair.
.PP
.Vb 6
\&
.Ve
It could just as easily be done with a radio button group combined
with the [checked ...] tag.
.PP
Interchange will automatically generate the above select box when the
[accessories size] or [item-accessories size] tags are
called. They have the syntax:
.PP
.Vb 1
\& [item_accessories attribute*, type*, field*, database*, name*, outboard*]
.Ve
.Vb 1
\& [accessories code attribute*, type*, field*, database*, name*, outboard*]
.Ve
.Ip "code" 4
.IX Item "code"
Not needed for item-accessories, this is the product code of the item
to reference.
.Ip "attribute" 4
.IX Item "attribute"
The item attribute as specified in the UseModifier configuration
directive. Typical are size or color.
.Ip "type" 4
.IX Item "type"
The action to be taken. One of:
.Sp
.Vb 2
\& select Builds a dropdown