1 # Vend::Options - Interchange item options base module
3 # $Id: Options.pm,v 2.8 2007-08-09 13:40:53 pajamian Exp $
5 # Copyright (C) 2002-2007 Interchange Development Group
6 # Copyright (C) 1996-2002 Red Hat, Inc.
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,
23 package Vend::Options;
26 $VERSION = substr(q$Revision: 2.8 $, 10);
41 use Vend::Interpolate;
44 sub remap_option_record {
45 my ($record, $map) = @_;
50 while (($k, $v) = each %$map) {
51 next unless defined $record->{$v};
52 $rec{$k} = $record->{$v};
55 delete @{$record}{@del};
56 @{$record}{keys %rec} = (values %rec);
61 sub find_options_type {
62 my ($item, $opt) = @_;
65 return $item->{$attrib}
66 if $attrib = $Vend::Cfg->{OptionsAttribute}
67 and defined $item->{$attrib};
69 my $sku = $item->{mv_sku} || $item->{code};
71 $opt = get_option_hash($opt);
75 if($Vend::Cfg->{OptionsEnable}) {
76 my ($tab, $field) = split /:+/, $Vend::Cfg->{OptionsEnable};
83 ($att, $tab) = split /\s*=\s*/, $tab;
87 $Vend::Cfg->{OptionsAttribute} ||= $attrib;
89 if(! defined $item->{$attrib}) {
90 $tab = $item->{mv_ib} || product_code_exists_tag($sku)
92 logOnce('error', "options: Unknown product %s.", $sku);
95 $item->{$attrib} = tag_data($tab, $field, $sku);
97 $module = $item->{$attrib} || '';
101 my $loc = $Vend::Cfg->{Options_repository}{Old48} || {};
102 my $table = $opt->{table}
104 $loc->{table} || $::Variable->{MV_OPTION_TABLE} || 'options'
106 my $db = $Vend::Interpolate::Db{$table} || database_exists_ref($table)
108 $db->record_exists($sku)
110 my $record = $opt->{options_record} = $db->row_hash($sku)
112 $opt->{options_db} = $db;
113 remap_option_record($record, $loc->{map})
116 return '' unless $record->{o_enable};
120 if($record->{o_matrix}) {
121 $opt->{display_routine}
122 = 'Vend::Options::Old48::display_options_matrix';
124 elsif($record->{o_modular}) {
128 $opt->{display_routine}
129 = 'Vend::Options::Old48::display_options_simple';
136 sub inventory_function {
138 return unless $opt->{inventory};
140 my ($t, $c) = split /[.:]+/, $opt->{inventory};
142 if($idb = database_exists_ref($t)) {
143 $inv_func = $idb->field_accessor($c);
151 $opt->{joiner} ||= ', ';
152 $opt->{separator} ||= ': ';
153 $opt->{type} ||= 'display';
156 $opt->{joiner} ||= "<br$Vend::Xtrailer>";
164 my $loc = shift || $Vend::Cfg->{Options_repository}{$opt->{options_type}} || {};
165 #::logDebug("called find_sort from " . scalar(caller()) . ", opt=" . ::uneval($opt));
166 $opt->{sort} = defined $opt->{sort} ? $opt->{sort} : $loc->{sort};
167 return '' unless $opt->{sort};
168 return " ORDER BY $opt->{sort}" if $opt->{rawsort} || $loc->{rawsort};
169 my @fields = split /\s*,\s*/, $opt->{sort};
170 my $map = $loc->{map} ||= {};
173 $extra = ' DESC' if s/\s+(r(?:ev(?:erse)?)?|desc(?:ending)?)//i;
174 $_ = $map->{$_} || $_;
175 unless (defined $db->test_column($_)) {
177 "%s options sort field %s does not exist, returning unsorted",
183 $_ .= $extra if $extra;
186 return " ORDER BY " . join(",", @fields);
190 my ($sku, $opt) = @_;
194 $sku = $item->{mv_sku} || $item->{code};
196 $item ||= { code => $sku };
197 $opt = get_option_hash($opt);
200 my $module = find_options_type($item, $opt)
202 $opt->{options_type} = $module;
203 #::logDebug("tag_options module=$module");
205 my $loc = $Vend::Cfg->{Options_repository}{$module} || {};
208 if($opt->{admin_page}) {
209 $opt->{routine_description} ||= "admin page";
210 $routine = $opt->{admin_page_routine}
211 ||= "Vend::Options::${module}::admin_page";
214 $opt->{routine_description} ||= "display";
215 $routine = $opt->{display_routine};
216 $routine ||= $loc->{display_routine}
217 ||= "Vend::Options::${module}::display_options";
218 #::logDebug("tag_options display routine=$routine");
220 my $sub = \&{"$routine"};
223 "Options type %s %s routine %s not found, aborting options for %s.",
225 $opt->{routine_description},
231 #::logDebug("main tag_options item=" . ::uneval($item) . ", opt=" . ::uneval($opt));
232 return $sub->($item, $opt, $loc);
236 my ($item, $table, $final) = @_;
238 my $module = find_options_type($item)
240 #::logDebug("price_options module=$module");
241 my $loc = $Vend::Cfg->{Options_repository}{$module} || {};
242 return undef if $loc->{no_pricing};
244 my $routine = $loc->{price_routine};
245 $routine ||= "Vend::Options::${module}::price_options";
246 my $sub = \&{"$routine"};
247 #::logDebug("price_options sub=$sub");
251 "Options type %s not found, aborting option_cost for %s.",
257 return $sub->($item, $table, $final, $loc);