[ic] mv_price and CommonAdjust

John Allman interchange-users@icdevgroup.org
Wed Oct 16 05:29:01 2002


Jim Balcom wrote:

>On Tue, 15 Oct 2002, John Allman wrote:
>
>JA>>Thanks Karen and Ed. I think i've finally got my head around
>JA>>CommonAdjust! I think i have it all working the way i want now. The only
>JA>>extra bit of advice i have for anyone else in this situation is to make
>JA>>sure that there's nothing Autoload-ed into every page that fiddles with
>JA>>your CommonAdjust or your $Config->{PriceField}.
>
>To to either confuse you, or to clear things up, here are 3 pieces that Mike
>Heins wrote in April 2001. If you have already seen these, I'm sorry for the
>duplication.
>
>------------------------------------
>
>Actually, there is more detailed documentation. I have edited this to
>reflect current reality, and offer:
>
>=head2 Chained Pricing
>
>A flexible chained pricing scheme is available when the I<CommonAdjust>
>directive is set.
>
>We talk below about a I<CommonAdjust string>; it will be defined
>in due time.
>
>NOTE: while we call the field C<common_adjust> below, usually PriceField
>is set to C<no_price> in the Interchange demos.
>
>A few rules about CommonAdjust, all assuming the I<PriceField> directive
>is set to C<common_adjust>:
>
>=over 4
>
>=item 1
>
>If C<CommonAdjust> is set to any value, a valid I<CommonAdjust string> or
>not, extended price adjustments are enabled. It may and often does hold the
>default pricing scheme.
>
>=item 2
>
>The C<common_adjust> field may also hold a I<CommonAdjust string>. It takes
>precedence over the default.
>
>=item 3
>
>If the value of the C<CommonAdjust> directive is set to a CommonAdjust
>string, and the C<common_adjust> field is empty or specifically I<0>, then it
>will be used to set the price of the items.
>
>=item 4
>
>If no CommonAdjust strings are found, then the price will be 0, subject
>to any later application of discounts.
>
>=item 5
>
>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.
>
>=back
>
>Prices may be adjusted in several ways, and the individual actions
>are referred to below as I<atoms>.  Price atoms they may be I<final>,
>I<chained>, or I<fallback>. 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.
>
>Atoms are separated by whitespace, and may be quoted (although there
>should not normally be whitespace in a setting unless it is ITL or Perl
>code). 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.
>
>A I<settor> is the means by which the price is set. There
>are several different types of price settors. All non-literal
>settors can then yield another CommonAdjust string.
>
>It is quite possible to create endless loops, so the maximum number of
>initial CommonAdjust strings is set to a sufficiently high number to
>prevent this; there are also limited iterations before the price will
>return zero on an error. NOTE: Interchange 4.7.x and higher allow setting
>of this with the Limit directive.
>
>B<NOTE>:  Common needs are easily shown but not so easily explained;
>skip to the examples if the reference below if your vision starts to
>blur when reading the next section. 8-)
>
>USAGE: Optional items below have asterisks appended. The asterisk should
>not be used in the actual string. Optional B<base> or B<table> always
>defaults to the active C<products> database table.  The optional B<key>
>defaults to the item code except in a special case for the attribute-based
>lookup. The B<field> name is not optional except in the case of an
>attribute lookup.
>
>=over 4
>
>=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.
>
>=item N.NN%
>
>where N is a digit.  A number which is applied as a percentage of
>the I<current> 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.
>
>=item table*:column:key*
>
>Causes a straight lookup in a database table. The optional B<table>
>defaults to the main products database table for the item (subject
>of course to multiple product files). The B<column> must always
>be present. The optional B<key> 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.
>
>=item table*:col1..col5,col10:key*
>
>Causes a quantity lookup in database table B<table> (which defaults to
>the products database), with a set of comma-separated fields, looked
>up by the optional B<key>. (Key defaults to the item code, of course).
>If ranges are specified with .., each column in the sequence will be used;
>Therefore
>
>    pricing:p1,p2,p3,p4,p5,p10:
>
>is the same as
>
>    pricing:p1..p5,p10:
>
>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.
>
>WARNING: 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.
>
>=item table*:price_group,col1..col5,col10:key*
>
>Causes a mix-and-match quantity lookup in database table B<table>
>(which defaults to the products database), with a set of comma-separated
>fields, looked up by the optional B<key>. The lookup is grouped
>by the attribute C<group>. The group field must not end in a digit,
>as that is how it is distinguished from a quantity.
>
>The quantity handling is as in the straight quantity lookup.
>
>The item attribute must be preloaded in the item to effect the
>lookup -- this is usually done with an AutoModifier setting
>in L<catalog.cfg>:
>
>    AutoModifier   pricing:price_group
>
>See L<AutoModifier> for more information on that.
>
>Price group values must contain at least one non-digit character, i.e.
>not all digits. "Autos" is a valid price group -- "2" is not.
>
>The effect of the grouping is for the quantity of all items with the
>same price group to be added together for the purpose of quantity
>discounts.
>
>If you have the SKUS:
>
>    sku    price_group   q5      q10
>    S102   shirts        11.95   9.95
>    S103   shirts        11.95   9.95
>    P102   pants         22.95   19.95
>
>Ordering two S102 and three S103 will cause the item price to be 11.95
>per item. Ordering 5 of each will drop the price of each to 9.95.
>Ordering 20 of P102, which is in group C<pants>, will have no effect on
>the quantity price of either item in group C<shirts>.
>
>WARNING: 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.
>
>=item ==attribute:table*:column*:key*
>
>Does an attribute-based adjustment. The attribute is looked up in the
>database B<table>, with the optional B<column> defaulting to the same
>name as the I<value> of the B<attribute>. If the column is not left blank,
>the I<key> is set to the I<value> of the B<attribute> if blank.
>
>4.7.x and higher: if there is only ==attribute, with no C<colon>
>calling a database table and field, then the special C<options>
>table will be used for price lookups. See (when it exists)
>L<Automated Option Handling>.
>
>=item & CODE
>
>The leading C<&> sign is stripped and the code is passed to the
>equivalent of a C<[calc]> tag. No Interchange tags can be used (i.e. no
>tag interpolation), but the full range of $Tag and other embedded Perl
>objects is available.  The current (or interim) value of the price
>chaining is available as C<$s>, and C<$q>; the current item hash is are
>available as C<$item>.  This means:
>
>  $item->{code}  gives key for current item
>  $item->{size}  gives size for current item (if there)
>  $item->{mv_ib} gives database ordered from
>  $s is the prospective item price (not settable).
>
>=item [valid minivend tags]
>
>If the settor begins with a square bracket (C<[>) or underscore, it
>is parsed for Interchange tags with variable substitution (but no Locale
>substitution). You may define a price in a I<Variable> in this fashion.
>The string is re-submitted as an atom, so it may yield yet another
>settor.
>
>IMPORTANT NOTE: You must use quotes to surround the tags if they have
>any whitespace, and any embedded quotes must be backslashed.
>
>=item $
>
>Tells Interchange to look in the C<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.
>
>=item >>word
>
>Tells the routine to return C<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.
>
>=item word
>
>The value of C<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 (C<$>) the C<word>
>will be substituted; i.e. C<table:column:$> becomes C<table:column:word>.
>
>=item ( settor )
>
>The value returned by C<settor> will be used as a key for the next
>lookup, as above.
>
>=back
>
>=head2 CommonAdjust Examples
>
>There are several examples of CommonAdjust setups in the L<Foundation>
>demo, and they fit many requirements without change.
>
>Most examples below use an outboard database table named B<pricing>, but
>any valid table including the B<products> table can be used. We will refer
>to this B<pricing> table:
>
>  code    common  q1     q5     q10    XL    S      red
>  99-102          10     9      8      1     -0.50  0.75
>  00-343                               2
>  red      0.75
>
>=over 4
>
>=item *
>
>  pricing:q1,q5,q10:, ;10.00
>
>This 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.
>
>=item *
>
>You can do lookups on a product attribute; I<size> in this case.
>
>  10.00, ==size:pricing
>
>With this value in the C<common_adjust> field, a base price of 10.00 will be
>adjusted with the value of the I<size> attribute. If size for the item
>99-102 is set to C<XL> then 1.00 will be added for a total price of 11.00;
>if it is C<S> then .50 will be subtracted for a total price of 9.50;
>for any other value of I<size> no further adjustment would be made. 00-343
>would be adjusted up 2.00 only for I<XL>.
>
>  10.00, ==size:pricing, ==color:pricing
>
>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.
>
>  10.00, ==size:pricing, ==color:pricing:common
>
>
>=item *
>
>  pricing:q1,q5,q10:, ;10.00, ==size:pricing, ==color:pricing:common
>
>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.
>
>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.
>
>=item *
>
>  pricing:q1,q5,q10:, ;products:list_price, ==size:pricing, ==color:pricing
>
>The value of the database column C<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.
>
>=back
>
>----------------------------------
>
>A little known fact about CommonAdjust is that you don't have to have
>them all be one, you can maintain multiple ones. Say you have as your
>default:
>
>    PriceField   common_adjust
>    CommonAdjust  pricing:q12,q24,q48,q96: ;:price
>
>    pricing.txt:
>    sku	q12	q24	q48	q96
>    AP-S		0.75	0.50
>
>    products.txt slice:
>    sku	price	common_adjust
>    AP-S	1.00
>
>If item AP-S has nothing in the field common_adjust, it uses the above.
>If another item needs different and custom breaks:
>
>    # Same as above, repeated
>    PriceField   common_adjust
>    CommonAdjust  pricing:q12,q24,q48,q96: ;:price
>
>    price_special.txt:
>    sku	q18	q36	q72
>    OR-S	0.90	0.75	0.50
>
>    products.txt slice:
>    sku	price	common_adjust
>    OR-S	1.00	price_special:q18,q36,q72 ;:price
>
>Now OR-S uses the CommonAdjust string from the database and ignores
>the default one.
>
>---------------------------------
>
>The normal way to do this would be to have your pricing table with fields
>corresponding to the quantities.
>The problem with your pricing structure is that the price breaks are not
>consistent.
>
>pricing table:
>sku	q12	q15	q16	q18	q20	q24	q48	q72	q75	q80	q96
>AP-S				0.75				0.50
>AP-M						1.25					1
>etc...
>
>PriceField	nonexistant_field
>CommonAdjust   pricing:q12,q15,q16,q18,q20,q48,q72,q75,q80,q96: ;:price
>
>This commonadjust setting says (starting at the right)
> get the price from the price field in the products table.
> if there is one, replace it with the price from the pricing table field
>which corresponds (<=) to the qty specified in the tag, or in the basket.
>
>
>
>
>-= Jim =-
>
>                   .-.
>                   /v\
>                  // \\
>                 /(   )\
>                 ^^ - ^^
>          > Phear the Penguin <
>              L  I  N  U  X
>
>----------------------------------------------------------------
>Jim's Linux-Operated Underground Bomb Shelter
>
>Tagline for Tuesday, October 15, 2002 at 17:50 PM:
>Interchangeable parts won't.
>
>----------------------------------------------------------------
>This Linux System has been up 47 hours
>
>My web page: http://www.idk-enterprises.com
>----------------------------------------------------------------
>
>_______________________________________________
>interchange-users mailing list
>interchange-users@icdevgroup.org
>http://www.icdevgroup.org/mailman/listinfo/interchange-users
>  
>
Thanks - that should be helpful to anyone else in my position. The first 
piece of documentation that you posted is now integrated in ic_ecommerce 
in the latest documentation at interchange.rtfm.org (i think - if i'm 
wrong please correct).

thanks

John