1 # Vend::Options::Old48 - Interchange 4.8 compatible product options
3 # $Id: Old48.pm,v 1.14 2007-08-09 13:40:55 pajamian Exp $
5 # Copyright (C) 2002-2007 Interchange Development Group <interchange@icdevgroup.org>
6 # Copyright (C) 2002-2003 Mike Heins <mikeh@perusion.net>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public
19 # License along with this program; if not, write to the Free
20 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
24 package Vend::Options::Old48;
26 $VERSION = substr(q$Revision: 1.14 $, 10);
30 Vend::Options::Old48 - Interchange Compatibility Options Support
46 The Vend::Options::Old48 module implements simple and matrix product
47 options for Interchange. It is compatible with Interchange 4.8.x
48 matrix options. Newer versions use Simple and Matrix options instead.
50 If the Interchange Variable MV_OPTION_TABLE is not set, it defaults
51 to "options", which combines options for Simple, Matrix, and
52 Modular into that one table. This goes along with foundation and
53 construct demos up until Interchange 4.9.8.
55 The "options" table remains the default for matrix options.
59 Mike Heins <mikeh@perusion.net>
63 Jon Jensen <jon@swelter.net>
69 use Vend::Interpolate;
73 my ($item, $opt) = @_;
77 sub display_options_matrix {
78 my ($item, $opt, $loc) = @_;
80 $loc ||= $Vend::Cfg->{Options_repository}{Old48} || \%Default;
81 #::logDebug("Matrix options by module, old");
82 my $sku = $item->{mv_sku} || $item->{code};
86 if(not $db = $opt->{options_db}) {
87 $tab = $opt->{table} || $::Variable->{MV_OPTION_TABLE} || 'options';
88 $db = database_exists_ref($tab)
91 "Matrix options: unable to find table %s for item %s",
100 if(not $record = $opt->{options_record}) {
101 $db->record_exists($sku)
104 "Matrix options: unable to find record in table %s for item %s",
110 $record = $db->row_hash($sku) || {};
113 my $tname = $db->name();
115 if(not $opt->{display_type} ||= $record->{display_type}) {
116 $opt->{display_type} = $record->{o_matrix} == 2 ? 'separate' : 'single';
119 $opt->{display_type} = lc $opt->{display_type};
122 if(not $map = $opt->{options_map}) {
123 $map = $opt->{options_map} = {};
124 if(my $remap = $opt->{remap} || $::Variable->{MV_OPTION_TABLE_MAP}) {
125 remap_option_record($record, $map, $remap);
134 if($opt->{inventory}) {
135 my ($tab, $col) = split /:+/, $opt->{inventory};
137 my $idb = dbref($tab)
139 logError("Bad table %s for inventory function.", $tab);
142 $idb->test_column($col)
145 "Bad column %s in table %s for inventory function.",
153 return $idb->field($key, $col);
158 my $rsort = find_sort($opt, $db, $loc);
160 if($opt->{display_type} eq 'separate') {
161 for(qw/code o_enable o_group o_value o_label o_widget price/) {
162 push @rf, ($map->{$_} || $_);
165 if($item and $item->{code}) {
166 @def = split /-/, $item->{code};
168 my $fsel = $map->{sku} || 'sku';
169 my $rsel = $db->quote($sku, $fsel);
173 " FROM $tname where $fsel = $rsel $rsort";
174 #::logDebug("tag_options matrix query: $q");
175 my $ary = $db->query($q);
176 #::logDebug("tag_options matrix ary: " . ::uneval($ary));
179 my $phony = { %{$item || { }} };
180 foreach $ref (@$ary) {
182 next unless $ref->[3];
184 # skip based on inventory if enabled
186 my $oh = $inv_func->($ref->[0]);
192 # skip unless o_value
193 $phony->{mv_sku} = $def[$i];
196 $ref->[4] = "<b>$ref->[4]</b>" if $opt->{bold};
197 push @out, $ref->[4];
199 push @out, Vend::Interpolate::tag_accessories(
204 type => $opt->{type} || $ref->[5] || 'select',
205 attribute => 'mv_sku',
206 price_data => $ref->[6],
207 price => $opt->{price},
208 extra => $opt->{extra},
216 $phony->{mv_sku} = $sku;
217 my $begin = Vend::Interpolate::tag_accessories(
222 attribute => 'mv_sku',
230 $out .= "<td>$begin$_</td>";
235 $opt->{joiner} = "<br$Vend::Xtrailer>" if ! $opt->{joiner};
237 $out .= join $opt->{joiner}, @out;
241 for(qw/code o_enable o_group description price weight volume differential o_widget/) {
242 push @rf, ($map->{$_} || $_);
244 my $ccol = $map->{code} || 'code';
245 my $lcol = $map->{sku} || 'sku';
246 my $lval = $db->quote($sku, $lcol);
248 my $q = "SELECT " . join(",", @rf);
249 $q .= " FROM $tname where $lcol = $lval AND $ccol <> $lval $rsort";
250 #::logDebug("tag_options matrix query: $q");
251 my $ary = $db->query($q);
252 #::logDebug("tag_options matrix ary: " . ::uneval($ary));
255 foreach $ref (@$ary) {
256 # skip unless description
257 next unless $ref->[3];
259 # skip based on inventory if enabled
261 my $oh = $inv_func->($ref->[0]);
265 $ref->[3] =~ s/,/,/g;
266 $ref->[3] =~ s/=/=/g;
267 $price->{$ref->[0]} = $ref->[4];
268 push @out, "$ref->[0]=$ref->[3]";
270 $out .= "<td>" if $opt->{td};
271 $out .= Vend::Interpolate::tag_accessories(
277 extra => $opt->{extra},
281 passed => join(",", @out),
282 price => $opt->{price},
283 price_data => $price,
284 type => $opt->{type} || $ref->[8] || 'select',
288 $out .= "</td>" if $opt->{td};
289 #::logDebug("matrix option returning $out");
296 my ($item, $table, $final, $loc) = @_;
298 #::logDebug("option_cost table=$table");
299 $loc ||= $Vend::Cfg->{Options_repository}{Old48} || {};
301 my $sku = $item->{mv_sku} || $item->{code};
302 my $db = database_exists_ref($table)
304 #::logDebug("option_cost db=$db");
306 my $map = $loc->{map} || {};
307 my $fsel = $map->{sku} || 'sku';
308 my $rsel = $db->quote($sku, $fsel);
310 for(qw/o_group price/) {
311 push @rf, ($map->{$_} || $_);
314 my $q = "SELECT " . join (",", @rf) . " FROM $table WHERE $fsel = $rsel";
315 #::logDebug("option_cost query=$q");
316 my $ary = $db->query($q);
317 return if ! $ary->[0];
322 foreach $ref (@$ary) {
323 #::logDebug("checking option " . uneval_it($ref));
324 next unless defined $item->{$ref->[0]};
325 $ref->[1] =~ s/^\s+//;
326 $ref->[1] =~ s/\s+$//;
327 $ref->[1] =~ s/==/=:/g;
328 my %info = split /\s*[=,]\s*/, $ref->[1];
329 if(defined $info{ $item->{$ref->[0]} } ) {
330 my $atom = $info{ $item->{$ref->[0]} };
331 if($atom =~ s/^://) {
335 elsif ($atom =~ s/\%$//) {
336 $f = $final if ! defined $f;
337 $f += ($atom * $final / 100);
344 #::logDebug("option_cost returning price=$price f=$f");
348 sub display_options_simple {
349 my ($item, $opt) = @_;
350 #::logDebug("Simple options, item=" . ::uneval($item) . "\nopt=" . ::uneval($opt));
351 my $map = $opt->{options_map} ||= {};
352 #::logDebug("Simple options by module, old");
354 my $sku = $item->{code};
357 if(not $db = $opt->{options_db}) {
358 $tab = $opt->{table} ||= $::Variable->{MV_OPTION_TABLE_SIMPLE}
359 ||= $::Variable->{MV_OPTION_TABLE}
361 $db = database_exists_ref($tab)
364 "Simple options: unable to find table %s for item %s",
372 my $tname = $db->name();
378 my $ishash = defined $item->{mv_ip} ? 1 : 0;
380 for(qw/code o_enable o_group o_value o_label o_widget price o_height o_width/) {
381 push @rf, ($map->{$_} || $_);
384 my $fsel = $map->{sku} || 'sku';
385 my $rsel = $db->quote($sku, $fsel);
387 my $q = "SELECT " . join (",", @rf) . " FROM $tname where $fsel = $rsel";
389 if(my $rsort = find_sort($opt, $db, $loc)) {
392 #::logDebug("tag_options simple query: $q");
394 my $ary = $db->query($q)
398 foreach $ref (@$ary) {
399 # skip unless o_value
400 next unless $ref->[3];
402 $ref->[4] = "<b>$ref->[4]</b>" if $opt->{bold};
403 push @out, $ref->[4];
405 my $precursor = $opt->{report}
406 ? "$ref->[2]$opt->{separator}"
407 : qq{<input type="hidden" name="mv_item_option" value="$ref->[2]">};
408 push @out, $precursor . Vend::Interpolate::tag_accessories(
412 attribute => $ref->[2],
414 extra => $opt->{extra},
416 name => $ishash ? undef : "mv_order_$ref->[2]",
419 price => $opt->{price},
420 price_data => $ref->[6],
421 height => $opt->{height} || $ref->[7],
422 width => $opt->{width} || $ref->[8],
423 type => $opt->{type} || $ref->[5] || 'select',
430 $out .= "<td>$_</td>";
434 $opt->{joiner} = "<br$Vend::Xtrailer>" if ! $opt->{joiner};
435 $out .= join $opt->{joiner}, @out;
440 *display_options = \&display_options_simple;