Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
261 lines (230 sloc) 6.2 KB
# Vend::Options - Interchange item options base module
#
# Copyright (C) 2002-2007 Interchange Development Group
# Copyright (C) 1996-2002 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301 USA.
package Vend::Options;
require Exporter;
$VERSION = '2.8';
@ISA = qw(Exporter);
@EXPORT = qw(
find_joiner
find_options_type
find_sort
inventory_function
option_cost
remap_option_record
);
use Vend::Util;
use Vend::Data;
use Vend::Interpolate;
use strict;
sub remap_option_record {
my ($record, $map) = @_;
my %rec;
my @del;
my ($k, $v);
while (($k, $v) = each %$map) {
next unless defined $record->{$v};
$rec{$k} = $record->{$v};
push @del, $v;
}
delete @{$record}{@del};
@{$record}{keys %rec} = (values %rec);
return;
}
sub find_options_type {
my ($item, $opt) = @_;
my $attrib;
return $item->{$attrib}
if $attrib = $Vend::Cfg->{OptionsAttribute}
and defined $item->{$attrib};
my $sku = $item->{mv_sku} || $item->{code};
return unless defined $sku && $sku ne '';
$opt = get_option_hash($opt);
my $module;
if($Vend::Cfg->{OptionsEnable}) {
my ($tab, $field) = split /:+/, $Vend::Cfg->{OptionsEnable};
if(! $field) {
$field = $tab;
undef $tab;
}
elsif($tab =~ /=/) {
my $att;
($att, $tab) = split /\s*=\s*/, $tab;
$attrib ||= $att;
}
$attrib ||= $field;
$Vend::Cfg->{OptionsAttribute} ||= $attrib;
if(! defined $item->{$attrib}) {
$tab = $item->{mv_ib} || product_code_exists_tag($sku)
or do {
logOnce('error', "options: Unknown product %s.", $sku);
return;
};
$item->{$attrib} = tag_data($tab, $field, $sku);
}
$module = $item->{$attrib} || '';
}
else {
## Old style options
my $loc = $Vend::Cfg->{Options_repository}{Old48} || {};
my $table = $opt->{table}
||= (
$loc->{table} || $::Variable->{MV_OPTION_TABLE} || 'options'
);
my $db = $Vend::Interpolate::Db{$table} || database_exists_ref($table)
or return;
$db->record_exists($sku)
or return;
my $record = $opt->{options_record} = $db->row_hash($sku)
or return;
$opt->{options_db} = $db;
remap_option_record($record, $loc->{map})
if $loc->{remap};
return '' unless $record->{o_enable};
$module = 'Old48';
if($record->{o_matrix}) {
$opt->{display_routine}
= 'Vend::Options::Old48::display_options_matrix';
}
elsif($record->{o_modular}) {
$module = 'Modular';
}
else {
$opt->{display_routine}
= 'Vend::Options::Old48::display_options_simple';
}
}
return $module;
}
sub inventory_function {
my $opt = shift;
return unless $opt->{inventory};
my $inv_func;
my ($t, $c) = split /[.:]+/, $opt->{inventory};
my $idb;
if($idb = database_exists_ref($t)) {
$inv_func = $idb->field_accessor($c);
}
return $inv_func;
}
sub find_joiner {
my $opt = shift;
if($opt->{report}) {
$opt->{joiner} ||= ', ';
$opt->{separator} ||= ': ';
$opt->{type} ||= 'display';
}
else {
$opt->{joiner} ||= "<br$Vend::Xtrailer>";
}
return;
}
sub find_sort {
my $opt = shift;
my $db = shift;
my $loc = shift || $Vend::Cfg->{Options_repository}{$opt->{options_type}} || {};
#::logDebug("called find_sort from " . scalar(caller()) . ", opt=" . ::uneval($opt));
$opt->{sort} = defined $opt->{sort} ? $opt->{sort} : $loc->{sort};
return '' unless $opt->{sort};
return " ORDER BY $opt->{sort}" if $opt->{rawsort} || $loc->{rawsort};
my @fields = split /\s*,\s*/, $opt->{sort};
my $map = $loc->{map} ||= {};
for(@fields) {
my $extra;
$extra = ' DESC' if s/\s+(r(?:ev(?:erse)?)?|desc(?:ending)?)//i;
$_ = $map->{$_} || $_;
unless (defined $db->test_column($_)) {
logOnce(
"%s options sort field %s does not exist, returning unsorted",
'Matrix',
$_,
);
return undef;
}
$_ .= $extra if $extra;
}
return " ORDER BY " . join(",", @fields);
}
sub tag_options {
my ($sku, $opt) = @_;
my $item;
if(ref $sku) {
$item = $sku;
$sku = $item->{mv_sku} || $item->{code};
}
$item ||= { code => $sku };
$opt = get_option_hash($opt);
find_joiner($opt);
my $module = find_options_type($item, $opt)
or return '';
$opt->{options_type} = $module;
#::logDebug("tag_options module=$module");
my $loc = $Vend::Cfg->{Options_repository}{$module} || {};
no strict 'refs';
my $routine;
if($opt->{admin_page}) {
$opt->{routine_description} ||= "admin page";
$routine = $opt->{admin_page_routine}
||= "Vend::Options::${module}::admin_page";
}
else {
$opt->{routine_description} ||= "display";
$routine = $opt->{display_routine};
$routine ||= $loc->{display_routine}
||= "Vend::Options::${module}::display_options";
#::logDebug("tag_options display routine=$routine");
}
my $sub = \&{"$routine"};
if(! defined $sub) {
::logOnce(
"Options type %s %s routine %s not found, aborting options for %s.",
$module,
$opt->{routine_description},
$routine,
$sku,
);
return undef;
}
#::logDebug("main tag_options item=" . ::uneval($item) . ", opt=" . ::uneval($opt));
return $sub->($item, $opt, $loc);
}
sub option_cost {
my ($item, $table, $final) = @_;
my $module = find_options_type($item)
or return undef;
#::logDebug("price_options module=$module");
my $loc = $Vend::Cfg->{Options_repository}{$module} || {};
return undef if $loc->{no_pricing};
no strict 'refs';
my $routine = $loc->{price_routine};
$routine ||= "Vend::Options::${module}::price_options";
my $sub = \&{"$routine"};
#::logDebug("price_options sub=$sub");
if(! defined $sub) {
::logOnce(
"Options type %s not found, aborting option_cost for %s.",
$module,
$item->{code},
);
return undef;
}
return $sub->($item, $table, $final, $loc);
}
1;
__END__
You can’t perform that action at this time.