Adding the productmanager

This commit is contained in:
Martin Kamerbeek 2005-04-25 22:26:30 +00:00
parent b5998af961
commit d12082f8ed
5 changed files with 1193 additions and 0 deletions

View file

@ -0,0 +1,77 @@
package WebGUI::Commerce::Item::Product;
use strict;
#use WebGUI::SQL;
use WebGUI::Product;
our @ISA = qw(WebGUI::Commerce::Item);
#-------------------------------------------------------------------
sub available {
return $_[0]->{_variant}->{available};
}
#-------------------------------------------------------------------
sub description {
return $_[0]->{_product}->get('description');
}
#-------------------------------------------------------------------
#sub duration {
#
#-------------------------------------------------------------------
#sub handler {
#}
#-------------------------------------------------------------------
sub id {
return $_[0]->{_variant}->{variantId};
}
#-------------------------------------------------------------------
sub isRecurring {
return 0;
}
#-------------------------------------------------------------------
sub name {
return $_[0]->{_product}->get('title').' ('.$_[0]->{_composition}.')';
}
#-------------------------------------------------------------------
sub new {
my ($class, $sku, $product, $variantId);
$class = shift;
$variantId = shift;
$product = WebGUI::Product->getByVariantId($variantId);
my $variant = $product->getVariant($variantId);
my %parameters = map {split(/\./, $_)} split(/,/, $variant->{composition});
my $composition = join(', ',map {$product->getParameter($_)->{name} .': '. $product->getOption($parameters{$_})->{value}} keys (%parameters));
bless {_product => $product, _composition => $composition, _variant => $variant}, $class;
}
#-------------------------------------------------------------------
sub needsShipping {
return 1;
}
#-------------------------------------------------------------------
sub price {
return $_[0]->{_variant}->{price};
}
#-------------------------------------------------------------------
sub type {
return 'Product';
}
#-------------------------------------------------------------------
sub weight {
return $_[0]->{_variant}->{weight};
}
1;

View file

@ -0,0 +1,63 @@
package WebGUI::Help::ProductManager;
our $HELP = {
'list products' => {
title => 'help list products title',
body => 'help list products body',
related => [
]
},
'manage product' => {
title => 'help manage product title',
body => 'help manage product body',
related => [
]
},
'edit product' => {
title => 'help edit product title',
body => 'help edit product body',
related => [
{
tag => 'template language',
namespace => 'Asset_Template'
},
]
},
'edit parameter' => {
title => 'help edit parameter title',
body => 'help edit parameter body',
related => [
]
},
'edit option' => {
title => 'help edit option title',
body => 'help edit option body',
related => [
]
},
'list variants' => {
title => 'help list variants title',
body => 'help list variants body',
related => [
]
},
'edit variant' => {
title => 'help edit variant title',
body => 'help edit variant body',
related => [
]
},
'edit sku template' => {
title => 'help edit sku template title',
body => 'help edit sku template body',
related => [
]
},
};
1;

View file

@ -0,0 +1,62 @@
package WebGUI::Macro::Product;
use strict;
use WebGUI::Session;
use WebGUI::Macro;
use WebGUI::Product;
use WebGUI::Asset::Template;
use WebGUI::SQL;
use WebGUI::International;
sub process {
my (@param, $productId, $variantId, $product, $variant, $output, $templateId, @variantLoop, %var);
@param = WebGUI::Macro::getParams(@_);
return 'No SKU or productId passed' unless ($_[0]);
($productId, $variantId) = WebGUI::SQL->quickArray("select productId, variantId from productVariants where sku=".quote($_[0]));
($productId) = WebGUI::SQL->quickArray("select productId from products where sku=".quote($_[0])) unless ($productId);
($productId) = WebGUI::SQL->quickArray("select productId from products where productId=".quote($_[0])) unless ($productId);
return 'Cannot find product' unless ($productId);
$product = WebGUI::Product->new($productId);
if ($variantId) {
$variant = [ $product->getVariant($variantId) ];
} else {
$variant = $product->getVariant;
};
foreach (@$variant) {
my @compositionLoop;
foreach (split(/,/,$_->{composition})) {
my ($parameterId, $optionId) = split(/\./, $_);
push(@compositionLoop, {
parameter => $product->getParameter($parameterId)->{name},
value => $product->getOption($optionId)->{value}
});
}
push (@variantLoop, {
'variant.variantId' => $_->{variantId},
'variant.price' => $_->{price},
'variant.weight' => $_->{weight},
'variant.sku' => $_->{sku},
'variant.compositionLoop' => \@compositionLoop,
'variant.addToCart.url' => WebGUI::URL::page('op=addToCart&itemType=Product&itemId='.$_->{variantId}),
'variant.addToCart.label' => WebGUI::International::get('add to cart', 'Macro_Product'),
}) if ($_->{available});
}
%var = %{$product->get};
$var{variantLoop} = \@variantLoop;
$var{'variants.message'} = WebGUI::International::get('available product configurations', 'Macro_Product');
$templateId = $_[1] || $product->get('templateId');
return WebGUI::Asset::Template->new($templateId)->process(\%var);
}
1;

View file

@ -0,0 +1,571 @@
package WebGUI::Operation::ProductManager;
use strict;
use WebGUI::Session;
use WebGUI::SQL;
use WebGUI::HTMLForm;
use WebGUI::Form;
use WebGUI::Id;
use WebGUI::International;
use WebGUI::AdminConsole;
use Tie::IxHash;
use WebGUI::Product;
use WebGUI::Icon;
use WebGUI::HTML;
use WebGUI::Privilege;
use WebGUI::Grouping;
#-------------------------------------------------------------------
sub _submenu {
my $i18n = WebGUI::International->new("ProductManager");
my $workarea = shift;
my $title = shift;
$title = $i18n->get($title) if ($title);
my $help = shift;
my $ac = WebGUI::AdminConsole->new("productManager");
if ($help) {
$ac->setHelp($help, 'ProductManager');
}
my $productId = $session{form}{productId} || WebGUI::Session::getScratch('managingProduct');
undef $productId if ($productId eq 'new');
$ac->addSubmenuItem(WebGUI::URL::page('op=editProduct&productId=new'), $i18n->get('add product'));
$ac->addSubmenuItem(WebGUI::URL::page('op=listProducts'), $i18n->get('list products'));
$ac->addSubmenuItem(WebGUI::URL::page('op=manageProduct&productId='.$productId), $i18n->get('manage product')) if ($productId);
$ac->addSubmenuItem(WebGUI::URL::page('op=listProductVariants&productId='.$productId), $i18n->get('list variants')) if ($productId);
return $ac->render($workarea, $title);
}
#-------------------------------------------------------------------
sub www_deleteProductParameterOption {
my $optionId = $session{form}{optionId};
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
WebGUI::Product->getByOptionId($optionId)->deleteOption($optionId);
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_deleteProductParameter {
my $parameterId = $session{form}{parameterId};
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
WebGUI::Product->getByParameterId($parameterId)->deleteParameter($parameterId);
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_deleteProduct {
my $productId = $session{form}{productId};
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
WebGUI::Product->new($productId)->delete;
return WebGUI::Operation::execute('listProducts');
}
#-------------------------------------------------------------------
sub www_editProduct {
my ($productId, $product, $f, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
$productId = $session{form}{productId};
unless ($productId eq 'new') {
$product = WebGUI::Product->new($productId)->get;
}
$f = WebGUI::HTMLForm->new;
$f->hidden('op', 'editProductSave');
$f->hidden('productId', $productId);
$f->text(
-name => 'title',
-label => $i18n->get('title'),
-value => $session{form}{title} || $product->{title},
-maxlength => 255,
);
$f->textarea(
-name => 'description',
-label => $i18n->get('description'),
-value => $session{form}{decsription} || $product->{description},
);
$f->float(
-name => 'price',
-label => $i18n->get('price'),
-value => $session{form}{price} || $product->{price},
-maxlength => 13,
);
$f->float(
-name => 'weight',
-label => $i18n->get('weight'),
-value => $session{form}{weight} || $product->{weight},
-maxlength => 9,
);
$f->text(
-name => 'sku',
-label => $i18n->get('sku'),
-value => $session{form}{sku} || $product->{SKU},
-maxlength => 64,
);
$f->template(
-name => 'templateId',
-label => $i18n->get('template'),
-value => $session{form}{templateId} || $product->{templateId},
-namespace => 'Commerce/Product',
);
$f->text(
-name => 'skuTemplate',
-label => $i18n->get('sku template'),
-value => $session{form}{skuTemplate} || $product->{skuTemplate},
-maxlength => 255,
);
$f->submit;
return _submenu($f->print, 'edit product', 'edit product');
}
#-------------------------------------------------------------------
sub www_editProductSave {
my ($self, @error, $productId, $product, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
push(@error, $i18n->get('edit product title error')) unless $session{form}{title};
push(@error, $i18n->get('edit product price error')) unless ($session{form}{price} && $session{form}{price} =~ /^\d+(\.\d+)?$/);
push(@error, $i18n->get('edit product weight error')) unless (defined $session{form}{weight} && $session{form}{price} =~ /^\d+(\.\d+)?$/);
push(@error, $i18n->get('edit product title error')) unless ($session{form}{sku});
return '<ul><li>'.join('</li><li>', @error).'</li></ul><br>'.WebGUI::Operation::execute('editProduct') if (@error);
$productId = $session{form}{productId};
$product = WebGUI::Product->new($productId);
$product->set({
title => $session{form}{title},
description => $session{form}{description},
price => $session{form}{price},
weight => $session{form}{weight},
sku => $session{form}{sku},
templateId => $session{form}{templateId},
skuTemplate => $session{form}{skuTemplate},
});
$session{form}{productId} = $product->get('productId');
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_editProductParameter {
my ($parameterId, $product, $productId, $parameter, $f, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
$parameterId = $session{form}{parameterId};
$productId = $session{form}{productId};
unless ($parameterId eq 'new') {
$product = WebGUI::Product->getByParameterId($parameterId);
$parameter = $product->getParameter($parameterId);
$productId = $product->get('productId');
}
$f = WebGUI::HTMLForm->new;
$f->hidden('op', 'editProductParameterSave');
$f->hidden('parameterId', $parameterId);
$f->hidden('productId', $productId);
$f->readOnly(
-label => 'parameterId',
-value => $parameterId,
);
$f->text(
-name => 'name',
-label => $i18n->get('edit parameter name'),
-value => $session{form}{name} || $parameter->{name},
-maxlength => 64,
);
$f->submit;
return _submenu($f->print, 'edit parameter', 'edit parameter');
}
#-------------------------------------------------------------------
sub www_editProductParameterSave {
my (@error, $parameterId, $product, $i18n, $skuTemplate, $oldName, $newName);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
$parameterId = $session{form}{parameterId};
push (@error, $i18n->get('edit parameter error name')) unless $session{form}{name};
push (@error, $i18n->get('edit parameter productId error')) unless $session{form}{productId};
return "<ul><li>".join('</li><li>', @error)."</li></ul>".WebGUI::Operation::execute('editProductParameter') if (@error);
$product = WebGUI::Product->new($session{form}{productId});
$skuTemplate = $product->get('skuTemplate');
if ($parameterId eq 'new') {
$parameterId = $product->addParameter;
} else {
($oldName = $product->getParameter($parameterId)->{name}) =~ s/[ ><]/\./g;
($newName = $session{form}{name}) =~ s/[ ><]/\./g;
$skuTemplate = $product->get('skuTemplate');
$skuTemplate =~ s/< *?tmpl_var *?param\.$oldName *?>/<tmpl_var param.$newName>/i;
$product->set({
skuTemplate => $skuTemplate
});
}
$product->setParameter($parameterId, {
name => $session{form}{name}
});
return WebGUI::Operation::execute('editSkuTemplate') if ($session{form}{parameterId} eq 'new');
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_editProductParameterOption {
my ($self, $optionId, $option, $f, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
$optionId = $session{form}{optionId};
unless ($optionId eq 'new') {
$option = WebGUI::Product->getByOptionId($optionId)->getOption($optionId);
}
$f = WebGUI::HTMLForm->new;
$f->hidden('op', 'editProductParameterOptionSave');
$f->hidden('optionId', $optionId);
$f->hidden('parameterId', $session{form}{parameterId});
$f->readOnly(
-label => 'optionId',
-value => $optionId
);
$f->text(
-name => 'value',
-label => $i18n->get('edit option value'),
-value => $session{form}{value} || $option->{value},
-maxlength => 64,
);
$f->float(
-name => 'priceModifier',
-label => $i18n->get('edit option price modifier'),
-value => $session{form}{priceModifier} || $option->{priceModifier},
-maxlength => 11,
);
$f->float(
-name => 'weightModifier',
-label => $i18n->get('edit option weight modifier'),
-value => $session{form}{weightModifier} || $option->{weightModifier},
-maxlength => 7,
);
$f->text(
-name => 'skuModifier',
-label => $i18n->get('edit option sku modifier'),
-value => $session{form}{skuModifier} || $option->{skuModifier},
-maxlength => 64,
);
$f->submit;
return _submenu($f->print, 'edit option', 'edit option');
}
#-------------------------------------------------------------------
sub www_editProductParameterOptionSave {
my ($self, @error, $optionId, $product, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
push (@error, $i18n->get('edit option value error')) unless ($session{form}{value});
push (@error, $i18n->get('edit option parameterId error')) unless ($session{form}{parameterId});
return '<ul><li>'.join('</li><li>', @error).'</li></ul><br>'.WebGUI::Operation::execute('editProduct') if (@error);
$product = WebGUI::Product->getByParameterId($session{form}{parameterId});
$optionId = $session{form}{optionId};
$optionId = $product->addOptionToParameter($session{form}{parameterId}) if ($optionId eq 'new');
$product->setOption($optionId, {
value => $session{form}{value},
priceModifier => $session{form}{priceModifier},
weightModifier => $session{form}{weightModifier},
skuModifier => $session{form}{skuModifier}
});
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_editProductVariant {
my ($variantId, $variant, $f, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new("ProductManager");
$variantId = $session{form}{variantId};
$variant = WebGUI::Product->getByVariantId($variantId)->getVariant($variantId);
$f = WebGUI::HTMLForm->new;
$f->hidden('op', 'editProductVariantSave');
$f->hidden('variantId', $variantId);
$f->readOnly(
-label => 'varaiantId',
-value => $variant->{variantId}
);
$f->float(
-name => 'price',
-label => $i18n->get('price override'),
-value => $variant->{priceOverride} ? $variant->{price} : ''
);
$f->float(
-name => 'weight',
-label => $i18n->get('weight override'),
-value => $variant->{weightOverride} ? $variant->{weight} : ''
);
$f->text(
-name => 'sku',
-label => $i18n->get('sku override'),
-value => $variant->{skuOverride} ? $variant->{sku} : ''
);
$f->yesNo(
-name => 'available',
-label => $i18n->get('available'),
-value => $variant->{available}
);
$f->submit;
return _submenu($f->print, 'edit variant', 'edit variant');
}
#-------------------------------------------------------------------
sub www_editProductVariantSave {
my $variantId = $session{form}{variantId};
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
WebGUI::Product->getByVariantId($variantId)->setVariant($variantId, $session{form});
return WebGUI::Operation::execute('listProductVariants');
}
#-------------------------------------------------------------------
sub www_editSkuTemplate {
my ($product, $productId, $output, $f, $name, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new("ProductManager");
$productId = $session{form}{productId};
$product = WebGUI::Product->new($productId);
$output .= "Available are: <br>\n";
$output .= "<ul><li>base</li>\n";
foreach (@{$product->getParameter}) {
($name = $_->{name}) =~ s/[ ><]/\./g;
$output .= "<li>param.".$name."</li>\n";
}
$output .= "</ul><br>";
$f = WebGUI::HTMLForm->new;
$f->hidden('op', 'editSkuTemplateSave');
$f->hidden('productId', $productId);
$f->text(
-name => 'skuTemplate',
-value => $product->get('skuTemplate'),
-label => $i18n->get('sku template'),
);
$f->submit;
$output .= $f->print;
return _submenu($output, 'edit sku composition label', 'edit sku template');
}
#-------------------------------------------------------------------
sub www_editSkuTemplateSave {
my ($productId) = $session{form}{productId};
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
WebGUI::Product->new($productId)->set({
skuTemplate => $session{form}{skuTemplate},
});
return WebGUI::Operation::execute('manageProduct');
}
#-------------------------------------------------------------------
sub www_listProducts {
my ($self, $sth, $output, $row, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new('ProductManager');
WebGUI::Session::setScratch('managingProduct', '-delete-');
$sth = WebGUI::SQL->read('select * from products order by title');
$output .= '<table>';
while ($row = $sth->hashRef) {
$output .= '<tr>';
$output .= '<td>';
$output .= deleteIcon('op=deleteProduct&productId='.$row->{productId});
$output .= editIcon('op=manageProduct&productId='.$row->{productId});
$output .= '</td>';
$output .= '<td>'.$row->{title}.'</td>';
$output .= '</tr>';
}
$output .= '</table>';
return _submenu($output, 'list products', 'list products');
}
#-------------------------------------------------------------------
sub www_listProductVariants {
my ($productId, $product, @variants, %parameters, %options, $output, %composition, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new("ProductManager");
$productId = $session{form}{productId} || WebGUI::Session::getScratch('managingProduct');
return WebGUI::Operation::execute('listProducts') if ($productId eq 'new' || !$productId);
$product = WebGUI::Product->new($productId);
@variants = sort {$a->{composition} cmp $b->{composition}} @{$product->getVariant};
tie %parameters, "Tie::IxHash";
%parameters = map {$_->{parameterId} => $_->{name}} sort {$a->{name} <=> $b->{name}} @{$product->getParameter};
%options = map {$_->{optionId} => $_->{value}} @{$product->getOption};
$output = WebGUI::Form::formHeader;
$output .= WebGUI::Form::hidden({
name => 'op',
value => 'listProductVariantsSave',
});
$output .= WebGUI::Form::hidden({
name => 'productId',
value => $productId,
});
$output .= '<table><tr align="left">';
$output .= "<th>".join('</th><th>', values(%parameters))."</th>" if (%parameters);
$output .= '<th colspan="2">'.$i18n->get('sku').'</th>'.
'<th colspan="2">'.$i18n->get('price').'</th>'.
'<th colspan="2">'.$i18n->get('weight').'</th>'.
'<th>'.$i18n->get('available').'</th>';
$output .= "</tr>";
foreach (@variants) {
$output .= "<tr>";
%composition = map {split(/\./, $_)} split(/,/, $_->{composition});
foreach (keys(%parameters)) {
$output .= '<td align="left">'.$options{$composition{$_}}.'</td>';
}
$output .= '<td align="left">'.$_->{sku}."</td><td>";
$output .= '*' if ($_->{skuOverride});
$output .= '</td><td align="right">'.$_->{price}."</td><td>";
$output .= '*'if ($_->{priceOverride});
$output .= '</td><td align="right">'.$_->{weight}."</td><td>";
$output .= '*' if ($_->{weightOverride});
$output .= "</td>";
$output .= "<td>".WebGUI::Form::checkbox({
name => 'available',
value => $_->{variantId},
checked => $_->{available},
}).editIcon('op=editProductVariant&variantId='.$_->{variantId})."</td>";
$output .= "</tr>";
}
$output .= "</table>";
$output .= WebGUI::Form::submit;
$output .= WebGUI::Form::formFooter;
return _submenu($output, 'list variants label', 'list variants');
}
#-------------------------------------------------------------------
sub www_listProductVariantsSave {
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
my %availableVariants = map {$_ => 1} $session{cgi}->param('available');
my $product = WebGUI::Product->new($session{form}{productId});
my @variants = @{$product->getVariant};
foreach (@variants) {
$product->setVariant($_->{variantId}, {
available => $availableVariants{$_->{variantId}} ? '1' : '0'});
}
return WebGUI::Operation::execute('listProductVariants');
}
#-------------------------------------------------------------------
sub www_manageProduct {
my ($productId, $product, $output, $parameter, $option, $optionId, $i18n);
return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(14));
$i18n = WebGUI::International->new("ProductManager");
$productId = $session{form}{productId} || WebGUI::Session::getScratch('managingProduct');
return WebGUI::Operation::execute('listProducts') if ($productId eq 'new' || !$productId);
WebGUI::Session::setScratch('managingProduct', $productId);
$product = WebGUI::Product->new($productId);
$output .= "<h1>".$product->get('title')."</h1>";
$output .= "<h2>".$i18n->get('properties').editIcon('op=editProduct&productId='.$productId)."</h2>";
$output .= "<table>";
$output .= "<tr><td>".$i18n->get('price')."</td><td>".$product->get('price')."</td></tr>";
$output .= "<tr><td>".$i18n->get('weight')."</td><td>".$product->get('weight')."</td></tr>";
$output .= "<tr><td>".$i18n->get('sku')."</td><td>".$product->get('sku')."</td></tr>";
$output .= "<tr><td>".$i18n->get('description')."</td><td>".$product->get('description')."</td></tr>";
$output .= "<tr><td>".$i18n->get('sku template')."</td><td>".WebGUI::HTML::format($product->get('skuTemplate'), 'text')."</td></tr>";
$output .= "</table>";
$output .= "<h2>Parameters</h2>";
$output .= '<a href="'.WebGUI::URL::page('op=editProductParameter&parameterId=new&productId='.$product->get('productId')).'">'.
$i18n->get('add parameter').'</a><br>';
foreach $parameter (@{$product->getParameter}) {
$output .= deleteIcon('op=deleteProductParameter&parameterId='.$parameter->{parameterId}).
editIcon('op=editProductParameter&parameterId='.$parameter->{parameterId});
$output .= '<span style="margin-left: 10px"><b>'.$parameter->{name}.'</b></span><br>';
$output .= '<a style="margin-left: 20px" href="'.
WebGUI::URL::page('op=editProductParameterOption&optionId=new&parameterId='.$parameter->{parameterId}).'">'.
$i18n->get('add option').'</a><br>';
foreach $optionId (@{$parameter->{options}}) {
$option = $product->getOption($optionId);
$output .= '<span style="margin-left: 20px">'.
deleteIcon('op=deleteProductParameterOption&optionId='.$option->{optionId}).
editIcon('op=editProductParameterOption&parameterId='.$parameter->{parameterId}.'&optionId='.$option->{optionId}).$option->{value}.'</span><br>';
}
$output .= '<br>';
}
return _submenu($output, 'manage product', 'manage product');
}
1;

420
lib/WebGUI/Product.pm Executable file
View file

@ -0,0 +1,420 @@
package WebGUI::Product;
use strict;
use WebGUI::SQL;
use WebGUI::Id;
use WebGUI::Asset::Template;
#-------------------------------------------------------------------
sub _permute {
my ($currentSet, @permutations, $permutation, $value, @result);
$currentSet = shift;
@permutations = (@_) ? _permute(@_) : [];
foreach $permutation (@permutations) {
foreach $value (@$currentSet) {
push(@result, [$value, @{$permutation}]);
}
}
return @result;
}
#-------------------------------------------------------------------
sub addOptionToParameter {
my ($self, $parameterId, $properties, $optionId);
$self = shift;
$parameterId = shift;
$properties = shift || {};
$optionId = WebGUI::Id::generate;
WebGUI::SQL->write("insert into productParameterOptions ".
"(optionId, parameterId) values ".
"(".quote($optionId).", ".quote($parameterId).")");
$self->{_options}->{$optionId} = {
%$properties,
parameterId => $parameterId,
optionId => $optionId,
};
push(@{$self->{_parameters}->{$parameterId}->{options}}, $optionId);
$self->updateVariants;
return $optionId;
}
#-------------------------------------------------------------------
sub addParameter {
my ($self, $properties, $parameterId);
$self = shift;
$properties = shift;
$parameterId = WebGUI::Id::generate;
WebGUI::SQL->write("insert into productParameters (parameterId, productId) values ".
"(".quote($parameterId).", ".quote($self->get('productId')).")");
$self->{_parameters}->{$parameterId}->{parameterId} = $parameterId;
$self->{_parameters}->{$parameterId}->{options} = [];
return $parameterId;
}
#-------------------------------------------------------------------
sub delete {
my ($self) = shift;
foreach (@{$self->getParameter}) {
WebGUI::SQL->write("delete from productParameterOptions where parameterId=".quote($_->{parameterId}));
}
WebGUI::SQL->write("delete from productParameters where productId=".quote($self->get('productId')));
WebGUI::SQL->write("delete from productVariants where productId=".quote($self->get('productId')));
WebGUI::SQL->write("delete from products where productId=".quote($self->get('productId')));
return undef;
}
#-------------------------------------------------------------------
sub deleteParameter {
my ($self, $parameterId);
$self = shift;
$parameterId = shift;
WebGUI::SQL->write("delete from productParameterOptions where parameterId=".quote($parameterId));
WebGUI::SQL->write("delete from productParameters where parameterId=".quote($parameterId));
$self->updateVariants;
return undef;
}
#-------------------------------------------------------------------
sub deleteOption {
my ($self, $optionId, @options, $parameterId);
$self = shift;
$optionId = shift;
WebGUI::SQL->write("delete from productParameterOptions where optionId=".quote($optionId));
$parameterId = $self->{_options}->{$optionId}->{parameterId};
delete($self->{_options}->{$optionId});
foreach (@{$self->{_parameters}->{$parameterId}->{options}}) {
push(@options, $_) unless ($_ eq $optionId);
}
$self->{_parameters}->{$parameterId}->{options} = \@options;
$self->updateVariants;
return undef;
}
#-------------------------------------------------------------------
sub get {
my ($self, $property);
$self = shift;
$property = shift;
return $self->{_properties}->{$property} if ($property);
return $self->{_properties};
}
#-------------------------------------------------------------------
sub getByOptionId {
my ($class, $optionId, $productId);
$class = shift;
$optionId = shift;
($productId) = WebGUI::SQL->quickArray("select productId from productParameters as t1, productParameterOptions as t2 ".
"where t1.parameterId=t2.parameterId and t2.optionId=".quote($optionId));
return undef unless ($productId);
return WebGUI::Product->new($productId);
}
#-------------------------------------------------------------------
sub getByParameterId {
my ($class, $parameterId, $productId);
$class = shift;
$parameterId = shift;
($productId) = WebGUI::SQL->quickArray("select productId from productParameters where parameterId=".quote($parameterId));
return WebGUI::Product->new($productId);
}
#-------------------------------------------------------------------
sub getByVariantId {
my ($class, $productId, $variantId);
$class = shift;
$variantId = shift;
($productId) = WebGUI::SQL->quickArray("select productId from productVariants where variantId=".quote($variantId));
return WebGUI::Product->new($productId);
}
#-------------------------------------------------------------------
sub getOption {
my ($self, $optionId);
$self = shift;
$optionId = shift;
return $self->{_options}->{$optionId} if ($optionId);
return [ values %{$self->{_options}} ];
}
#-------------------------------------------------------------------
sub getParameter {
my ($self, $parameterId);
$self = shift;
$parameterId = shift;
return $self->{_parameters}->{$parameterId} if ($parameterId);
return [ values %{$self->{_parameters}} ];
}
#-------------------------------------------------------------------
sub getVariant {
my ($self, $variantId);
$self = shift;
$variantId = shift;
return $self->{_variants}->{$variantId} if ($variantId);
return [ values %{$self->{_variants}} ];
}
#-------------------------------------------------------------------
sub new {
my ($class, $productId, $properties, $parameters, $variants, $options, $sth, %row, $option, $new);
$class = shift;
$productId = shift;
WebGUI::ErrorHandler::fatal('no productId') unless ($productId);
$parameters = {};
$variants = {};
$options = {};
if ($productId eq 'new') {
$productId = WebGUI::Id::generate;
$properties = {productId => $productId};
WebGUI::SQL->write("insert into products (productId) values (".quote($productId).")");
} else {
$properties = WebGUI::SQL->quickHashRef("select * from products where productId=".quote($productId));
# fetch parameters and options
$sth = WebGUI::SQL->read("select opt.*, param.* from productParameters as param left join productParameterOptions as opt ".
"on param.parameterId=opt.parameterId where param.productId=".quote($productId));
while (%row = $sth->hash) {
$parameters->{$row{parameterId}} = {
name => $row{name},
parameterId => $row{parameterId},
options => [],
} unless (defined $parameters->{$row{parameterId}});
if ($row{value}) {
$option = {
value => $row{value},
optionId => $row{optionId},
parameterId => $row{parameterId},
priceModifier => $row{priceModifier},
weightModifier => $row{weightModifier},
skuModifier => $row{skuModifier}
};
push(@{$parameters->{$row{parameterId}}->{options}}, $row{optionId});
$options->{$row{optionId}} = $option;
}
}
# fetch variants
$sth = WebGUI::SQL->read("select * from productVariants where productId=".quote($productId));
while (%row = $sth->hash) {
$variants->{$row{variantId}} = {%row};
}
$new = 0;
}
bless {_properties => $properties, _parameters => $parameters, _options => $options, _variants => $variants, _new => $new}, $class;
}
#-------------------------------------------------------------------
sub set {
my ($self, $properties);
$self = shift;
$properties = shift;
WebGUI::SQL->write("update products set ".join(', ', map {$_."=".quote($properties->{$_})} keys(%$properties)).
" where productId=".quote($self->get('productId')));
foreach (keys(%$properties)) {
$self->{_properties}->{$_} = $properties->{$_};
}
$self->updateVariants;
}
#-------------------------------------------------------------------
sub setParameter {
my ($self, $parameterId, $properties);
$self = shift;
$parameterId = shift;
$properties = shift;
WebGUI::SQL->write("update productParameters set ".join(', ', map {$_."=".quote($properties->{$_})} keys(%$properties)).
" where parameterId=".quote($parameterId));
map {$self->{_parameter}->{$parameterId}->{$_} = $properties->{$_}} keys %$properties;
}
#-------------------------------------------------------------------
sub setOption {
my ($self, $optionId, $properties);
$self = shift;
$optionId = shift;
$properties = shift;
WebGUI::SQL->write("update productParameterOptions set ".join(', ', map {$_."=".quote($properties->{$_})} keys(%$properties)).
" where optionId=".quote($optionId));
foreach (keys(%$properties)) {
$self->{_options}->{$optionId}->{$_} = $properties->{$_};
}
$self->updateVariants;
}
#-------------------------------------------------------------------
sub setVariant {
my ($self, $variantId, $properties, @pairs, $original, %sku, $parameterName);
$self = shift;
$variantId = shift;
$properties = shift;
my %pairs = map {split(/\./, $_)} split(/,/, $self->getVariant($variantId)->{composition});
$original->{price} = $self->get('price');
$original->{weight} = $self->get('weight');
$sku{base} = $self->get('sku');
foreach (values(%pairs)) {
my $currentOption = $self->getOption($_);
$original->{price} += $currentOption->{priceModifier};
$original->{weight} += $currentOption->{weightModifier};
($parameterName = $self->{_parameters}->{$currentOption->{parameterId}}->{name}) =~ s/ //g;
$sku{'param.'.$parameterName} = $currentOption->{skuModifier};
}
$original->{sku} = WebGUI::Asset::Template->processRaw($self->get('skuTemplate'), \%sku );
if (defined $properties->{price}) {
if ($properties->{price} ne '') {
push(@pairs, 'price='.quote($properties->{price}).', priceOverride=1');
} else {
push(@pairs, 'price='.quote($original->{price}).', priceOverride=0');
}
}
if (defined $properties->{weight}) {
if ($properties->{weight} ne '') {
push(@pairs, 'weight='.quote($properties->{weight}).', weightOverride=1');
} else {
push(@pairs, 'weight='.quote($original->{weight}).', weightOverride=0');
}
}
if (defined $properties->{sku}) {
if ($properties->{sku} ne '') {
push(@pairs, 'sku='.quote($properties->{sku}).', skuOverride=1');
} else {
push(@pairs, 'sku='.quote($original->{sku}).', skuOverride=0');
}
}
push(@pairs, 'available='.quote($properties->{available})) if (defined $properties->{available});
WebGUI::SQL->write("update productVariants set ".join(', ', @pairs)." where variantId=".quote($variantId)) if (@pairs);
$self->{_variants}->{$variantId} = {%{$self->{_variants}->{$variantId}}, %$properties};
}
#-------------------------------------------------------------------
sub updateVariants {
my ($self, %variants, @optionSets, @variants, $variant, %var, @composition, $option, @newVariants, $parameterName);
$self = shift;
foreach (@{$self->getVariant}) {
$variants{$_->{composition}} = $_;
}
# group options per parameter so they can be permuted
foreach my $parameter (@{$self->getParameter}) {
push (@optionSets, [ map {$self->{_options}->{$_}} @{$parameter->{options}} ] ) if (@{$parameter->{options}});
}
@variants = _permute(@optionSets);
@variants = ([]) unless (@variants);
my %newVariants;
foreach $variant (@variants) {
my %sku;
$var{productId} = $self->get('productId');
$var{price} = $self->get('price');
$var{weight} = $self->get('weight');
$var{sku} = $self->get('sku');
$sku{base} = $self->get('sku');
@composition = ();
foreach $option (@{$variant}) {
$var{price} += $option->{priceModifier};
$var{weight} += $option->{weightModifier};
$var{sku} .= $option->{skuModifier};
($parameterName = $self->{_parameters}->{$option->{parameterId}}->{name}) =~ s/ //g;
$sku{'param.'.$parameterName} = $option->{skuModifier};
$var{description} .= $option->{value};
push (@composition, $option->{parameterId}.".".$option->{optionId});
}
$var{composition} = join(',', sort @composition);
$var{available} = 1;
$var{sku} = WebGUI::Asset::Template->processRaw($self->get('skuTemplate'), \%sku ) || $self->get('sku');
if (defined $variants{$var{composition}}) {
$var{price} = $variants{$var{composition}}{price} if ($variants{$var{composition}}{priceOverride});
$var{weight} = $variants{$var{composition}}{weight} if ($variants{$var{composition}}{weightOverride});
$var{sku} = $variants{$var{composition}}{sku} if ($variants{$var{composition}}{skuOverride});
$var{available} = 0 unless ($variants{$var{composition}}{available});
}
if (exists $variants{$var{composition}}) {
$var{variantId} = $variants{$var{composition}}{variantId},
} else {
$var{variantId} = WebGUI::Id::generate;
}
push (@newVariants, {%var});
$newVariants{$var{variantId}} = {%var};
}
WebGUI::SQL->write("delete from productVariants where productId=".quote($self->get('productId')));
foreach (values %newVariants) {
WebGUI::SQL->write("insert into productVariants (variantId, productId, composition, price, weight, sku, available) values ".
"(".quote($_->{variantId}).", ".quote($_->{productId}).", ".quote($_->{composition}).", ".quote($_->{price}).
", ".quote($_->{weight}).", ".quote($_->{sku}).", ".quote($_->{available}).")");
}
$self->{_variants} = \%newVariants;
}
1;