1 # Copyright 2002-2007 Interchange Development Group and others
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version. See the LICENSE file for details.
8 # $Id: weight.tag,v 1.9 2007-07-18 00:16:26 jon Exp $
10 UserTag weight Order attribute
11 UserTag weight addAttr
12 UserTag weight Version $Revision: 1.9 $
13 UserTag weight Routine <<EOR
15 my ($attr, $opt) = @_;
20 $cart = $Vend::Session->{carts}{$opt->{cart}} || [];
28 my $field = $opt->{field} || 'weight';
29 my $table = $opt->{table};
34 my $oattr = $Vend::Cfg->{OptionsAttribute}
36 my $odb = dbref($opt->{options_table} || 'options')
38 my $otab = $odb->name();
40 SELECT o_group, weight FROM $otab
42 AND weight is not null
45 my $sth = $odb->dbh()->prepare($q)
51 if($it->{$oattr} eq 'Simple') {
52 $sth->execute($it->{code});
53 while(my $ref = $sth->fetchrow_arrayref) {
54 my ($opt, $wtext) = @$ref;
55 next unless length($it->{$opt});
56 my $whash = get_option_hash($wtext);
58 $oweight += $whash->{$it->{$opt}};
69 if(my $thing = $opt->{exclude_attribute}) {
71 if(ref($thing) eq 'HASH') {
73 $exclude{$_} = qr{$thing->{$_}};
77 my ($k, $v) = split /=/, $thing;
78 $exclude{$k} = qr{$v};
82 ::logError("Bad weight exclude option: %s", ::uneval($thing));
91 if(my $thing = $opt->{zero_unless_attribute}) {
93 if(ref($thing) eq 'HASH') {
95 $zero_unless{$_} = qr{$thing->{$_}};
99 my ($k, $v) = split /=/, $thing;
100 $zero_unless{$k} = qr{$v};
104 ::logError("Bad weight zero_unless option: %s", ::uneval($thing));
112 $attr = $opt->{field} || 'weight';
114 return shift(@_)->{$attr};
117 elsif($opt->{fill_attribute}) {
118 $attr = $opt->{fill_attribute};
121 return $it->{$attr} if defined $it->{$attr};
122 my $tab = $table || $it->{mv_ib} || $Vend::Cfg->{ProductFiles}[0];
123 $it->{$attr} = tag_data($tab,$field,$it->{code}) || 0;
124 if($opt->{matrix} and ! $it->{$attr} and $it->{mv_sku}) {
125 $it->{$attr} = Vend::Data::product_field($field,$it->{mv_sku});
133 my $tab = $table || $it->{mv_ib} || $Vend::Cfg->{ProductFiles}[0];
134 my $w = tag_data($tab,$field,$it->{code}) || 0;
135 if(! $w and $opt->{matrix} and $it->{mv_sku}) {
136 $w = Vend::Data::product_field($field,$it->{mv_sku});
147 for my $k (keys %exclude) {
148 $found = 1, last if $_->{$k} =~ $exclude{$k};
153 for my $k (keys %zero_unless) {
154 return 0 unless $_->{$k} =~ $zero_unless{$k};
157 next if $_->{mv_free_shipping} && ! $opt->{no_free_shipping};
158 $total += $_->{quantity} * $wsub->($_);
160 $total += $_->{quantity} * $osub->($_);
163 unless($opt->{no_set}) {
164 $::Scratch->{$opt->{weight_scratch} ||= 'total_weight'} = $total;
167 return $total unless $opt->{hide};
172 UserTag weight Documentation <<EOD
175 ITL tag [weight] -- calculate shipping weight from cart
184 fill-attribute=weight*
185 zero-unless-attribute="attribute=regex"
186 exclude-attribute="attribute=regex"
191 weight-scratch=sh_weight*
196 Calculates total weight of items in shopping cart, by default setting
197 a scratch variable (default "total_weight").
205 If set, weight tag will calculate from the field in the item itself instead
206 of going to the database. This is the most efficient, and can be enabled
207 by using this in catalog.cfg:
211 The default is not set, using the database every time.
215 The cart to calculate for. Defaults to current cart.
219 The fieldname to use -- default "weight". This applies both to attribute
222 =item exclude-attribute
224 If an attribute I<already in the cart hash> matches the regex, it
225 will not show up as weight. Can be a scalar or hash.
227 [weight exclude-attribute="prod_group=Gift Certificates"]
231 [weight exclude-attribute.prod_group="Gift Certificates"]
233 are identical, but with the second form you can do:
236 exclude-attribute.prod_group="Gift Certificates"
237 exclude-attribute.category="Downloads"
240 The value is a regular expression, so you can group with C<|>,
241 or make case insensitive with:
243 [weight exclude-attribute.prod_group="(?i)certificate"]
245 If the regular expression does not compile, an error is logged
246 and no exclusion is done.
248 It is IMPORTANT to note that you must have the attribute pre-filled
249 for this to work -- no database accesses will be done. If you want
250 to do this, use L<AutoModifier>, i.e. put in catalog.cfg:
252 AutoModifier prod_group
256 Sets the attribute from the database the first time, and uses it thereafter.
257 Sets to weight of a single unit, of course.
261 Don't display the weight, only set in Scratch. It makes no sense to
262 use hide=1 and no-set=1.
266 If set, will get the weight from the ProductFiles for the mv_sku
267 attribute of the item. In other words, if the weight for a variant
268 is not set, it will use the weight for the base SKU.
272 Don't set the weight in scratch.
276 Scan the options table for applicable options and adjust weight
277 accordingly. Only works for "Simple" type options set in the
278 OptionsEnable attribute, and the o_group and weight fields must
279 represent the option attribute and the weight text. The weight text is a
280 normal Interchange option hash string type, i.e.
282 titanium=-1.2, iron=1.5
284 where "titanium" and "iron" are the values of an option
285 setting like "blade".
287 Will only work if your options table is SQL/DBI.
291 Specify a table to use to look up weights. Defaults to the table the
292 product was ordered from (or the first ProductFiles).
296 The scratch variable name to set -- default is "total_weight".
298 =item zero-unless-attribute
300 Same as C<exclude-attribute> except that a zero weight is returned
301 unless B<all> items match the expression. This allows you to do
302 something like only offer Book Rate shipping when all items have
303 a prod_group of "Books".