getting rid of old commerce code. bye bye!

This commit is contained in:
JT Smith 2008-05-27 20:26:16 +00:00
parent f3b14a227c
commit be8ce29f57
36 changed files with 13 additions and 10753 deletions

View file

@ -1,869 +0,0 @@
package WebGUI::Asset::Wobject::Product;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2008 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
use strict;
use Tie::CPHash;
use Tie::IxHash;
use WebGUI::Cache;
use WebGUI::HTMLForm;
use WebGUI::Storage::Image;
use WebGUI::SQL;
use WebGUI::Utility;
use WebGUI::Asset::Wobject;
our @ISA = qw(WebGUI::Asset::Wobject);
#-------------------------------------------------------------------
sub _duplicateFile {
my $self = shift;
my $newAsset = $_[0];
my $column = $_[1];
if($self->get($column)){
my $file = WebGUI::Storage->get($self->session,$self->get($column));
my $newstore = $file->copy;
$newAsset->update({ $column=>$newstore->getId });
}
}
#-------------------------------------------------------------------
=head2 addRevision
Override the default method in order to deal with attachments.
=cut
sub addRevision {
my $self = shift;
my $newSelf = $self->SUPER::addRevision(@_);
if ($newSelf->getRevisionCount > 1) {
foreach my $field (qw(image1 image2 image3 brochure manual warranty)) {
if ($self->get($field)) {
my $newStorage = WebGUI::Storage->get($self->session,$self->get($field))->copy;
$newSelf->update({$field=>$newStorage->getId});
}
}
}
return $newSelf;
}
#-------------------------------------------------------------------
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
my $i18n = WebGUI::International->new($session,"Asset_Product");
my %properties;
tie %properties, 'Tie::IxHash';
%properties = (
cacheTimeout => {
tab => "display",
fieldType => "interval",
defaultValue => 3600,
uiLevel => 8,
label => $i18n->get("cache timeout"),
hoverHelp => $i18n->get("cache timeout help")
},
templateId =>{
fieldType=>"template",
tab => "display",
namespace=>"Product",
label=>$i18n->get(62),
hoverHelp=>$i18n->get('62 description'),
defaultValue=>'PBtmpl0000000000000056'
},
price=>{
label=>$i18n->get(10),
hoverHelp=>$i18n->get('10 description'),
tab => "properties",
fieldType=>"text",
defaultValue=>undef
},
productNumber=>{
tab => "properties",
label=>$i18n->get(11),
hoverHelp=>$i18n->get('11 description'),
fieldType=>"text",
defaultValue=>undef
},
image1=>{
tab => "properties",
fieldType=>"image",
defaultValue=>undef,
maxAttachments=>1,
label=>$i18n->get(7),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=image1;filename=")
},
image2=>{
tab => "properties",
fieldType=>"image",
maxAttachments=>1,
label=>$i18n->get(8),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=image2;filename="),
defaultValue=>undef
},
image3=>{
tab => "properties",
fieldType=>"image",
maxAttachments=>1,
label=>$i18n->get(9),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=image3;filename="),
defaultValue=>undef
},
brochure=>{
tab => "properties",
fieldType=>"file",
maxAttachments=>1,
label=>$i18n->get(13),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=brochure;filename="),
defaultValue=>undef
},
manual=>{
tab => "properties",
fieldType=>"file",
maxAttachments=>1,
label=>$i18n->get(14),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=manual;filename="),
defaultValue=>undef
},
warranty=>{
tab => "properties",
fieldType=>"file",
maxAttachments=>1,
label=>$i18n->get(15),
deleteFileUrl=>$session->url->page("func=deleteFileConfirm;file=warranty;filename="),
defaultValue=>undef
},
);
push(@{$definition}, {
assetName=>$i18n->get('assetName'),
autoGenerateForms=>1,
icon=>'product.gif',
tableName=>'Product',
className=>'WebGUI::Asset::Wobject::Product',
properties=>\%properties
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
sub duplicate {
my $self = shift;
my $newAsset = $self->SUPER::duplicate(@_);
foreach my $file ('image1', 'image2', 'image3', 'manual', 'brochure', 'warranty') {
$self->_duplicateFile($newAsset, $file);
}
foreach my $basename ('feature', 'benefit', 'specification') {
my $table = "Product_${basename}";
my $sth = $self->session->db->read("select * from $table where assetId=?", [$self->getId]);
while (my $row = $sth->hashRef) {
$row->{"${table}Id"} = "new";
$row->{"assetId"} = $newAsset->getId;
$newAsset->setCollateral($table, "${table}Id", $row);
}
}
foreach my $basename ('accessory', 'related') {
my $table = "Product_${basename}";
my $tableAssetId = "${basename}AssetId";
my $sth = $self->session->db->read("select * from $table where assetId=?", [$self->getId]);
my %data;
tie %data, 'Tie::CPHash';
while (%data = $sth->hash) {
$self->session->db->write("insert into $table (assetId, $tableAssetId, sequenceNumber) values (?, ?, ?)", [$newAsset->getId, $data{$tableAssetId}, $data{sequenceNumber}]);
}
}
return $newAsset;
}
#-------------------------------------------------------------------
sub getFileIconUrl {
my $self = shift;
my $store = $_[0];
return $store->getFileIconUrl($self->getFilename($store));
}
#-------------------------------------------------------------------
sub getFilename {
my $self = shift;
my $store = $_[0];
my $files = $store->getFiles();
foreach my $file (@{$files}){
unless($file =~ m/^thumb-/){
return $file;
}
}
return "";
}
#-------------------------------------------------------------------
sub getFileUrl {
my $self = shift;
my $store = $_[0];
return $store->getUrl($self->getFilename($store));
}
#-------------------------------------------------------------------
sub getThumbnailFilename {
my $self = shift;
my $filestore = $_[0];
my $files = $filestore->getFiles();
foreach my $file (@{$files}){
if($file =~ m/^thumb-/){
return $file;
}
}
return "";
}
#-------------------------------------------------------------------
sub getThumbnailUrl {
my $self = shift;
my $store = $_[0];
return $store->getUrl($self->getThumbnailFilename($store));
}
#-------------------------------------------------------------------
=head2 indexContent ( )
Indexing product data. See WebGUI::Asset::indexContent() for additonal details.
=cut
sub indexContent {
my $self = shift;
my $indexer = $self->SUPER::indexContent;
my @data = $self->session->db->buildArray("select feature from Product_feature where assetId=".$self->session->db->quote($self->getId));
$indexer->addKeywords(join(" ", @data));
@data = $self->session->db->buildArray("select benefit from Product_benefit where assetId=".$self->session->db->quote($self->getId));
$indexer->addKeywords(join(" ", @data));
@data = $self->session->db->buildArray("select concat(name,' ',value,' ', units) from Product_specification where assetId=".$self->session->db->quote($self->getId));
$indexer->addKeywords(join(" ", @data));
}
#-------------------------------------------------------------------
=head2 prepareView ( )
See WebGUI::Asset::prepareView() for details.
=cut
sub prepareView {
my $self = shift;
$self->SUPER::prepareView();
my $template = WebGUI::Asset::Template->new($self->session, $self->get("templateId"));
$template->prepare;
$self->{_viewTemplate} = $template;
}
#-------------------------------------------------------------------
sub purge {
my $self = shift;
my $sth = $self->session->db->read("select image1, image2, image3, brochure, manual, warranty from Product where assetId=".$self->session->db->quote($self->getId));
while (my @array = $sth->array) {
foreach my $id (@array){
next if ($id eq "");
WebGUI::Storage->get($self->session,$id)->delete;
}
}
$sth->finish;
$self->session->db->write("delete from Product_accessory where assetId=".$self->session->db->quote($self->getId)." or accessoryAssetId=".$self->session->db->quote($self->getId));
$self->session->db->write("delete from Product_related where assetId=".$self->session->db->quote($self->getId)." or relatedAssetId=".$self->session->db->quote($self->getId));
$self->session->db->write("delete from Product_benefit where assetId=".$self->session->db->quote($self->getId));
$self->session->db->write("delete from Product_feature where assetId=".$self->session->db->quote($self->getId));
$self->session->db->write("delete from Product_specification where assetId=".$self->session->db->quote($self->getId));
$self->SUPER::purge();
}
#-------------------------------------------------------------------
=head2 purgeCache ( )
See WebGUI::Asset::purgeCache() for details.
=cut
sub purgeCache {
my $self = shift;
WebGUI::Cache->new($self->session,"view_".$self->getId)->delete;
$self->SUPER::purgeCache;
}
#-------------------------------------------------------------------
sub purgeRevision {
my $self = shift;
WebGUI::Storage->get($self->session,$self->get("image1"))->delete if ($self->get("image1"));
WebGUI::Storage->get($self->session,$self->get("image2"))->delete if ($self->get("image2"));
WebGUI::Storage->get($self->session,$self->get("image3"))->delete if ($self->get("image3"));
WebGUI::Storage->get($self->session,$self->get("brochure"))->delete if ($self->get("brochure"));
WebGUI::Storage->get($self->session,$self->get("manual"))->delete if ($self->get("manual"));
WebGUI::Storage->get($self->session,$self->get("warranty"))->delete if ($self->get("warranty"));
return $self->SUPER::purgeRevision;
}
#-------------------------------------------------------------------
sub www_addAccessory {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
my ($f, $accessory, @usedAccessories);
$f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name => "func",
-value => "addAccessorySave",
);
@usedAccessories = $self->session->db->buildArray("select accessoryAssetId from Product_accessory where assetId=".$self->session->db->quote($self->getId));
push(@usedAccessories,$self->getId);
$accessory = $self->session->db->buildHashRef("select asset.assetId, assetData.title from asset left join assetData on assetData.assetId=asset.assetId where asset.className='WebGUI::Asset::Wobject::Product' and asset.assetId not in (".$self->session->db->quoteAndJoin(\@usedAccessories).") and (assetData.status='approved' or assetData.tagId=".$self->session->db->quote($self->session->scratch->get("versionTag")).") group by assetData.assetId");
my $i18n = WebGUI::International->new($self->session,"Asset_Product");
$f->selectBox(
-name => "accessoryAccessId",
-options => $accessory,
-label => $i18n->get(17),
-hoverHelp => $i18n->get('17 description'),
);
$f->yesNo(
-name => "proceed",
-label => $i18n->get(18),
-hoverHelp => $i18n->get('18 description'),
);
$f->submit;
return $self->getAdminConsole->render($f->print, "product accessory add/edit");
}
#-------------------------------------------------------------------
sub www_addAccessorySave {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
return "" unless ($self->session->form->process("accessoryAccessId"));
my ($seq) = $self->session->db->quickArray("select max(sequenceNumber) from Product_accessory where assetId=".$self->session->db->quote($self->getId()));
$self->session->db->write("insert into Product_accessory (assetId,accessoryAssetId,sequenceNumber) values (".$self->session->db->quote($self->getId()).",".$self->session->db->quote($self->session->form->process("accessoryAccessId")).",".($seq+1).")");
return "" unless($self->session->form->process("proceed"));
return $self->www_addAccessory();
}
#-------------------------------------------------------------------
sub www_addRelated {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
my ($f, $related, @usedRelated);
$f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name => "func",
-value => "addRelatedSave",
);
@usedRelated = $self->session->db->buildArray("select relatedAssetId from Product_related where assetId=".$self->session->db->quote($self->getId));
push(@usedRelated,$self->getId);
$related = $self->session->db->buildHashRef("select asset.assetId,assetData.title from asset left join assetData on assetData.assetId=asset.assetId where asset.className='WebGUI::Asset::Wobject::Product' and asset.assetId not in (".$self->session->db->quoteAndJoin(\@usedRelated).")");
my $i18n = WebGUI::International->new($self->session,'Asset_Product');
$f->selectBox(
-name => "relatedAssetId",
-options => $related,
-label => $i18n->get(20),
-hoverHelp => $i18n->get('20 description'),
);
$f->yesNo(
-name => "proceed",
-label => $i18n->get(21),
-hoverHelp => $i18n->get('21 description'),
);
$f->submit;
return $self->getAdminConsole->render($f->print,"product related add/edit");
}
#-------------------------------------------------------------------
sub www_addRelatedSave {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
return "" unless ($self->session->form->process("relatedAssetId"));
my ($seq) = $self->session->db->quickArray("select max(sequenceNumber) from Product_related where assetId=".$self->session->db->quote($self->getId));
$self->session->db->write("insert into Product_related (assetId,relatedAssetId,sequenceNumber) values (".$self->session->db->quote($self->getId).",".$self->session->db->quote($self->session->form->process("relatedAssetId")).",".($seq+1).")");
return "" unless($self->session->form->process("proceed"));
return $self->www_addRelated();
}
#-------------------------------------------------------------------
sub www_deleteAccessoryConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->session->db->write("delete from Product_accessory where assetId=".$self->session->db->quote($self->getId())." and accessoryAssetId=".$self->session->db->quote($self->session->form->process("aid")));
$self->reorderCollateral("Product_accessory","accessoryAssetId");
return "";
}
#-------------------------------------------------------------------
sub www_deleteBenefitConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->deleteCollateral("Product_benefit","Product_benefitId",$self->session->form->process("bid"));
$self->reorderCollateral("Product_benefit","Product_benefitId");
return "";
}
#-------------------------------------------------------------------
sub www_deleteFeatureConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->deleteCollateral("Product_feature","Product_featureId",$self->session->form->process("fid"));
$self->reorderCollateral("Product_feature","Product_featureId");
return "";
}
#-------------------------------------------------------------------
sub www_deleteFileConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
my $column = $self->session->form->process("file");
return $self->www_edit unless (isIn($column, qw(image1 image2 image3 manual warranty brochure)));
my $store = $self->get($column);
my $file = WebGUI::Storage->get($self->session,$store);
$file->delete if defined $file;
$self->update({$column=>''});
return $self->www_edit;
}
#-------------------------------------------------------------------
sub www_deleteRelatedConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->session->db->write("delete from Product_related where assetId=".$self->session->db->quote($self->getId)." and relatedAssetId=".$self->session->db->quote($self->session->form->process("rid")));
$self->reorderCollateral("Product_related","relatedAssetId");
return "";
}
#-------------------------------------------------------------------
sub www_deleteSpecificationConfirm {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->deleteCollateral("Product_specification","Product_specificationId",$self->session->form->process("sid"));
$self->reorderCollateral("Product_specification","Product_specificationId");
return "";
}
#-------------------------------------------------------------------
sub www_editBenefit {
my $self = shift;
my $bid = shift || $self->session->form->process("bid");
return $self->session->privilege->insufficient() unless ($self->canEdit);
my ($data, $f, $benefits);
$data = $self->getCollateral("Product_benefit","Product_benefitId",$bid);
my $i18n = WebGUI::International->new($self->session,'Asset_Product');
$f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name => "bid",
-value => $data->{Product_benefitId},
);
$f->hidden(
-name => "func",
-value => "editBenefitSave",
);
$benefits = $self->session->db->buildHashRef("select benefit,benefit from Product_benefit order by benefit");
$f->combo(
-name => "benefit",
-options => $benefits,
-label => $i18n->get(51),
-hoverHelp => $i18n->get('51 description'),
-value => [$data->{benefits}],
);
$f->yesNo(
-name => "proceed",
-label => $i18n->get(52),
-hoverHelp => $i18n->get('52 description'),
);
$f->submit;
return $self->getAdminConsole->render($f->print, "product benefit add/edit");
}
#-------------------------------------------------------------------
sub www_editBenefitSave {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->setCollateral("Product_benefit", "Product_benefitId", {
Product_benefitId => $self->session->form->process("bid"),
benefit => $self->session->form->process("benefit","combo")
});
return "" unless($self->session->form->process("proceed"));
return $self->www_editBenefit("new");
}
#-------------------------------------------------------------------
sub www_editFeature {
my $self = shift;
my $fid = shift || $self->session->form->process("fid");
return $self->session->privilege->insufficient() unless ($self->canEdit);
my ($data, $f, $features);
$data = $self->getCollateral("Product_feature","Product_featureId",$fid);
my $i18n = WebGUI::International->new($self->session,'Asset_Product');
$f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name => "fid",
-value => $data->{Product_featureId},
);
$f->hidden(
-name => "func",
-value => "editFeatureSave",
);
$features = $self->session->db->buildHashRef("select feature,feature from Product_feature order by feature");
$f->combo(
-name => "feature",
-options => $features,
-label => $i18n->get(23),
-hoverHelp => $i18n->get('23 description'),
-value => [$data->{feature}],
);
$f->yesNo(
-name => "proceed",
-label => $i18n->get(24),
-hoverHelp => $i18n->get('24 description'),
);
$f->submit;
return $self->getAdminConsole->render($f->print, "product feature add/edit");
}
#-------------------------------------------------------------------
sub www_editFeatureSave {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->setCollateral("Product_feature", "Product_featureId", {
Product_featureId => $self->session->form->process("fid"),
feature => $self->session->form->process("feature","combo")
});
return "" unless($self->session->form->process("proceed"));
return $self->www_editFeature("new");
}
#-------------------------------------------------------------------
sub www_editSpecification {
my $self = shift;
my $sid = shift || $self->session->form->process("sid");
return $self->session->privilege->insufficient() unless ($self->canEdit);
my ($data, $f, $hashRef);
my $i18n = WebGUI::International->new($self->session,'Asset_Product');
$data = $self->getCollateral("Product_specification","Product_specificationId",$sid);
$f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
$f->hidden(
-name => "sid",
-value => $data->{Product_specificationId},
);
$f->hidden(
-name => "func",
-value => "editSpecificationSave",
);
$hashRef = $self->session->db->buildHashRef("select name,name from Product_specification order by name");
$f->combo(
-name => "name",
-options => $hashRef,
-label => $i18n->get(26),
-hoverHelp => $i18n->get('26 description'),
-value => [$data->{name}],
);
$f->text(
-name => "value",
-label => $i18n->get(27),
-hoverHelp => $i18n->get('27 description'),
-value => $data->{value},
);
$hashRef = $self->session->db->buildHashRef("select units,units from Product_specification order by units");
$f->combo(
-name => "units",
-options => $hashRef,
-label => $i18n->get(29),
-hoverHelp => $i18n->get('29 description'),
-value => [$data->{units}],
);
$f->yesNo(
-name => "proceed",
-label => $i18n->get(28),
-hoverHelp => $i18n->get('28 description'),
);
$f->submit;
return $self->getAdminConsole->render($f->print, "product specification add/edit");
}
#-------------------------------------------------------------------
sub www_editSpecificationSave {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->setCollateral("Product_specification", "Product_specificationId", {
Product_specificationId => $self->session->form->process("sid"),
name => $self->session->form->process("name","combo"),
value => $self->session->form->process("value","combo"),
units => $self->session->form->process("units","combo")
});
return "" unless($self->session->form->process("proceed"));
return $self->www_editSpecification("new");
}
#-------------------------------------------------------------------
sub www_moveAccessoryDown {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralDown("Product_accessory","accessoryAssetId",$self->session->form->process("aid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveAccessoryUp {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralUp("Product_accessory","accessoryAssetId",$self->session->form->process("aid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveBenefitDown {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralDown("Product_benefit","Product_benefitId",$self->session->form->process("bid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveBenefitUp {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralUp("Product_benefit","Product_benefitId",$self->session->form->process("bid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveFeatureDown {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralDown("Product_feature","Product_featureId",$self->session->form->process("fid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveFeatureUp {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralUp("Product_feature","Product_featureId",$self->session->form->process("fid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveRelatedDown {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralDown("Product_related","relatedAssetId",$self->session->form->process("rid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveRelatedUp {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralUp("Product_related","relatedAssetId",$self->session->form->process("rid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveSpecificationDown {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralDown("Product_specification","Product_specificationId",$self->session->form->process("sid"));
return "";
}
#-------------------------------------------------------------------
sub www_moveSpecificationUp {
my $self = shift;
return $self->session->privilege->insufficient() unless ($self->canEdit);
$self->moveCollateralUp("Product_specification","Product_specificationId",$self->session->form->process("sid"));
return "";
}
#-------------------------------------------------------------------
sub view {
my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get;
return $out if $out;
}
my (%data, $sth, $file, $segment, %var, @featureloop, @benefitloop, @specificationloop, @accessoryloop, @relatedloop);
tie %data, 'Tie::CPHash';
my $brochure = $self->get("brochure");
my $manual = $self->get("manual");
my $warranty = $self->get("warranty");
my $image1 = $self->get("image1");
my $image2 = $self->get("image2");
my $image3 = $self->get("image3");
#---brochure
my $i18n = WebGUI::International->new($self->session,'Asset_Product');
if ($brochure) {
$file = WebGUI::Storage->get($self->session,$brochure);
$var{"brochure.icon"} = $self->getFileIconUrl($file);
$var{"brochure.label"} = $i18n->get(13);
$var{"brochure.URL"} = $self->getFileUrl($file);
}
#---manual
if ($manual) {
$file = WebGUI::Storage->get($self->session,$manual);
$var{"manual.icon"} = $self->getFileIconUrl($file);
$var{"manual.label"} = $i18n->get(14);
$var{"manual.URL"} = $self->getFileUrl($file);
}
#---warranty
if ($warranty) {
$file = WebGUI::Storage->get($self->session,$warranty);
$var{"warranty.icon"} = $self->getFileIconUrl($file);
$var{"warranty.label"} = $i18n->get(15);
$var{"warranty.URL"} = $self->getFileUrl($file);
}
#---image1
if ($image1) {
$file = WebGUI::Storage->get($self->session,$image1);
$var{thumbnail1} = $self->getThumbnailUrl($file);
$var{image1} = $self->getFileUrl($file);
}
#---image2
if ($image2) {
$file = WebGUI::Storage->get($self->session,$image2);
$var{thumbnail2} = $self->getThumbnailUrl($file);
$var{image2} = $self->getFileUrl($file);
}
#---image3
if ($image3) {
$file = WebGUI::Storage->get($self->session,$image3);
$var{thumbnail3} = $self->getThumbnailUrl($file);
$var{image3} = $self->getFileUrl($file);
}
#---features
$var{"addFeature.url"} = $self->getUrl('func=editFeature&fid=new');
$var{"addFeature.label"} = $i18n->get(34);
$sth = $self->session->db->read("select feature,Product_featureId from Product_feature where assetId=".$self->session->db->quote($self->getId)." order by sequenceNumber");
while (%data = $sth->hash) {
$segment = $self->session->icon->delete('func=deleteFeatureConfirm&fid='.$data{Product_featureId},$self->get("url"),$i18n->get(3))
.$self->session->icon->edit('func=editFeature&fid='.$data{Product_featureId},$self->get("url"))
.$self->session->icon->moveUp('func=moveFeatureUp&&fid='.$data{Product_featureId},$self->get("url"))
.$self->session->icon->moveDown('func=moveFeatureDown&&fid='.$data{Product_featureId},$self->get("url"));
push(@featureloop,{
"feature.feature"=>$data{feature},
"feature.controls"=>$segment
});
}
$sth->finish;
$var{feature_loop} = \@featureloop;
#---benefits
$var{"addBenefit.url"} = $self->getUrl('func=editBenefit&fid=new');
$var{"addBenefit.label"} = $i18n->get(55);
$sth = $self->session->db->read("select benefit,Product_benefitId from Product_benefit where assetId=".$self->session->db->quote($self->getId)." order by sequenceNumber");
while (%data = $sth->hash) {
$segment = $self->session->icon->delete('func=deleteBenefitConfirm&bid='.$data{Product_benefitId},$self->get("url"),$i18n->get(48))
.$self->session->icon->edit('func=editBenefit&bid='.$data{Product_benefitId},$self->get("url"))
.$self->session->icon->moveUp('func=moveBenefitUp&bid='.$data{Product_benefitId},$self->get("url"))
.$self->session->icon->moveDown('func=moveBenefitDown&bid='.$data{Product_benefitId},$self->get("url"));
push(@benefitloop,{
"benefit.benefit"=>$data{benefit},
"benefit.controls"=>$segment
});
}
$sth->finish;
$var{benefit_loop} = \@benefitloop;
#---specifications
$var{"addSpecification.url"} = $self->getUrl('func=editSpecification&sid=new');
$var{"addSpecification.label"} = $i18n->get(35);
$sth = $self->session->db->read("select name,value,units,Product_specificationId from Product_specification where assetId=".$self->session->db->quote($self->getId)." order by sequenceNumber");
while (%data = $sth->hash) {
$segment = $self->session->icon->delete('func=deleteSpecificationConfirm&sid='.$data{Product_specificationId},$self->get("url"),$i18n->get(5))
.$self->session->icon->edit('func=editSpecification&sid='.$data{Product_specificationId},$self->get("url"))
.$self->session->icon->moveUp('func=moveSpecificationUp&sid='.$data{Product_specificationId},$self->get("url"))
.$self->session->icon->moveDown('func=moveSpecificationDown&sid='.$data{Product_specificationId},$self->get("url"));
push(@specificationloop,{
"specification.controls"=>$segment,
"specification.specification"=>$data{value},
"specification.units"=>$data{units},
"specification.label"=>$data{name}
});
}
$sth->finish;
$var{specification_loop} = \@specificationloop;
#---accessories
$var{"addaccessory.url"} = $self->getUrl('func=addAccessory');
$var{"addaccessory.label"} = $i18n->get(36);
$sth = $self->session->db->read("select Product_accessory.accessoryAssetId from Product_accessory
where Product_accessory.assetId=".$self->session->db->quote($self->getId)."
order by Product_accessory.sequenceNumber");
while (my ($id) = $sth->array) {
$segment = $self->session->icon->delete('func=deleteAccessoryConfirm&aid='.$id,$self->get("url"),$i18n->get(2))
.$self->session->icon->moveUp('func=moveAccessoryUp&aid='.$id,$self->get("url"))
.$self->session->icon->moveDown('func=moveAccessoryDown&aid='.$id,$self->get("url"));
my $accessory = WebGUI::Asset->newByDynamicClass($self->session,$id);
push(@accessoryloop,{
"accessory.URL"=>$accessory->getUrl,
"accessory.title"=>$accessory->getTitle,
"accessory.controls"=>$segment
});
}
$sth->finish;
$var{accessory_loop} = \@accessoryloop;
#---related
$var{"addrelatedproduct.url"} = $self->getUrl('func=addRelated');
$var{"addrelatedproduct.label"} = $i18n->get(37);
$sth = $self->session->db->read("select Product_related.relatedAssetId
from Product_related
where Product_related.assetId=".$self->session->db->quote($self->getId)."
order by Product_related.sequenceNumber");
while (my ($id) = $sth->array) {
$segment = $self->session->icon->delete('func=deleteRelatedConfirm&rid='.$id,$self->get("url"),$i18n->get(4))
.$self->session->icon->moveUp('func=moveRelatedUp&rid='.$id,$self->get("url"))
.$self->session->icon->moveDown('func=moveRelatedDown&rid='.$id,$self->get("url"));
my $related = WebGUI::Asset->newByDynamicClass($self->session,$id);
push(@relatedloop,{
"relatedproduct.URL"=>$related->getUrl,
"relatedproduct.title"=>$related->getTitle,
"relatedproduct.controls"=>$segment
});
}
$sth->finish;
$var{relatedproduct_loop} = \@relatedloop;
my $out = $self->processTemplate(\%var,undef,$self->{_viewTemplate});
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
WebGUI::Cache->new($self->session,"view_".$self->getId)->set($out,$self->get("cacheTimeout"));
}
return $out;
}
#-------------------------------------------------------------------
=head2 www_view ( )
See WebGUI::Asset::Wobject::www_view() for details.
=cut
sub www_view {
my $self = shift;
$self->session->http->setCacheControl($self->get("cacheTimeout"));
$self->SUPER::www_view(@_);
}
1;

View file

@ -1,33 +0,0 @@
package WebGUI::Commerce;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
#-------------------------------------------------------------------
sub setCommerceSetting {
my $session = shift;
my ($entry);
$entry = shift;
$session->db->write("delete from commerceSettings where ".
"namespace=".$session->db->quote($entry->{namespace})." and ".
"type=".$session->db->quote($entry->{type})." and fieldName=".$session->db->quote($entry->{fieldName}));
$session->db->write("insert into commerceSettings (namespace, type, fieldName, fieldValue) values ".
"(".$session->db->quote($entry->{namespace}).",".$session->db->quote($entry->{type}).",".$session->db->quote($entry->{fieldName}).",".$session->db->quote($entry->{fieldValue}).")");
}
1;

View file

@ -1,258 +0,0 @@
package WebGUI::Commerce::Item;
use strict;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item
=head1 DESCRIPTION
This is the SUPER class off all Item plugins. Item plugins are an abstraction layer to connect
arbitrary types of products and other stuff you might want to sell to the commerce system.
The SUPER class new method provides an easy way to load Item plugins: WebGUI::Commerce::Item->new($self->session,'1234', 'MyItem')
is equivalent to WebGUI::Commerce::Item::MyItem->new($self->session,'1234'). The SUPER class new has the benefit of added
error checking, so you should use this.
=head1 SYNOPSIS
use WebGUI::Commerce::Item;
$item = WebGUI::Commerce::Item->new($self->session,$itemId, $itemType);
$description = $item->description;
$duration = $item->duration;
$item->handler;
$id = $item->id
$isRecurring = $item->isRecurring;
$name = $item->name;
$price = $item->price;
$type = $item->type;
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 available ( )
Returns a boolean indicating that the item is available or not.
=cut
sub available {
return 1;
}
#-------------------------------------------------------------------
=head2 description ( )
This returns the description of the item. This must be implemented by an item plugin.
=cut
sub description {
my $self = shift;
return $self->session->errorHandler->fatal('The description method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 duration ( )
This returns the duration of a term when the item is recurring. If your item isn't
recurring you don't need to override this method. If you do however, you should return
undef if it's not recurring.
=cut
sub duration {
return undef;
}
#-------------------------------------------------------------------
=head2 handler ( )
This will execute the handler that's tied to this item. If you don't have a handler for
your item you don't have to override this method or if you do, you can just return undef.
=cut
sub handler {
return undef;
}
#-------------------------------------------------------------------
=head2 id ( )
This returns the item ID. This must be implemented by an item plugin. This must be implemented
by an item plugin.
=cut
sub id {
my $self = shift;
return $self->session->errorHandler->fatal('The id method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 isRecurring ( )
A boolean identifying wheter the item is recurring (like, for instance, a subscription) or not.
You must override this method if your item is recurring.
=cut
sub isRecurring {
return 0;
}
#-------------------------------------------------------------------
=head2 name ( )
Returns the name of the item. This must be implemented by an item plugin.
=cut
sub name {
my $self = shift;
return $self->session->errorHandler->fatal('The name method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 needsShipping ( )
Return a boolean indicating whether the item needs to be shipped or not. Defaults to false.
=cut
sub needsShipping {
return 0;
}
#-------------------------------------------------------------------
=head2 new ( itemdId, itemType )
Returns an item object of type itemType and with id itemId. Note that this is an easy way to load
item plugins. Your custom plugin should also have a new method that returns the actual item object.
The new method of the plugin won't overload this method, since there's no inheritance.
=head3 itemId
The id of the item you want to load.
=head3 itemType
The type (namespace) of the item you want.
=cut
sub new {
my ($class, $session, $id, $namespace) = @_;
$session->errorHandler->fatal('No namespace') unless ($namespace);
$session->errorHandler->fatal('No ID') unless ($id);
my $cmd = "WebGUI::Commerce::Item::$namespace";
my $load = "use $cmd";
eval($load);
$session->errorHandler->warn("Item plugin failed to compile: $cmd.".$@) if($@);
my $plugin = eval($cmd.'->new($session, "$id", "$namespace")');
$session->errorHandler->warn("Couldn't instantiate Item plugin: $cmd.".$@) if($@);
return $plugin;
}
#-------------------------------------------------------------------
=head2 price ( )
This method should return the price of the item. If the item is recurring this should be the per
term price. This must be implemented by an item plugin.
=cut
sub price {
my $self = shift;
return $self->session->errorHandler->fatalError('The price method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 session ( )
Returns a reference to the current session.
=cut
sub session {
my $self = shift;
return $self->{_session};
}
#-------------------------------------------------------------------
=head2 type ( )
Returns the type (namespace) of the item.
=cut
sub type {
my $self = shift;
return $self->session->errorHandler->fatalError('The type method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 useSalesTax ( )
This method should return whether or not the item uses sales tax.
This must be implemented by an item plugin.
=cut
sub useSalesTax {
my $self = shift;
return $self->session->errorHandler->fatalError('The useSalesTax method of WebGUI::Commerce::Item must be overridden.');
}
#-------------------------------------------------------------------
=head2 weight ( )
Returns the weight of the item. If your item has a weight, you'll want to overload this method. Weight is calculated on a unit based scale.
So for instance if your units are kg's 3.154 means 3 kg and 154 grams.
=cut
sub weight {
return 0;
}
1;

View file

@ -1,203 +0,0 @@
package WebGUI::Commerce::Item::Event;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item::Event
=head1 DESCRIPTION
Item plugin for events in the EventManagement system. Allows events entered there
to be part of the Commerce system.
=cut
use strict;
our @ISA = qw(WebGUI::Commerce::Item);
use WebGUI::Utility;
#-------------------------------------------------------------------
sub available {
return $_[0]->{_event}->{approved};
}
#-------------------------------------------------------------------
sub description {
return $_[0]->{_event}->{description};
}
#-------------------------------------------------------------------
sub handler {
my $self = shift;
my $transactionId = shift;
#mark all purchaseIds as paid
my $purchases
= $self->session->db->buildArrayRefOfHashRefs(
"SELECT purchaseId FROM EventManagementSystem_sessionPurchaseRef WHERE sessionId=?",
[$self->session->getId]
);
for my $purchase (@$purchases) {
my $purchaseId = $purchase->{purchaseId};
$self->session->db->setRow('EventManagementSystem_purchases', 'purchaseId', {'purchaseId'=>$purchaseId, 'transactionId'=>$transactionId}, $purchaseId);
my $theseRegs = $self->session->db->buildArrayRefOfHashRefs("select * from EventManagementSystem_registrations where purchaseId=?",[$purchaseId]);
foreach (@$theseRegs) {
# clean up the duplicate registrations, if any.
$self->session->db->write("delete from EventManagementSystem_registrations where badgeId=? and productId=? and registrationId != ?",[$_->{badgeId},$_->{productId},$_->{registrationId}]);
}
}
$self->session->db->write(
"DELETE FROM EventManagementSystem_sessionPurchaseRef WHERE sessionId=?",
[$self->session->getId]
);
}
#-------------------------------------------------------------------
sub id {
return $_[0]->{_event}->{productId};
}
#-------------------------------------------------------------------
sub isRecurring {
return 0;
}
#-------------------------------------------------------------------
sub name {
return $_[0]->{_event}->{sku}." ".$_[0]->{_event}->{title};
}
#-------------------------------------------------------------------
=head2 new ( $session )
Overload default constructor to glue in information from the EMS.
=cut
sub new {
my ($class, $session, $eventId);
$class = shift;
$session = shift;
$eventId = shift;
my $eventData = $session->db->quickHashRef("select p.productId, p.title, p.description, p.price, p.useSalesTax, p.sku, e.approved, e.passId, e.passType
from EventManagementSystem_products as e, products as p
where p.productId = e.productId and p.productId=".$session->db->quote($eventId));
bless {_event => $eventData, _session => $session, priceLineItem => 1}, $class;
}
#-------------------------------------------------------------------
sub needsShipping {
return 0;
}
#-------------------------------------------------------------------
sub price {
return $_[0]->{_event}->{price};
}
#-------------------------------------------------------------------
sub priceLineItem {
my $self = shift;
# this will become the total number of normally-priced events.
my $quantity = shift;
# this is the output of ShoppingCart->getItems (the \@normal arrayref).
my $cartItems = shift;
#use Data::Dumper;
# $self->session->errorHandler->warn('normal contents: '.Dumper($cartItems));
# this is the default price of this event.
my $price = $self->{_event}->{price};
# get the list of discount passes that this event is "under"
my @discountPasses = split(/::/,$self->{_event}->{passId});
# $self->session->errorHandler->warn('discount passes: '.Dumper(\@discountPasses));
# return the default behavior if this event does not have a pass assigned.
return ($price * $quantity) unless (scalar(@discountPasses) && ($self->{_event}->{passType} eq 'member'));
# keep a running total of this line item.
my $totalPrice = 0;
# build the list of passes in our cart.
my %passesInCart; # key: passId, value: quantity in cart
my $totalPassesInCart;
foreach my $passId (@discountPasses) {
# get a list of events that define this pass
my @passEvents = $self->session->db->buildArray("select productId from EventManagementSystem_products where passType='defines' and passId=?",[$passId]);
# $self->session->errorHandler->warn('pass events: '.Dumper(\@passEvents));
my $numberOfPasses = 0;
# find out if we have any of this pass's events in our cart.
foreach my $item (@$cartItems) {
# $self->session->errorHandler->warn('quantity of this pass event: '.$item->{quantity});
$numberOfPasses += $item->{quantity} if (
$item->{item}->type eq 'Event'
&& isIn($item->{item}->{_event}->{productId},@passEvents)
);
}
if ($numberOfPasses) {
#$self->session->errorHandler->warn('adding a discount pass.');
$passesInCart{$passId} = $numberOfPasses;
$totalPassesInCart += $numberOfPasses;
}
}
foreach my $passId (keys(%passesInCart)) {
my $pass = $self->session->db->quickHashRef("select * from EventManagementSystem_discountPasses where passId=?",[$passId]);
my $discountedPrice = $price;
my $numberOfThisPass = $passesInCart{$passId};
# calculate discount.
if ($pass->{type} eq 'newPrice') {
#$self->session->errorHandler->warn('discounted price: '.$pass->{amount});
$discountedPrice = (0 + $pass->{amount}) if ($price > (0 + $pass->{amount}));
} elsif ($pass->{type} eq 'amountOff') {
# not yet implemented!
} elsif ($pass->{type} eq 'percentOff') {
# not yet implemented!
}
# while we still have passes and items left to discount.
while ($numberOfThisPass && $quantity) {
#$self->session->errorHandler->warn('applying a discount pass.');
$totalPrice += $discountedPrice;
#$self->session->errorHandler->warn('new discounted price: '.$discountedPrice);
$quantity--;
$numberOfThisPass--;
}
}
# return the total of the discounted items plus the total of the non discounted items.
#$self->session->errorHandler->warn($totalPrice + ($quantity * $price));
return ($totalPrice + ($quantity * $price));
}
#-------------------------------------------------------------------
sub session {
my $self = shift;
return $self->{_session};
}
#-------------------------------------------------------------------
sub type {
return 'Event';
}
#-------------------------------------------------------------------
sub useSalesTax {
my $self = shift;
return $self->{_event}->{useSalesTax} ? 1 : 0;
}
#-------------------------------------------------------------------
sub weight {
return 0;
}
1;

View file

@ -1,33 +0,0 @@
package WebGUI::Commerce::Item::Fake;
# Adding this to cope with sales tax without changing the schema.
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2008 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
use strict;
use WebGUI::Commerce::Item;
use base 'WebGUI::Commerce::Item';
sub new {
my $class = shift;
my $session = shift;
my $id = shift;
my $namespace = shift;
my ($price, $name) = split /\,/, $id, 2;
bless { _name => $name, _price => $price }, $class;
}
sub useSalesTax { 0 }
sub name { $_[0]{_name} }
sub price { $_[0]{_price} }
sub type { 'Fake' }
sub id { "$_[0]{_price},$_[0]{_name}" }
sub description { $_[0]{_name} }
1;

View file

@ -1,142 +0,0 @@
package WebGUI::Commerce::Item::Product;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item::Product
=head1 DESCRIPTION
Item plugin for products in the Commerce system.
=cut
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 {
my $self = shift;
### Add to group action
# If group is 'everyone', skip
if ($self->{_product}->get('groupId') && $self->{_product}->get('groupId') ne '7') {
my $g = WebGUI::Group->new($self->session,$self->{_product}->get('groupId'));
my $expiresOffset;
# Parse the value
if ($self->{_product}->get('groupExpiresOffset') =~ /^(\d+)month/i) {
$expiresOffset = $1 * 3600*24*30; # One month
} elsif ($self->{_product}->get('groupExpiresOffset') =~ /^(\d+)year/i) {
$expiresOffset = $1 * 3600*24*365; # One year
}
# Multiply by how many quantity we're purchasing
#!!! TODO !!! - handlers don't know how many we're purchasing
# If user has time left
my $remains = $g->userGroupExpireDate($self->session->user->userId);
if ($remains) {
# Add any remaining time to the offset
$expiresOffset += $remains - time();
}
# Add user to group
$g->addUsers([$self->session->user->userId],$expiresOffset);
}
}
#-------------------------------------------------------------------
sub id {
return $_[0]->{_variant}->{variantId};
}
#-------------------------------------------------------------------
sub isRecurring {
return 0;
}
#-------------------------------------------------------------------
sub name {
return $_[0]->{_product}->get('title').' ('.$_[0]->{_composition}.')';
}
#-------------------------------------------------------------------
=head2 new ( $session )
Overload default constructor to glue in a WebGUI::Product object.
=cut
sub new {
my ($class, $session, $sku, $product, $variantId);
$class = shift;
$session = shift;
$variantId = shift;
$product = WebGUI::Product->getByVariantId($session,$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, _session => $session }, $class;
}
#-------------------------------------------------------------------
sub needsShipping {
return 1;
}
#-------------------------------------------------------------------
sub price {
return $_[0]->{_variant}->{price};
}
#-------------------------------------------------------------------
sub useSalesTax {
my $self = shift;
return $self->{_product}->get('useSalesTax') ? 1 : 0;
}
#-------------------------------------------------------------------
sub type {
return 'Product';
}
#-------------------------------------------------------------------
sub weight {
return $_[0]->{_variant}->{weight};
}
1;

View file

@ -1,97 +0,0 @@
package WebGUI::Commerce::Item::Subscription;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item::Subscription
=head1 DESCRIPTION
Item plugin for subscriptions.
=cut
use strict;
#use WebGUI::SQL;
use WebGUI::Subscription;
our @ISA = qw(WebGUI::Commerce::Item);
#-------------------------------------------------------------------
sub description {
return $_[0]->{_subscription}->get('description');
}
#-------------------------------------------------------------------
sub duration {
$_[0]->{_subscription}->get('duration');
}
#-------------------------------------------------------------------
sub handler {
$_[0]->{_subscription}->apply($_[1]);
}
#-------------------------------------------------------------------
sub id {
return $_[0]->{_subscription}->get('subscriptionId');
}
#-------------------------------------------------------------------
sub isRecurring {
return 1;
}
#-------------------------------------------------------------------
sub name {
return $_[0]->{_subscription}->get('name');
}
#-------------------------------------------------------------------
=head2 new ( $session , $subscriptionId, $type )
Overload default constructor to glue in a WebGUI::Subscription object.
=cut
sub new {
my ($class, $session, $subscriptionId, $type, $subscription);
$class = shift;
$session = shift;
$subscriptionId = shift;
$type = shift;
$subscription = WebGUI::Subscription->new($session,$subscriptionId);
bless {_session => $session, _subscription => $subscription, _subscriptionId => $subscriptionId}, $class;
}
#-------------------------------------------------------------------
sub price {
return $_[0]->{_subscription}->get('price');
}
#-------------------------------------------------------------------
sub useSalesTax {
my $self = shift;
return $self->{_subscription}->get('useSalesTax') ? 1 : 0;
}
#-------------------------------------------------------------------
sub type {
return 'Subscription';
}
1;

View file

@ -1,637 +0,0 @@
package WebGUI::Commerce::Payment;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use WebGUI::SQL;
use WebGUI::International;
use Tie::IxHash;
use WebGUI::HTMLForm;
=head1 NAME
Package WebGUI::Commerce::Payment
=head1 DESCRIPTION
An abstract class for all payment plugins to extend.
=head1 SYNOPSIS
use WebGUI::CommercePayment;
our @ISA = qw(WebGUI::Commerce::Payment);
Invoking goes as follows:
$plugin = WebGUI::Commerce::Payment->init($session,'MyPlugin');
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 cancelRecurringPayment ( data )
This method takes care of canceling a recurring transaction. You must override this
method if your plugin can handle recurring payments.
=head3 data
A hashref containing:
id => the gateway ID of the transaction,
transaction => the instantiated WebGUI::Commerce::Transaction object
=cut
sub cancelRecurringPayment {
return "";
}
#-------------------------------------------------------------------
=head2 checkoutForm ( )
This must return a printRowsOnly'ed WebGUI::HTMLForm containing the fields for the checkout
dat you want to collect. Do not include submit buttons. You probably want to override this
method.
=cut
sub checkoutForm {
return "";
}
#-------------------------------------------------------------------
=head2 configurationForm ( )
This generates the configuration form that's displayed in the admin console. You must
extend this method to include parameters specific to this payment module. To do so return
the SUPER::configurationForm method with a printRowsOnly'ed WebGUI::HTMLForm as the argument.
Also be sure to prepend all formfield names with the prepend method. See propend for more info.
=cut
sub configurationForm {
my ($self, $form, $f);
$self = shift;
$form = shift;
$f = WebGUI::HTMLForm->new($self->session);
my $i18n = WebGUI::International->new($self->session, 'Commerce');
$f->text(
-name => $self->prepend('label'),
-value => $self->label,
-label => $i18n->get('label'),
-hoverHelp => $i18n->get('label hoverhelp'),
);
$f->yesNo(
-name => $self->prepend('enabled'),
-value => $self->enabled,
-label => $i18n->get('enable'),
);
$f->group(
-name => $self->prepend('whoCanUse'),
-value => [$self->get('whoCanUse')],
-label => 'Who Can Use?',
-hoverHelp => 'Members belonging to this group will see this payment gateway as a choice at the payment gateway selection screen during checkout.'
);
$f->raw($form);
return $f->printRowsOnly;
}
#-------------------------------------------------------------------
=head2 confirmRecurringTransaction ( )
This method is called if your gateway signals you (ie. posts data to some URL) to confirm a
recurring payment term has been processed. If this is the case, you probably want to store
the result in some table so it can be processed by the Schedualer plugin through the
getRecurringPaymentStatus method.
You only need to override this method if your gateway uses a webbased contacting scheme.
=cut
sub confirmRecurringTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 confirmTransaction ( )
This method is called when your gateway contacts a specific URL to notify you of the result of a
transaction. You should override this method only if your gateway uses this kind of notification
(ie. like PayPal APN). Returns a boolean indicating whether the transaction was successful or not.
=cut
sub confirmTransaction {
return 0;
}
#-------------------------------------------------------------------
=head2 connectionError ( )
Returns an error message if there was a connection error. You must override this method.
=cut
sub connectionError {
return "The connetionError method must be overridden.";
}
#-------------------------------------------------------------------
=head2 enabled ( )
Returns a boolean indicating whether the plugin is enabled or not.
=cut
sub enabled {
return $_[0]->{_enabled};
}
#-------------------------------------------------------------------
=head2 get ( property )
Returns property of the plugin.
=head3 property
The name of the property you want.
=cut
sub get {
return $_[0]->{_properties}{$_[1]};
}
#-------------------------------------------------------------------
=head2 getEnabledPlugins ( )
Returns a reference to an array of all enabled instantiated payment plugins.
=cut
sub getEnabledPlugins {
#my ($session) = @_;
my $class = shift;
my $session = shift;
my (@enabledPlugins, $plugin, @plugins);
@enabledPlugins = $session->db->buildArray("select namespace from commerceSettings where type='Payment' and fieldName='enabled' and fieldValue='1'");
foreach (@enabledPlugins) {
$plugin = WebGUI::Commerce::Payment->load($session, $_);
push(@plugins, $plugin) if ($plugin);
}
return \@plugins;
}
#-------------------------------------------------------------------
=head2 init ( session, namespace )
Constructor for the plugin. You should extend this method.
=head3 session
A copy of the session object
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $session, $namespace, $properties);
$class = shift;
$session = shift;
$namespace = shift;
$properties = $session->db->buildHashRef("select fieldName, fieldValue from commerceSettings where namespace=".$session->db->quote($namespace)." and type='Payment'");
bless {_session=>$session, _properties=>$properties, _namespace=>$namespace, _enabled=>$properties->{enabled}}, $class;
}
#-------------------------------------------------------------------
=head2 gatewayId ( )
Returns the gatewayId of the transaction. You must override this method.
=cut
sub gatewayId {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the gatewayId method in your Payment plugin.");
}
#-------------------------------------------------------------------
=head2 getRecurringPaymentStatus ( recurringId, term )
This should return a hashref containing the payment status of the specified term. If
the term has not been processed yet this method should return undef. Override only if
your plugin is capable of recurring transactions.
The hashref should contain:
resultCode => the result of the payment
=head3 recurringId
The ID the gateway has assigned to the recurring transaction.
=head3 term
The term number you want the status of.
=cut
sub getRecurringPaymentStatus {
return undef;
}
#-------------------------------------------------------------------
=head2 errorCode ( )
Returns the error code of the last submission.
=cut
sub errorCode {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override thie errorCode method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 label ( )
Returns the label for the commerce plugin.
=cut
sub label {
my $self = shift;
return $self->get("label") || $self->namespace;
}
#-------------------------------------------------------------------
=head2 load ( namespace )
A convienient method to load a plugin. It handles all error checking and stuff for you.
This is a SUPER class method only and shoud NOT be overridden.
=head3 session
The session variable.
=head3 namespace
The namespace of the plugin.
=cut
sub load {
my ($class, $namespace, $load, $cmd, $plugin);
$class = shift;
my $session = shift;
$namespace = shift;
$cmd = "WebGUI::Commerce::Payment::$namespace";
$load = "use $cmd";
eval($load);
$session->errorHandler->warn("Payment plugin failed to compile: $cmd.".$@) if($@);
$plugin = eval($cmd.'->init($session)');
$session->errorHandler->warn("Couldn't instantiate payment plugin: $cmd.".$@) if($@);
return $plugin;
}
#-------------------------------------------------------------------
=head2 name
Returns the (display) name of the plugin. You must override this method.
=cut
sub name {
my ($session) = @_;
return $session->errorHandler->fatal("You must override the name method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 namespace ( )
Returns the namespace of the plugin.
=cut
sub namespace {
return $_[0]->{_namespace};
}
#-------------------------------------------------------------------
=head2 normalTransaction ( transactionData )
This method submits a normal (non-recurring) transaction to the payment gateway. You probably
should override this method.
=head3 transactionData
A hashref containing:
amount => the total amount of the transaction
description => the transaction description
invoiceNumber => the invoice number of the transaction
id => the webgui transaction ID
=cut
sub normalTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 recurringTransaction ( transactionData )
This method submits a recurring transaction to the payment gateway. You must override
this method if your plugin supports recurring payments.
=head3 transactionData
A hashref containing:
amount => the total amount of the transaction,
term => the number of terms of the subscription should last.
If none is given your plugin should use an infinite number of terms,
payPeriod => the billing interval,
description => the transaction description,
invoiceNumber => the invoice number of the transaction,
id => the webgui transaction ID,
=cut
sub recurringTransaction {
return undef;
}
#-------------------------------------------------------------------
=head2 resultCode ( )
Returns the result code of the transaction. You must override this method.
=cut
sub resultCode {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the resultCode method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 resultMessage ( )
Returns the result message of the transaction. You must override this method.
=cut
sub resultMessage {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the resultMessage method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 prepend ( fieldName )
A utility method that prepends fieldName with a string that's used to save configuration data to
the database. Use it on all fields in the configurationForm method.
For instance:
$f = WebGUI::HTMLForm->new($self->session);
$f->text(
-name => $self->prepend('MyField');
-label => 'MyField'
);
=head3 fieldName
The string to prepend.
=cut
sub prepend {
my ($self, $name);
$self = shift;
$name = shift;
return "Payment_".$self->namespace."_".$name;
}
#-------------------------------------------------------------------
=head2 recurringPeriodValues ( period )
A utility method that returns the internationalized name for period.
=head3 period
The period you want the name for.
=cut
sub recurringPeriodValues {
my $class = shift;
my $session = shift;
my ($i18n, %periods);
$i18n = WebGUI::International->new($session, 'Commerce');
tie %periods, "Tie::IxHash";
%periods = (
Weekly => $i18n->get('weekly'),
BiWeekly => $i18n->get('biweekly'),
FourWeekly => $i18n->get('fourweekly'),
Monthly => $i18n->get('monthly'),
Quarterly => $i18n->get('quarterly'),
HalfYearly => $i18n->get('halfyearly'),
Yearly => $i18n->get('yearly'),
);
return \%periods;
}
#-------------------------------------------------------------------
=head2 session ( )
Returns the local copy of the session variable
=cut
sub session {
my ($self) = @_;
return $self->{_session};
}
##-------------------------------------------------------------------
=head2 shippingCost ( amount )
This sets the shippingcost involved with the transaction. Your plugin must override this
method.
=head3 amount
The amaount of money that's being charged for shipping.
=cut
sub shippingCost {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the shippingCost method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 shippingDescription ( message )
This method sets the description for the shipping cost of the transaction. You must overload
this method if you are writing a custom plugin.
=head3 message
The description of the shiping cost.
=cut
sub shippingDescription {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the shippingDescription method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 supports ( )
Returns a hashref containg the types of payment the plugin supports. The hashref may contain:
single => 1 if the plugin supports normal transactions,
recurring => 1 if the plugin supports recurring transactions
You must override this method.
=cut
sub supports {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the supports method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionCompleted ( )
A boolean indicating whether the payment has been finished or not. You must override this method.
=cut
sub transactionCompleted {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the transactionCompleted method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionError ( )
Returns an error message if a transaction error has occurred. You must override this method.
=cut
sub transactionError {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the transactionError method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 transactionPending ( )
A boolean indicating whether the payment is pending or not. You must override this method.
=cut
sub transactionPending {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the transactionPending method in the payment plugin.");
}
#-------------------------------------------------------------------
=head2 validateFormData ( )
This method checks the data entered in the checkoutForm. If an error has occurred this method must
return an arrayref containing the errormessages tied to the errors. If everything's ok it will return
undef. You must override this method.
=cut
sub validateFormData {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the validateFormData method in the payment plugin.");
}
=head2 logExtraTransactionData ( $transaction )
This method puts extra, Payment plugin specific data into the transaction log. This
needs to be be overridden to actually do the logging.
=head3 $transaction
A WebGUI::Commerce::Transaction object to do the logging.
=cut
sub logExtraTransactionData {
return 1;
}
1;

View file

@ -1,319 +0,0 @@
package WebGUI::Commerce::Payment::Cash;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Payment::Cash
=head1 DESCRIPTION
Payment plug-in for cash transactions.
=cut
use strict;
use WebGUI::HTMLForm;
use WebGUI::Commerce::Payment;
use WebGUI::Commerce::Item;
use Tie::IxHash;
use WebGUI::International;
use WebGUI::SQL;
our @ISA = qw(WebGUI::Commerce::Payment);
#-------------------------------------------------------------------
sub connectionError {
return undef;
}
#-------------------------------------------------------------------
sub checkoutForm {
my ($self, $u, $f, %months, %years, $i18n);
$self = shift;
$i18n = $self->i18n;
$u = WebGUI::User->new($self->session,$self->session->user->userId);
$f = WebGUI::HTMLForm->new($self->session);
$f->readOnly(
-label=>$i18n->get("payment method"),
-value=>ucfirst($self->getPaymentMethod),
);
$f->text(
-name => 'firstName',
-label => $i18n->get('firstName'),
-value => $self->session->form->process("firstName") || $u->profileField('firstName')
);
$f->text(
-name => 'lastName',
-label => $i18n->get('lastName'),
-value => $self->session->form->process("lastName") || $u->profileField('lastName')
);
$f->text(
-name => 'address',
-label => $i18n->get('address'),
-value => $self->session->form->process("address") || $u->profileField('homeAddress')
);
$f->text(
-name => 'city',
-label => $i18n->get('city'),
-value => $self->session->form->process("city") || $u->profileField('homeCity')
);
$f->text(
-name => 'state',
-label => $i18n->get('state'),
-value => $self->session->form->process("state") || $u->profileField('homeState')
);
$f->zipcode(
-name => 'zipcode',
-label => $i18n->get('zipcode'),
-value => $self->session->form->process("zipcode") || $u->profileField('homeZip')
);
$f->country(
-name=>"country",
-label=>$i18n->get("country"),
-value=>($self->session->form->process("country",'country') || $u->profileField("homeCountry") || 'United States')
);
$f->phone(
-name=>"phone",
-label=>$i18n->get("phone"),
-defaultValue=>$u->profileField("homePhone"),
-value=>$self->session->form->process("phone",'phone'),
);
$f->email(
-name => 'email',
-label => $i18n->get('email'),
-value => $self->session->form->process("email",'email') || $u->profileField('email')
);
return $f->printRowsOnly;
}
#-------------------------------------------------------------------
sub configurationForm {
my ($self, $f, $i18n);
$self = shift;
$i18n = $self->i18n;
$f = WebGUI::HTMLForm->new($self->session);
$f->textarea(
-name => $self->prepend('emailMessage'),
-label => $i18n->get('emailMessage'),
-value => $self->get('emailMessage')
);
$f->yesNo(
-name => $self->prepend('completeTransaction'),
-value => ($self->get('completeTransaction') eq "0" ? 0 : $self->get('completeTransaction') || 1),
-label => $i18n->get('complete transaction'),
-hoverHelp => $i18n->get('complete transaction description'),
);
return $self->SUPER::configurationForm($f->printRowsOnly);
}
#-------------------------------------------------------------------
sub confirmTransaction {
return 0;
}
#-------------------------------------------------------------------
sub i18n {
my $self = shift;
unless (exists $self->{_i18n}) {
$self->{_i18n} = WebGUI::International->new($self->session,'CommercePaymentCash');
}
return $self->{_i18n};
}
#-------------------------------------------------------------------
=head2 init ( namespace )
Constructor for the Cash plugin.
=head3 session
A copy of the session object
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
my $namespace = shift || 'Cash';
$self = $class->SUPER::init($session,$namespace);
return $self;
}
#-------------------------------------------------------------------
sub gatewayId {
my $self = shift;
return $self->getPaymentMethod.":".$self->session->id->generate;
}
#-------------------------------------------------------------------
sub getPaymentMethod {
my $self = shift;
unless($self->{_paymentMethod}) {
$self->{_paymentMethod} = "cash";
}
return $self->{_paymentMethod};
}
#-------------------------------------------------------------------
sub errorCode {
my $self = shift;
return $self->{_error}->{code};
}
#-------------------------------------------------------------------
=head2 label ( )
Returns the label for the commerce plugin.
=cut
sub label {
my $self = shift;
my $i18n = $self->i18n;
return $self->get("label") || $i18n->get("label");
}
#-------------------------------------------------------------------
sub name {
return 'Cash';
}
#-------------------------------------------------------------------
sub namespace {
my $self = shift;
return $self->{_namespace};
}
#-------------------------------------------------------------------
sub normalTransaction {
my ($self, $normal);
$self = shift;
$normal = shift;
if ($normal) {
my $i18n = $self->i18n;
$self->{_transactionParams} = {
AMT => sprintf('%.2f', $normal->{amount}),
DESCRIPTION => $normal->{description} || $i18n->get('no description'),
INVOICENUMBER => $normal->{invoiceNumber},
ORGID => $normal->{id},
};
}
if ($self->get('completeTransaction')) {
$self->{_transaction}->{status} = 'complete';
}
else {
$self->{_transaction}->{status} = 'pending';
$self->{_error}->{message} = 'Your transaction will be completed upon receipt of payment.';
$self->{_error}->{code} = 1;
}
}
#-------------------------------------------------------------------
sub shippingCost {
my $self = shift;
$self->{_shipping}->{cost} = shift;
}
#-------------------------------------------------------------------
sub shippingDescription {
my $self = shift;
$self->{_shipping}->{description} = shift;
}
#-------------------------------------------------------------------
sub supports {
return {
single => 1,
recurring => 0,
}
}
#-------------------------------------------------------------------
sub transactionCompleted {
my $self = shift;
return 1 if $self->{_transaction}->{status} eq 'complete';
}
#-------------------------------------------------------------------
sub transactionError {
my $self = shift;
return $self->{_error}->{message};
}
#-------------------------------------------------------------------
sub transactionPending {
my $self = shift;
return 1 if $self->{_transaction}->{status} eq 'pending';
}
#-------------------------------------------------------------------
sub validateFormData {
my ($self, @error, $i18n, $currentYear, $currentMonth);
$self = shift;
$i18n = $self->i18n;
push (@error, $i18n->get('invalid firstName')) unless ($self->session->form->process("firstName"));
push (@error, $i18n->get('invalid lastName')) unless ($self->session->form->process("lastName"));
push (@error, $i18n->get('invalid address')) unless ($self->session->form->process("address"));
push (@error, $i18n->get('invalid city')) unless ($self->session->form->process("city"));
push (@error, $i18n->get('invalid zip')) if ($self->session->form->process("zipcode") eq "" && $self->session->form->process("country") eq "United States");
push (@error, $i18n->get('invalid email')) unless ($self->session->form->process("email"));
unless (@error) {
$self->{_paymentData} = {
PAYMENTMETHOD => $self->getPaymentMethod,
#$self->session->form->process("paymentMethod"),
};
$self->{_userData} = {
STREET => $self->session->form->process("address"),
ZIP => $self->session->form->process("zipcode"),
CITY => $self->session->form->process("city"),
FIRSTNAME => $self->session->form->process("firstName"),
LASTNAME => $self->session->form->process("lastName"),
EMAIL => $self->session->form->process("email"),
STATE => $self->session->form->process("state"),
COUNTRY => $self->session->form->process("country"),
PHONE => $self->session->form->process("phone"),
};
return 0;
}
return \@error;
}
1;

View file

@ -1,84 +0,0 @@
package WebGUI::Commerce::Payment::Check;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Payment::Check
=head1 DESCRIPTION
Payment plug-in for check transactions.
=cut
use strict;
use WebGUI::HTMLForm;
use WebGUI::Commerce::Payment;
use WebGUI::Commerce::Item;
use Tie::IxHash;
use WebGUI::International;
use WebGUI::SQL;
use base 'WebGUI::Commerce::Payment::Cash';
#-------------------------------------------------------------------
sub getPaymentMethod {
my $self = shift;
unless($self->{_paymentMethod}) {
$self->{_paymentMethod} = "check";
}
return $self->{_paymentMethod};
}
#-------------------------------------------------------------------
sub i18n {
my $self = shift;
unless (exists $self->{_i18n}) {
$self->{_i18n} = WebGUI::International->new($self->session,'CommercePaymentCheck');
}
return $self->{_i18n};
}
#-------------------------------------------------------------------
=head2 init ( namespace )
Constructor for the Check plugin.
=head3 session
A copy of the session object
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
my $namespace = shift || 'Check';
$self = $class->SUPER::init($session,$namespace);
return $self;
}
#-------------------------------------------------------------------
sub name {
return 'Check';
}
1;

View file

@ -1,703 +0,0 @@
package WebGUI::Commerce::Payment::ITransact;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Payment::ITransact
=head1 DESCRIPTION
Payment plug-in for ITransact payment gateway.
=cut
use strict;
use WebGUI::HTMLForm;
use WebGUI::Commerce::Payment;
use WebGUI::Commerce::Item;
use Tie::IxHash;
use WebGUI::International;
use LWP::UserAgent;
use XML::Simple;
use HTML::Entities qw(encode_entities_numeric);
use HTTP::Cookies;
use WebGUI::SQL;
our @ISA = qw(WebGUI::Commerce::Payment);
#-------------------------------------------------------------------
sub _resolveRecipe {
my %resolve = (
Weekly => 'weekly',
BiWeekly => 'biweekly',
FourWeekly => 'fourweekly',
Monthly => 'monthly',
Quarterly => 'quarterly',
HalfYearly => 'halfyearly',
Yearly => 'yearly',
);
return $resolve{$_[0]};
}
#-------------------------------------------------------------------
sub cancelRecurringPayment {
my ($self, $recurring, $userAgent, $request, $response);
$self = shift;
$recurring = shift;
if ($recurring) {
$self->{_recurring} = 1;
my $itemProperties = $recurring->{transaction}->getItems->[0];
my $item = WebGUI::Commerce::Item->new($self->session,$itemProperties->{itemId}, $itemProperties->{itemType});
my $recipe = _resolveRecipe($item->duration);
# Set up a user agent that uses cookies and allows POST redirects
$userAgent = LWP::UserAgent->new;
$userAgent->env_proxy;
$userAgent->agent("Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0");
push @{ $userAgent->requests_redirectable }, 'POST';
$userAgent->cookie_jar({});
# Login to iTransact
$request = HTTP::Request->new(POST => 'https://secure.paymentclearing.com/cgi-bin/rc/sess.cgi');
$request->content_type('application/x-www-form-urlencoded');
$request->content('mid='.$self->get('vendorId').';pwd='.$self->get('password').';cookie_precheck=0');
$response = $userAgent->request($request);
# Check the outcome of the response
if ($response->is_success) {
# print "FIRST PAGE SUCCESS!\n";
# print "(".$response->base.")\n";
} else {
$self->session->errorHandler->fatalError(
'Connection Error while trying to cancel transaction '.$recurring->{transaction}->transactionId." \n".
"Could not reach login page.\n".
"(".$response->base.")\n".
$response->status_line. "\n");
}
# Post cancelation
my $request = HTTP::Request->new(POST => 'https://secure.paymentclearing.com/cgi-bin/rc/recur/update/update.cgi');
$request->content_type('application/x-www-form-urlencoded');
$request->content(
'reps=0;'. # Set number of remaining repetition to zero in order to cancel
'recipe_code='.$recipe.';'.
'xid='.$recurring->{id});
my $response = $userAgent->request($request);
# Check the outcome of the response
if ($response->is_success) {
# print "CANCELATION PAGE SUCCESS!\n";
# print "(".$response->base.")\n";
} else {
$self->session->errorHandler->fatalError(
'Connection Error while trying to cancel transaction '.$recurring->{transaction}->transactionId." \n".
"(".$response->base.")\n".
$response->status_line. "\n");
}
}
}
#-------------------------------------------------------------------
sub connectionError {
my ($self, $resultCode);
$self = shift;
return $self->resultMessage if ($self->{_connectionError});
return undef;
}
#-------------------------------------------------------------------
sub checkoutForm {
my ($self, $u, $f, %months, %years, $i18n);
$self = shift;
$i18n = WebGUI::International->new($self->session, 'CommercePaymentITransact');
$u = WebGUI::User->new($self->session,$self->session->user->userId);
$f = WebGUI::HTMLForm->new($self->session);
$f->text(
-name => 'firstName',
-label => $i18n->get('firstName'),
-value => $self->session->form->process("firstName") || $u->profileField('firstName')
);
$f->text(
-name => 'lastName',
-label => $i18n->get('lastName'),
-value => $self->session->form->process("lastName") || $u->profileField('lastName')
);
$f->text(
-name => 'address',
-label => $i18n->get('address'),
-value => $self->session->form->process("address") || $u->profileField('homeAddress')
);
$f->text(
-name => 'city',
-label => $i18n->get('city'),
-value => $self->session->form->process("city") || $u->profileField('homeCity')
);
$f->text(
-name => 'state',
-label => $i18n->get('state'),
-value => $self->session->form->process("state") || $u->profileField('homeState')
);
$f->zipcode(
-name => 'zipcode',
-label => $i18n->get('zipcode'),
-value => $self->session->form->process("zipcode") || $u->profileField('homeZip')
);
$f->country(
-name=>"country",
-label=>$i18n->get("country"),
-value=>($self->session->form->process("country",'country') || $u->profileField("homeCountry") || 'United States')
);
$f->phone(
-name=>"phone",
-label=>$i18n->get("phone"),
-defaultValue=>$u->profileField("homePhone"),
-value=>$self->session->form->process("phone",'phone'),
);
$f->email(
-name => 'email',
-label => $i18n->get('email'),
-value => $self->session->form->process("email") || $u->profileField('email')
);
$f->text(
-name => 'cardNumber',
-label => $i18n->get('cardNumber'),
-value => $self->session->form->process("cardNumber")
);
tie %months, "Tie::IxHash";
%months = map {sprintf('%02d',$_) => sprintf('%02d',$_)} 1..12;
tie %years, "Tie::IxHash";
%years = map {$_ => $_} 2004..2099;
$f->readOnly(
-label => $i18n->get('expiration date'),
-value =>
WebGUI::Form::selectBox($self->session,{name => 'expMonth', options => \%months, value => [$self->session->form->process("expMonth")]}).
" / ".
WebGUI::Form::selectBox($self->session,{name => 'expYear', options => \%years, value => [$self->session->form->process("expYear")]})
);
$f->integer(
-name => 'cvv2',
-label => $i18n->get('cvv2'),
-value => $self->session->form->process("cvv2")
) if ($self->get('useCVV2'));
return $f->printRowsOnly;
}
#-------------------------------------------------------------------
sub configurationForm {
my ($self, $f, $i18n);
$self = shift;
$i18n = WebGUI::International->new($self->session, 'CommercePaymentITransact');
$f = WebGUI::HTMLForm->new($self->session);
$f->text(
-name => $self->prepend('vendorId'),
-label => $i18n->get('vendorId'),
-value => $self->get('vendorId')
);
$f->text(
-name => $self->prepend('password'),
-label => $i18n->get('password'),
-value => $self->get('password')
);
$f->yesNo(
-name => $self->prepend('useCVV2'),
-label => $i18n->get('use cvv2'),
-value => $self->get('useCVV2'),
);
$f->textarea(
-name => $self->prepend('emailMessage'),
-label => $i18n->get('emailMessage'),
-value => $self->get('emailMessage')
);
$f->readOnly(
-value => '<br />'
);
if ($self->get('vendorId')) {
$f->readOnly(
-value => '<a target="_blank" href="https://secure.paymentclearing.com/support/login.html">'.$i18n->get('show terminal').'</a>'
);
}
$f->readOnly(
-value => '<br />'
);
$f->readOnly(
-value => $i18n->get('extra info').'<br /><b>https://'.$self->session->config->get("defaultSitename").'/?op=confirmRecurringTransaction;gateway='.$self->namespace
);
return $self->SUPER::configurationForm($f->printRowsOnly);
}
#-------------------------------------------------------------------
sub confirmRecurringTransaction {
#### !!!Site checken!!! ####
my $self = shift;
my $transaction = WebGUI::Commerce::Transaction->getByGatewayId($self->session->form->process("orig_xid"), $self->namespace);
my $itemProperties = $transaction->getItems->[0];
my $item = WebGUI::Commerce::Item->new($self->session,$itemProperties->{itemId}, $itemProperties->{itemType});
my $startEpoch = $self->session->datetime->setToEpoch(sprintf("%4d-%02d-%02d %02d:%02d:%02d", unpack('a4a2a2a2a2a2', $self->session->form->process("start_date"))));
my $currentEpoch = $self->session->datetime->setToEpoch(sprintf("%4d-%02d-%02d %02d:%02d:%02d", unpack('a4a2a2a2a2a2', $self->session->form->process("when"))));
$self->session->db->write("delete from ITransact_recurringStatus where gatewayId=".$self->session->db->quote($self->session->form->process("orig_xid")));
$self->session->db->write("insert into ITransact_recurringStatus ".
"(gatewayId, initDate, lastTransaction, status, errorMessage, recipe) values ".
"(".$self->session->db->quote($self->session->form->process("orig_xid")).", $startEpoch, $currentEpoch, ".$self->session->db->quote($self->session->form->process("status")).", ".$self->session->db->quote($self->session->form->process("error_message")).
", ".$self->session->db->quote($self->session->form->process("recipe_name")).")");
}
#-------------------------------------------------------------------
sub confirmTransaction {
# This function should never be called with site side payment gateways!
return 0;
}
#-------------------------------------------------------------------
=head2 init ( namespace )
Constructor for the ITransact plugin.
=head3 session
A copy of the session object
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
$self = $class->SUPER::init($session,'ITransact');
return $self;
}
#-------------------------------------------------------------------
sub gatewayId {
my $self = shift;
return $self->{_response}->{XID};
}
#-------------------------------------------------------------------
sub getRecurringPaymentStatus {
my ($self, $term, $recurringId, $response, %paymentHistory);
$self = shift;
$recurringId = shift;
$term = shift || 1;
my %resolve = (
weekly => 7*3600*24,
biweekly => 14*3600*24,
fourweekly => 28*3600*24,
monthly => 30*3600*24,
quarterly => 91*3600*24,
halfyearly => 182*3600*24,
yearly => 365*3600*24
);
my $transactionData = $self->session->db->quickHashRef("select * from ITransact_recurringStatus where gatewayId=".$self->session->db->quote($recurringId));
unless ($transactionData->{recipe}) { # if for some reason there's no transaction data, we shouldn't calc anything
$self->session->errorHandler->error("For some reason recurring transaction $recurringId doesn't have any recurring status transaction data. This is most likely because you don't have the Recurring Postback URL set in your ITransact virtual terminal.");
return undef;
}
my $lastTerm = int(($transactionData->{lastTransaction} - $transactionData->{initDate}) / $resolve{$transactionData->{recipe}}) + 1;
# Process the response
if ($lastTerm > $term) {
$paymentHistory{resultCode} = 0;
} elsif ($lastTerm == $term) {
$paymentHistory{resultCode} = $transactionData->{status}.' '.$transactionData->{errorMessage};
$paymentHistory{resultCode} = 0 if $transactionData->{status} eq 'OK';
} else {
return undef;
}
return \%paymentHistory;
}
#-------------------------------------------------------------------
sub errorCode {
my ($self, $resultCode);
$self = shift;
$resultCode = $self->{_response}->{Status};
return $resultCode unless ($resultCode eq 'OK');
return undef;
}
#-------------------------------------------------------------------
=head2 label ( )
Returns the label for the commerce plugin.
=cut
sub label {
my $self = shift;
my $i18n = WebGUI::International->new($self->session,'CommercePaymentITransact');
return $self->get("label") || $i18n->get("label");
}
#-------------------------------------------------------------------
sub name {
return 'ITransact';
}
#-------------------------------------------------------------------
sub namespace {
my $self = shift;
return $self->{_namespace};
}
#-------------------------------------------------------------------
sub normalTransaction {
my ($self, $normal);
$self = shift;
$normal = shift;
if ($normal) {
my $i18n = WebGUI::International->new($self->session, 'CommercePaymentITransact');
$self->{_recurring} = 0;
$self->{_transactionParams} = {
AMT => sprintf('%.2f', $normal->{amount}),
DESCRIPTION => $self->session->url->escape($normal->{description}) || $i18n->get('no description'),
INVOICENUMBER => $normal->{invoiceNumber},
ORGID => $normal->{id},
};
}
return $self->submit;
}
#-------------------------------------------------------------------
sub recurringTransaction {
my ($self, $recurring, $initialAmount);
$self = shift;
$recurring = shift;
if ($recurring) {
# initial amount = (daysInMonth - dayInMonth) / daysInMonth * amount
$initialAmount = ($self->session->datetime->getDaysInMonth(time) - ($self->session->datetime->localtime)[2])*$recurring->{amount}/$self->session->datetime->getDaysInMonth(time);
$initialAmount = $recurring->{amount} if ($initialAmount < 1);
$self->{_recurring} = 1;
my $i18n = WebGUI::International->new($self->session, 'CommercePaymentITransact');
$self->{_transactionParams} = {
START => $recurring->{start} || $self->session->datetime->epochToHuman($self->session->datetime->addToDate(time, 0, 0, 1), '%m%d%y'),
AMT => sprintf('%.2f', $recurring->{amount}),
INITIALAMT => sprintf('%.2f', $initialAmount),
TERM => $recurring->{term} || 9999,
RECIPE => _resolveRecipe($recurring->{payPeriod}),
DESCRIPTION => $self->session->url->escape($recurring->{description}) || $i18n->get('no description'),
INVOICENUMBER => $recurring->{invoiceNumber},
ORGID => $recurring->{id},
};
}
return $self->submit;
}
#-------------------------------------------------------------------
sub resultCode {
my $self = shift;
return $self->{_response}->{Status};
}
#-------------------------------------------------------------------
sub resultMessage {
my $self = shift;
return $self->{_resultMessage} if ($self->{_connectionError});
return $self->{_response}->{ErrorMessage};
}
#-------------------------------------------------------------------
sub shippingCost {
my $self = shift;
$self->{_shipping}->{cost} = shift;
}
#-------------------------------------------------------------------
sub shippingDescription {
my $self = shift;
$self->{_shipping}->{description} = shift;
}
#-------------------------------------------------------------------
sub submit {
my ($self, $xml, $items);
$self = shift;
my %cardData = %{$self->{_cardData}} if $self->{_cardData};
my %userData = %{$self->{_userData}} if $self->{_userData};
my %transactionData = %{$self->{_transactionParams}};
# Set up the XML.
$xml =
'<?xml version="1.0"?>'.
'<SaleRequest>
<CustomerData>
<Email>'.encode_entities_numeric($userData{EMAIL}).'</Email>
<BillingAddress>
<Address1>'.encode_entities_numeric($userData{STREET}).'</Address1>
<FirstName>'.encode_entities_numeric($userData{FIRSTNAME}).'</FirstName>
<LastName>'.encode_entities_numeric($userData{LASTNAME}).'</LastName>
<City>'.encode_entities_numeric($userData{CITY}).'</City>
<State>'.encode_entities_numeric($userData{STATE}).'</State>
<Zip>'.encode_entities_numeric($userData{ZIP}).'</Zip>
<Country>'.encode_entities_numeric($userData{COUNTRY}).'</Country>
<Phone>'.encode_entities_numeric($userData{PHONE}).'</Phone>
</BillingAddress>
<AccountInfo>
<CardInfo>
<CCNum>'.encode_entities_numeric($cardData{ACCT}).'</CCNum>
<CCMo>'.encode_entities_numeric($cardData{EXPMONTH}).'</CCMo>
<CCYr>'.encode_entities_numeric($cardData{EXPYEAR})."</CCYr>\n";
$xml .= '<CVV2Number>'.encode_entities_numeric($cardData{CVV2})."</CVV2Number>\n" if $self->get('useCVV2');
# <CVV2Illegible>1</CVV2Illegible> <!-- .Submit only if CVV number is illegible. -->
$xml .=
" </CardInfo>
</AccountInfo>
</CustomerData>
<TransactionData>
<VendorId>".encode_entities_numeric($self->get('vendorId'))."</VendorId>
<VendorPassword>".encode_entities_numeric($self->get('password'))."</VendorPassword>
<HomePage>".encode_entities_numeric($self->session->setting->get("companyURL"))."</HomePage>\n";
if ($self->{_recurring}) {
$xml .=
' <RecurringData>
<RecurRecipe>'.encode_entities_numeric($transactionData{RECIPE}).'</RecurRecipe>
<RecurReps>'.encode_entities_numeric($transactionData{TERM}).'</RecurReps>
<RecurTotal>'.encode_entities_numeric($transactionData{AMT}).'</RecurTotal>
<RecurDesc>'.encode_entities_numeric($transactionData{DESCRIPTION})."</RecurDesc>
</RecurringData>\n";
};
$xml .=
' <EmailText>
<EmailTextItem>'.encode_entities_numeric($self->get('emailMessage')).'</EmailTextItem>
<EmailTextItem>ID: '.encode_entities_numeric($transactionData{ORGID})."</EmailTextItem>
</EmailText>
<OrderItems>\n";
$items = WebGUI::Commerce::Transaction->new($self->session, $transactionData{ORGID})->getItems;
foreach (@{$items}) {
my $data = $_->{itemName};
# $data =~ s/&/&amp;/sg;
# $data =~ s/</&lt;/sg;
# $data =~ s/>/&gt;/sg;
# $data =~ s/"/&quot;/sg;
$data =~ tr/A-Za-z0-9 //dc;
my $itemPrice = $_->{amount} / $_->{quantity};
$xml .=
' <Item>
<Description>'.encode_entities_numeric($data).'</Description>
<Cost>'.encode_entities_numeric(sprintf('%.2f', $itemPrice)).'</Cost>
<Qty>'.encode_entities_numeric($_->{quantity})."</Qty>
</Item>\n";
}
if ($self->{_shipping}->{cost}) {
$xml .=
" <Item>
<Description>Shipping cost. ".encode_entities_numeric($self->{_shipping}->{description})."</Description>
<Cost>".encode_entities_numeric(sprintf('%.2f', $self->{_shipping}->{cost}))."</Cost>
<Qty>1</Qty>
</Item>\n";
};
$xml .=
" </OrderItems>
</TransactionData>
</SaleRequest>";
##
## Nice for debugging
##
# open(DAT,">/tmp/itransact.xml") || die("Cannot Open File");
# print DAT "$xml";
# close(DAT);
#
my $xmlTransactionScript = 'https://secure.paymentclearing.com/cgi-bin/rc/xmltrans.cgi';
# Set up LWP to post the XML to iTransact.
my $userAgent = LWP::UserAgent->new;
$userAgent->env_proxy;
$userAgent->agent("WebGUI ");
my $request = HTTP::Request->new(POST => $xmlTransactionScript);
$request->content_type('application/x-www-form-urlencoded');
$request->content('xml='.$xml);
my $response = $userAgent->request($request);
if ($response->is_success) {
# We got some XML back from iTransact, now parse it.
my $xmlParser = XML::Simple->new;
my $transactionResult = $xmlParser->XMLin($response->content);
unless (defined $transactionResult->{TransactionData}) {
# Some error occurred
$self->{_transactionError} = 1;
$self->{_response} = $transactionResult;
$self->{_resultMessage} = $self->{_response}->{ErrorMessage};
} else {
$self->{_response} = $transactionResult->{TransactionData};
}
} else {
# Connection Error
$self->{_connectionError} = 1;
$self->{_resultMessage} = $response->status_line;
}
}
#-------------------------------------------------------------------
sub supports {
return {
single => 1,
recurring => 1,
}
}
#-------------------------------------------------------------------
sub transactionCompleted {
my ($self) = shift;
return ($self->{_response}->{Status} eq 'OK');
}
#-------------------------------------------------------------------
sub transactionError {
my ($self, $resultCode);
$self = shift;
$resultCode = $self->resultCode;
return $self->resultMessage if ($resultCode ne 'OK');
return undef;
}
#-------------------------------------------------------------------
sub transactionPending {
return 0;
}
#-------------------------------------------------------------------
sub validateFormData {
my ($self, @error, $i18n, $currentYear, $currentMonth);
$self = shift;
$i18n = WebGUI::International->new($self->session,'CommercePaymentITransact');
push (@error, $i18n->get('invalid firstName')) unless ($self->session->form->process("firstName"));
push (@error, $i18n->get('invalid lastName')) unless ($self->session->form->process("lastName"));
push (@error, $i18n->get('invalid address')) unless ($self->session->form->process("address"));
push (@error, $i18n->get('invalid city')) unless ($self->session->form->process("city"));
push (@error, $i18n->get('invalid zip')) if ($self->session->form->process("zipcode") eq "" && $self->session->form->process("country") eq "United States");
push (@error, $i18n->get('invalid email')) unless ($self->session->form->process("email"));
push (@error, $i18n->get('invalid card number')) unless ($self->session->form->process("cardNumber") =~ /^\d+$/);
push (@error, $i18n->get('invalid cvv2')) if ($self->session->form->process("cvv2") !~ /^\d+$/ && $self->get('useCVV2'));
($currentYear, $currentMonth) = $self->session->datetime->localtime;
# Check if expDate and expYear have sane values
unless (($self->session->form->process("expMonth") =~ /^(0[1-9]|1[0-2])$/) && ($self->session->form->process("expYear") =~ /^\d\d\d\d$/)) {
push (@error, $i18n->get('invalid expiration date'));
} elsif (($self->session->form->process("expYear") < $currentYear) ||
(($self->session->form->process("expYear") == $currentYear) && ($self->session->form->process("expMonth") < $currentMonth))) {
push (@error, $i18n->get('invalid expiration date'));
}
unless (@error) {
$self->{_cardData} = {
ACCT => $self->session->form->process("cardNumber"),
EXPMONTH => $self->session->form->process("expMonth"),
EXPYEAR => $self->session->form->process("expYear"),
CVV2 => $self->session->form->process("cvv2"),
};
$self->{_userData} = {
STREET => $self->session->form->process("address"),
ZIP => $self->session->form->process("zipcode"),
CITY => $self->session->form->process("city"),
FIRSTNAME => $self->session->form->process("firstName"),
LASTNAME => $self->session->form->process("lastName"),
EMAIL => $self->session->form->process("email"),
STATE => $self->session->form->process("state"),
COUNTRY => $self->session->form->process("country"),
PHONE => $self->session->form->process("phone"),
};
return 0;
}
return \@error;
}
sub logExtraTransactionData {
my ($self, $transaction) = @_;
$self->session->errorHandler->warn('transaction: '.$transaction->{_transactionId});
if ( exists($self->{_connectionError}) && $self->{_connectionError}) { ##Bad connection
$self->session->errorHandler->warn('Connection error');
$transaction->message($self->connectionError);
return;
}
elsif (exists($self->{_transactionError}) && $self->{_transactionError}) { ##Bad transaction
$self->session->errorHandler->warn('Transaction error');
$transaction->message($self->resultMessage);
$transaction->xid($self->{_response}->{XID});
return;
}
else { ##Everything went well
$self->session->errorHandler->warn('OK transaction');
if ($self->{_response}->{Status} eq 'OK') {
$transaction->message($self->{_response}->{Status});
}
else {
$transaction->message($self->resultMessage);
}
$transaction->xid($self->{_response}->{XID});
if (! ref $self->{_response}->{AuthCode} ) {
$transaction->authcode($self->{_response}->{AuthCode});
}
return;
}
}
1;

View file

@ -1,421 +0,0 @@
package WebGUI::Commerce::Shipping;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use WebGUI::SQL;
use WebGUI::HTMLForm;
use WebGUI::Commerce::ShoppingCart;
#-------------------------------------------------------------------
=head2 calc ( )
Returns the calculated shipping cost. Your plugin must override this method.
=cut
sub calc {
return WebGUI::ErrorHanlder::fatal('The calc method must be overriden.');
};
#-------------------------------------------------------------------
=head2 description ( )
Returns a description of the shipping configuration. Defaults to the name of your plugin
if you do not overload this method.
=cut
sub description {
return $_[0]->name;
}
#-------------------------------------------------------------------
=head2 configurationForm ( )
This generates the configuration form that's displayed in the admin console. You must
extend this method to include parameters specific to this payment module. To do so return
the SUPER::configurationForm method with a printRowsOnly'ed WebGUI::HTMLForm as the argument.
Also be sure to prepend all formfield names with the prepend method. See propend for more info.
=cut
sub configurationForm {
my ($self, $form, $f);
$self = shift;
$form = shift;
$f = WebGUI::HTMLForm->new($self->session);
my $i18n = WebGUI::International->new($self->session, 'Commerce');
$f->yesNo(
-name => $self->prepend('enabled'),
-value => $self->enabled,
-label => $i18n->get('enable'),
);
$f->raw($form);
return $f->printRowsOnly;
}
#-------------------------------------------------------------------
=head2 enabled ( )
Returns a boolean indicating whether the plugin is enabled or not.
=cut
sub enabled {
return $_[0]->{_enabled};
}
#-------------------------------------------------------------------
=head2 get ( property )
Returns property of the plugin.
=head3 property
The name of the property you want.
=cut
sub get {
return $_[0]->{_properties}{$_[1]};
}
#-------------------------------------------------------------------
=head2 getOptions ( )
Returns a hash containing the parameters of a user configurable shipping method. If
your shipping plugin has an options form you should overload this method.
=cut
sub getOptions {
return {};
}
#-------------------------------------------------------------------
=head2 getShippingItems ( )
Returns an arrayref containing the items, marked for shipping. If no items are set
using setShippingOptions it this method will default to the shopping cart of the user.
=cut
sub getShippingItems {
my ($normal, $recurring, @allItems, @items, $self);
$self = shift;
@allItems = @{$self->{_shippingItems}};
unless (@allItems) {
($normal, $recurring) = $self->getShoppingCart->getItems;
@allItems = (@$normal, @$recurring);
}
foreach (@allItems) {
push(@items, $_) if $_->{item}->needsShipping;
}
return [ @items ];
}
#-------------------------------------------------------------------
=head2 getEnabledPlugins ( )
Returns a reference to an array of all enabled instantiated payment plugins.
=cut
sub getEnabledPlugins {
my $class = shift;
my $session = shift;
my (@enabledPlugins, $plugin, @plugins);
@enabledPlugins = $session->db->buildArray("select namespace from commerceSettings where type='Shipping' and fieldName='enabled' and fieldValue='1'");
foreach (@enabledPlugins) {
$plugin = WebGUI::Commerce::Shipping->load($session, $_);
push(@plugins, $plugin) if ($plugin);
}
return \@plugins;
}
#-------------------------------------------------------------------
=head2 init ( namespace )
Constructor for the plugin. You should extend this method.
=head3 namespace
The namespace of the plugin.
=cut
sub init {
my ($class, $session, $namespace, $properties, $shoppingCart);
$class = shift;
$session = shift;
$namespace = shift;
$session->errorHandler->fatal('No namespace passed to init.') unless ($namespace);
$properties = $session->db->buildHashRef("select fieldName, fieldValue from commerceSettings where namespace=".$session->db->quote($namespace)." and type='Shipping'");
$shoppingCart = WebGUI::Commerce::ShoppingCart->new($session);
bless {_properties=>$properties,
_shippingParameters => {},
_shoppingCart => $shoppingCart,
_namespace=>$namespace,
_session=>$session,
_enabled=>$properties->{enabled},
_shippingItems => []}, $class;
}
#-------------------------------------------------------------------
=head2 getShoppingCart ( )
Returns a WebGUI::Commerce::ShoppingCart object of the current user.
=cut
sub getShoppingCart {
return $_[0]->{_shoppingCart};
};
#-------------------------------------------------------------------
=head2 load ( namespace )
A convienient method to load a plugin. It handles all error checking and stuff for you.
This is a SUPER class method only and should NOT be overridden.
=head3 namespace
The namespace of the plugin.
=cut
sub load {
my ($class, $namespace, $load, $cmd, $plugin);
$class = shift;
my $session = shift;
$namespace = shift;
$session->errorHandler->fatal('No namespace passed to load.') unless ($namespace);
$cmd = "WebGUI::Commerce::Shipping::$namespace";
$load = "use $cmd";
eval($load);
$session->errorHandler->warn("Shipping plugin failed to compile: $cmd.".$@) if($@);
$plugin = eval($cmd.'->init($session)');
$session->errorHandler->warn("Couldn't instantiate shipping plugin: $cmd.".$@) if($@);
return $plugin;
}
#-------------------------------------------------------------------
=head2 name ( )
Returns the (display) name of the plugin. You must override this method.
=cut
sub name {
my ($self) = @_;
return $self->session->errorHandler->fatal("You must override the name method in the shipping plugin.");
}
#-------------------------------------------------------------------
=head2 namespace ( )
Returns the namespace of the plugin.
=cut
sub namespace {
return $_[0]->{_namespace};
}
#-------------------------------------------------------------------
=head2 optionsOk ( )
Indicates whether the options loaded into the plugin (by using either setOptions or processOptionsForm)
are correct. If your plugin is able of being configured by an options form you must overload this method.
Defaults to true.
=cut
sub optionsOk {
return 1;
}
#-------------------------------------------------------------------
=head2 prepend ( fieldName )
A utility method that prepends fieldName with a string that's used to save configuration data to
the database. Use it on all fields in the configurationForm method.
For instance:
$f = WebGUI::HTMLForm->new($self->session);
$f->text(
-name => $self->prepend('MyField');
-label => 'MyField'
);
=head3 fieldName
The string to prepend.
=cut
sub prepend {
my ($self, $name);
$self = shift;
$name = shift;
return "Shipping_".$self->namespace."_".$name;
}
#-------------------------------------------------------------------
=head2 processOptionsForm ( )
Processes the submitted form variables from the optionsForm and stores them
into the plugin. You only need to overload this method if your plugin is capable
of using user configurable options.
=cut
sub processOptionsForm {
}
#-------------------------------------------------------------------
=head2 session ( )
Returns the cached, local session variable.
=cut
sub session {
my ($self) = @_;
return $self->{_session};
}
#-------------------------------------------------------------------
=head2 setOptions ( options )
Stores the supplied option hash into the plugin object.
=head3 options
Hashref containing the options.
=cut
sub setOptions {
}
#-------------------------------------------------------------------
=head2 setShippingItems ( items )
Sets the items the shipping is to be calculated for.
=head3 items
Arrayref containing the items.
=cut
sub setShippingItems {
my ($self, $items);
$self = shift;
$items = shift;
$self->{_shippingItems} = $items;
}
#-------------------------------------------------------------------
=head2 supportsTracking ( )
Returns a boolean indicating whether this plugin supports tracking of the shipment.
Overload this method if your plugin does. Defaults to false.
=cut
sub supportsTracking {
return 0;
}
#-------------------------------------------------------------------
=head2 trackingInfo ( )
Returns a message containing information about the shipment tracking (ie. where the
package is or something like that). If your plugin support these tracking, you probably
want to overload this method. Defaults to "".
=cut
sub trackingInfo {
return "";
}
#-------------------------------------------------------------------
=head2 trackingNumber ( )
Returns the tracking ID supplied by the shipment company. If your plugin supports tracking
you'll have to overload this method. Defaults to undef.
=cut
sub trackingNumber {
return undef;
}
#-------------------------------------------------------------------
=head2 trackingUrl ( )
Returns the URL where the user can go to either fill in the tracking number or view the tracking
info of his package. Overload this method if your plugin supports tracking. Defaults to undef.
=cut
sub trackingUrl {
return undef;
}
1;

View file

@ -1,98 +0,0 @@
package WebGUI::Commerce::Shipping::ByPrice;
use strict;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Shipping::ByPrice
=head1 DESCRIPTION
Shipping plugin for determining shipping cost by a percentage of total price.
=cut
our @ISA = qw(WebGUI::Commerce::Shipping);
#-------------------------------------------------------------------
=head2 calc ( $session )
Calculate the shipping price for this plugin.
=cut
sub calc {
my ($self, $items, $price);
$self = shift;
$items = $self->getShippingItems;
foreach (@$items) {
$price += $_->{totalPrice};
}
return $price * $self->get('percentageOfPrice') / 100;
};
#-------------------------------------------------------------------
=head2 configurationForm ( $session )
Configuration form for this shipping method.
=cut
sub configurationForm {
my ($self, $f);
$self = shift;
$f = WebGUI::HTMLForm->new($self->session);
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingByPrice');
$f->float(
-name => $self->prepend('percentageOfPrice'),
-label => $i18n->get('percentage of price'),
-value => $self->get('percentageOfPrice')
);
return $self->SUPER::configurationForm($f->printRowsOnly);
}
#-------------------------------------------------------------------
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
$self = $class->SUPER::init($session,'ByPrice');
return $self;
}
#-------------------------------------------------------------------
=head2 name ( $session )
Returns the internationalized name for this shipping plugin.
=cut
sub name {
my ($self) = @_;
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingByPrice');
return $i18n->get('title');
}
1;

View file

@ -1,106 +0,0 @@
package WebGUI::Commerce::Shipping::ByWeight;
use strict;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item::ByWeight
=head1 DESCRIPTION
Shipping plugin for determining shipping cost as a function of the total weight
or products being purchased.
=cut
our @ISA = qw(WebGUI::Commerce::Shipping);
#-------------------------------------------------------------------
=head2 calc ( $session )
Calculate the shipping price for this plugin.
=cut
sub calc {
my ($self, $items, $weight);
$self = shift;
$items = $self->getShippingItems;
foreach (@$items) {
$weight += $_->{item}->weight * $_->{quantity};
}
return $weight * $self->get('pricePerUnitWeight');
};
#-------------------------------------------------------------------
=head2 configurationForm ( $session )
Configuration form for this shipping method.
=cut
sub configurationForm {
my ($self, $f);
$self = shift;
$f = WebGUI::HTMLForm->new($self->session);
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingByWeight');
$f->float(
-name => $self->prepend('pricePerUnitWeight'),
-label => $i18n->get('price per weight'),
-value => $self->get('pricePerUnitWeight')
);
return $self->SUPER::configurationForm($f->printRowsOnly);
}
#-------------------------------------------------------------------
=head2 init ( $session )
Constructor
=cut
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
$self = $class->SUPER::init($session,'ByWeight');
return $self;
}
#-------------------------------------------------------------------
=head2 name ( $session )
Returns the internationalized name for this shipping plugin.
=cut
sub name {
my $self = shift;
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingByWeight');
return $i18n->get('title');
}
1;

View file

@ -1,101 +0,0 @@
package WebGUI::Commerce::Shipping::PerTransaction;
use strict;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Commerce::Item::PerTransaction
=head1 DESCRIPTION
Shipping plugin for a fixed shipping costs per transaction.
=cut
our @ISA = qw(WebGUI::Commerce::Shipping);
#-------------------------------------------------------------------
=head2 calc ( $self )
Calculate the shipping price for this plugin.
=cut
sub calc {
my ($self);
$self = shift;
return 0 unless (scalar(@{$self->getShippingItems}));
return $self->get('pricePerTransaction');
};
#-------------------------------------------------------------------
=head2 configurationForm ( $self )
Configuration form for this shipping method.
=cut
sub configurationForm {
my ($self, $f);
$self = shift;
$f = WebGUI::HTMLForm->new($self->session);
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingPerTransaction');
$f->float(
-name => $self->prepend('pricePerTransaction'),
-label => $i18n->get('price'),
-value => $self->get('pricePerTransaction')
);
return $self->SUPER::configurationForm($f->printRowsOnly);
}
#-------------------------------------------------------------------
=head2 init ( $session )
Constructor
=cut
sub init {
my ($class, $self);
$class = shift;
my $session = shift;
$self = $class->SUPER::init($session,'PerTransaction');
return $self;
}
#-------------------------------------------------------------------
=head2 name ( $session )
Returns the internationalized name for this shipping plugin.
=cut
sub name {
my ($self) = shift;
my $i18n = WebGUI::International->new($self->session, 'CommerceShippingPerTransaction');
return $i18n->get('title');
}
1;

View file

@ -1,293 +0,0 @@
package WebGUI::Commerce::ShoppingCart;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use WebGUI::SQL;
use WebGUI::Commerce::Item;
use WebGUI::Commerce::Payment;
=head1 NAME
Package WebGUI::Commerce::ShoppingCart
=head1 DESCRIPTION
This package implements a shopping cart for the E-Commerce system of WebGUI. This
shopping cart is tied to the sessionId and, thus, expires when the sessionId expires.
=head1 SYNOPSIS
$shoppingCart = WebGUI::Commerce::ShoppingCart->new($session);
$shoppingCart->add('myItemId', 'myItem', 3);
$shoppingCart->setQuantity('myItemId', 'myItem', 2);
$shoppingCart->delete('myItemId', 'myItem'); # These two lines are equivalent;
$shoppingCart->setQuantity('myItemId', 'myItem', 0); #
$shoppingCart->empty; # Remove contents from cart
($normal, $recurring) = $shoppingCart->getItems;
$normal->[0]->{quantity} # quantity of first normal item
$recurring->[2]->{period} # period of third recurring item
$normal->[0]->{item}->id # the id of the first normal item
=head1 METHODS
This package provides the following methods:
=cut
#-------------------------------------------------------------------
=head2 add ( itemId, itemType, quantity )
This will add qunatity items of type itemType and with id itemId to the shopping cart.
=head3 itemId
The id of the item to add.
=head3 itemType
The type (namespace) of the item that's to be added to the cart.
=head3 quantity
The number of items to add. Defaults to 1 if quantity is not given.
=cut
sub add {
my ($self, $itemId, $itemType, $quantity, $item);
$self = shift;
$itemId = shift;
$itemType = shift;
$quantity = shift || 1;
$item = WebGUI::Commerce::Item->new($self->session,$itemId, $itemType);
return "" unless ($item->available);
# Fetch the itemId from the item plugin in stead of the given parameter.
# This allows item plugins to dynamically create new items.
$itemId = $item->id;
$self->{_items}{$itemId."_".$itemType} = {
itemId => $itemId,
itemType => $itemType,
quantity => $self->{_items}{$itemId."_".$itemType}{quantity} + $quantity
};
$self->session->db->write("delete from shoppingCart where sessionId=".$self->session->db->quote($self->{_sessionId})." and itemId=".$self->session->db->quote($itemId)." and itemType=".$self->session->db->quote($itemType));
$self->session->db->write("insert into shoppingCart ".
"(sessionId, itemId, itemType, quantity) values ".
"(".$self->session->db->quote($self->{_sessionId}).",".$self->session->db->quote($itemId).",".$self->session->db->quote($itemType).",".$self->{_items}{$itemId."_".$itemType}{quantity}.")");
}
#-------------------------------------------------------------------
=head2 delete ( itemId, itemType )
Deletes the item identified by the passed parameters from the cart.
=head3 itemId
The id of the item to delete.
=head3 itemType
the type (namespace) of the item to delete.
=cut
sub delete {
my ($self, $itemId, $itemType);
$self = shift;
$itemId = shift;
$itemType = shift;
$self->session->db->write("delete from shoppingCart where sessionId=".$self->session->db->quote($self->{_sessionId}).
" and itemId=".$self->session->db->quote($itemId)." and itemType=".$self->session->db->quote($itemType));
delete $self->{_items}{$itemId."_".$itemType};
}
#-------------------------------------------------------------------
=head2 setQuantity ( itemId, itemType, quantity )
Sets the quantity of an item (identified by itemId and itemType) in the shopping
cart. When quantity is set to zero or a negative number, the item will be deleted
from the cart.
This method only operates on items that are already in the cart. You cannot use it
to add new items to the cart. In order to that use the add method.
Generates a fatal error when the quantity is not a number.
=head3 itemId
The is of item you want to set the quantity for.
=head3 itemType
The type (namespace) of the item.
=head3 quantity
The quantity you want to set the item to.
=cut
sub setQuantity {
my ($self, $itemId, $itemType, $quantity);
$self = shift;
$itemId = shift;
$itemType = shift;
$quantity = shift;
$self->session->errorHandler->fatal('No quantity or quantity is not a number: ('.$quantity.')') unless ($quantity =~ /^-?\d+$/);
return $self->delete($itemId, $itemType) if ($quantity <= 0);
$self->{_items}{$itemId."_".$itemType}->{quantity} = $quantity;
$self->session->db->write("update shoppingCart set quantity=".$self->session->db->quote($quantity).
" where sessionId=".$self->session->db->quote($self->{_sessionId})." and itemId=".$self->session->db->quote($itemId)." and itemType=".$self->session->db->quote($itemType));
}
#-------------------------------------------------------------------
=head2 empty ( )
Invoking this method will purge all content from the shopping cart.
=cut
sub empty {
my ($self);
$self = shift;
$self->session->db->write("delete from shoppingCart where sessionId=".$self->session->db->quote($self->{_sessionId}));
}
#-------------------------------------------------------------------
=head2 getItems ( )
This method will return two arrayrefs repectively containing the normal items and the recurring
items in the shoppingcart.
Items are returned as a hashref with the following properties:
=head3 quantity
The quantity of this item.
=head3 period
The duration of a billingperiod if this this is a recurring transaction.
=head3 name
The name of this item.
=head3 price
The price of a single item.
=head3 totalPrice
The total price of this item. Ie. totalPrice = quantity * price.
=head3 item
The instantiated plugin of this item. See WebGUI::Commerce::Item for a detailed API.
=cut
sub getItems {
my ($self, $periodResolve, %cartContent, $item, $properties, @recurring, @normal);
$self = shift;
my $salesTaxRate = shift;
$periodResolve = WebGUI::Commerce::Payment->recurringPeriodValues($self->session);
%cartContent = %{$self->{_items}};
foreach (values(%cartContent)) {
$item = WebGUI::Commerce::Item->new($self->session,$_->{itemId}, $_->{itemType});
my $totalPrice = $item->price * $_->{quantity};
my $productTax = $salesTaxRate * $item->useSalesTax;
$properties = {
quantity => $_->{quantity},
period => lc($periodResolve->{$item->duration}),
name => $item->name,
price => sprintf('%.2f', $item->price),
totalPrice => sprintf('%.2f', $totalPrice),
salesTax => sprintf('%.2f', $totalPrice * $productTax),
item => $item,
};
if ($item->isRecurring) {
push(@recurring, $properties);
} else {
push(@normal, $properties);
}
}
return (\@normal, \@recurring);
}
#-------------------------------------------------------------------
=head2 new ( sessionId )
Returns a shopping cart object tied to session id sessionId or the current session.
=head3 sessionId
The session id this cart should be tied to. If omitted this will default to the session id
of the current user.
=cut
sub new {
my ($class, $session, $sessionId, $sth, $row, %items);
$class = shift;
$session = shift;
$sessionId = shift || $session->var->get("sessionId");
$sth = $session->db->read("select * from shoppingCart where sessionId=".$session->db->quote($sessionId));
while ($row = $sth->hashRef) {
$items{$row->{itemId}."_".$row->{itemType}} = $row;
}
bless {_session=>$session, _sessionId => $sessionId, _items => \%items}, $class;
}
#-------------------------------------------------------------------
=head2 session ( )
Returns the cached, local session variable.
=cut
sub session {
my ($self) = @_;
return $self->{_session};
}
1;

View file

@ -1,765 +0,0 @@
package WebGUI::Commerce::Transaction;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2008 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use WebGUI::SQL;
use WebGUI::Commerce::Payment;
use JSON qw/ decode_json encode_json /;
#-------------------------------------------------------------------
=head2 addItem ( item, quantity )
Add's an item to the transaction.
=head3 item
An WebGUI::Commerce::Item object of the item you want to add.
=head3 quantity
The number of items that are tobe added.
=cut
sub addItem {
my ($self, $item, $quantity, $lineItemAmount);
$self = shift;
$item = shift;
$quantity = shift;
$lineItemAmount = shift;
# If we have a lineItemAmount specified, we have to override price*quantity and use the value passed in instead
# We will however maintain the quantity passed and tell the user that the prices displayed are always line item totals.
#
# Again, prices are not per item but per line item. Qty 3 Price 10.00 indicates 3 items for a total of 10.00, not 3 items at 10.00 each
# It has to be this way to handle discounted items where all items in the quantity are not discounted. For example, 2 items at 5.00 each and the third item is free.
#
# Hopefully the new commerce system will handle this better. (Maybe making discounted items a different item all together with their own line item to retain the detailed information)
#
my $totalPrice = ($lineItemAmount eq "") ? $item->price * $quantity : $lineItemAmount;
$self->session->db->write("insert into transactionItem (transactionId, itemName, amount, quantity, itemId, itemType) values (?,?,?,?,?,?)",
[$self->{_transactionId}, $item->name, $totalPrice, $quantity, $item->id, $item->type]);
# Adjust total amount in the transaction table.
$self->session->db->write("update transaction set amount=amount+? where transactionId=?",[$totalPrice,$self->{_transactionId}]);
$self->{_properties}{amount} += $totalPrice;
push @{$self->{_items}}, {
transactionId => $self->{_transactionId},
itemName => $item->name,
amount => $totalPrice,
quantity => $quantity,
itemId => $item->id,
itemType => $item->type,
}
}
#-------------------------------------------------------------------
=head2 authcode ( authcode )
Returns the authcode connected to the transaction. If authcode is given the authcode property is set to that.
Presently, this is only used by the ITransact module.
=head3 authcode
The authcode of the current transaction.
=cut
sub authcode {
my ($self, $authcode) = @_;
if ($authcode) {
$self->{_properties}{authcode} = $authcode;
$self->session->db->write("update transaction set authcode=? where transactionId=?",[$authcode, $self->{_transactionId}]);
}
return $self->{_properties}{authcode};
}
#-------------------------------------------------------------------
=head2 cancelTransaction ( )
Cancels a recurring transaction. This is done by trying to cancel the subscription at the gateway
using a Payment plugin. If this is succesfull the transaction is marked as canceled.
=cut
sub cancelTransaction {
my ($self, $item, $plugin);
$self = shift;
return "Not a recurring transaction" unless ($self->isRecurring);
# Recurring transactions can only have one item, so our items must be the first
$item = $self->getItems->[0];
$plugin = WebGUI::Commerce::Payment->load($self->session, $self->gateway);
$plugin->cancelRecurringPayment({
id => $self->gatewayId,
transaction => $self,
});
return $plugin->resultMessage.' (code: '.$plugin->errorCode.')' if ($plugin->errorCode);
$self->status('Canceled');
return undef;
}
#-------------------------------------------------------------------
=head2 completeTransaction ( )
Sets the status of a transaction to 'Completed' and executes the handler for every item attached to
the transction.
=cut
sub completeTransaction {
my ($self, $item);
$self = shift;
foreach (@{$self->getItems}) {
$item = WebGUI::Commerce::Item->new($self->session,$_->{itemId}, $_->{itemType});
if (ref($item) eq 'WebGUI::Commerce::Item::Event') {
$item->handler($_->{transactionId});
}
else {
$item->handler;
}
$self->session->errorHandler->warn(ref($item));
}
$self->status('Completed');
}
#-------------------------------------------------------------------
=head2 delete ( )
Deletes the transaction from the database;
=cut
sub delete {
my ($self) = shift;
$self->session->db->write("delete from transaction where transactionId=".$self->session->db->quote($self->{_transactionId}));
$self->session->db->write("delete from transactionItem where transactionId=".$self->session->db->quote($self->{_transactionId}));
undef $self;
}
#-------------------------------------------------------------------
=head2 deleteItem ( itemId, itemType )
Deletes an item from a transaction. This will purge the record from the database, and
updates the amount of the transaction. It doesn't change the shipping cost however.
Also if you want to credit the user (you'll probably want to) for the amount of the
removed items, you must do this yourself.
=head3 itemId
The id of the item you want to remove.
=head3 itemType
The type of the item you want to remove.
=cut
#-------------------------------------------------------------------
sub deleteItem {
my ($self, $itemId, $itemType, $amount, @items);
$self = shift;
$itemId = shift;
$itemType = shift;
$self->session->errorHandler->fatal('No itemId') unless ($itemId);
$self->session->errorHandler->fatal('No itemType') unless ($itemType);
$amount = $self->get('amount');
foreach (@{$self->getItems}) {
if (($_->{itemId} eq $itemId) && ($_->{itemType} eq $itemType)) {
$amount = $amount - ($_->{quantity} * $_->{amount});
} else {
push(@items, $_);
}
}
$self->session->db->write("delete from transactionItem where transactionId=".$self->session->db->quote($self->get('transactionId')).
" and itemId=".$self->session->db->quote($itemId)." and itemType=".$self->session->db->quote($itemType));
$self->session->db->write("update transaction set amount=".$self->session->db->quote($amount)." where transactionId=".$self->session->db->quote($self->get('transactionId')));
$self->{_properties}{amount} = $amount;
$self->{_items} = \@items;
}
#-------------------------------------------------------------------
=head2 gateway ( gatewayName )
Returns the gateway connected to the transaction. If gatewayName is given the gateway property is set to that.
=head3 gatewayName
The name to which to set the gateway.
=cut
sub gateway {
my ($self, $gateway);
$self = shift;
$gateway = shift;
if ($gateway) {
$self->{_properties}{gateway} = $gateway;
$self->session->db->write("update transaction set gateway=".$self->session->db->quote($gateway)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{gateway};
}
#-------------------------------------------------------------------
=head2 gatewayId ( id )
Returns the gateway ID of the transaction. If id is given the gateway ID is set to it.
=head3 id
The ID which to set the gatewayId to.
=cut
sub gatewayId {
my ($self, $gatewayId);
$self = shift;
$gatewayId = shift;
if ($gatewayId) {
$self->{_properties}{gatewayId} = $gatewayId;
$self->session->db->write("update transaction set gatewayId=".$self->session->db->quote($gatewayId)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{gatewayId};
}
#-------------------------------------------------------------------
=head2 get ( property )
Returns the property requested. If no property is specified this method returns a hashref
containing all properties.
=head3 property
The name of the property you want.
=cut
sub get {
my ($self, $key);
$self = shift;
$key = shift;
return $self->{_properties}{$key} if ($key);
return $self->{_properties};
}
#-------------------------------------------------------------------
=head2 getByGatewayId ( id, gateway )
Constructor. Return a transaction object that is identified by the given id and payment gateway.
Returns undef if no match is found.
=head3 id
The gateway ID of the transaction.
=head3 gateway
The payment gateway which the transaction is tied to.
=cut
sub getByGatewayId {
my ($self, $gatewayId, $paymentGateway, $transactionId);
$self = shift;
$gatewayId = shift;
$paymentGateway = shift;
($transactionId) = $self->session->db->quickArray("select transactionId from transaction where gatewayId=".$self->session->db->quote($gatewayId).
" and gateway=".$self->session->db->quote($paymentGateway));
return WebGUI::Commerce::Transaction->new($self->session, $transactionId) if $transactionId;
return undef;
}
#-------------------------------------------------------------------
=head2 getItems ( )
=cut
sub getItems {
my ($self);
$self = shift;
return $self->{_items};
}
#-------------------------------------------------------------------
=head2 getTransactions ( constraints )
Returns an array consisting of WebGUI::Commerce::Transaction objects complying to
the passed constraints.
=head3 constraints
A hashref containing the contrains by which the transactions are selected. These can be:
* initStart
Epoch that specifies the lower bounds on the initialisation date.
* initStop
Epoch that specifies the upper bound on the initialisation date.
* completionStart
Epoch specifying the lower bound on the completion date.
* completionStop
Epoch specifying the upper bound on the completion date.
* status
The status of the transaction. Can be: Pending, Completed or Canceled
* shippingStatus
The shipping status of the transaction. Can be: NotShipped, Shipped or Delivered
=cut
sub getTransactions {
my ($self, $criteria, @constraints, $sql, @transactionIds, @transactions);
$self = shift;
$criteria = shift;
push (@constraints, 'initDate >= '.$self->session->db->quote($criteria->{initStart})) if (defined $criteria->{initStart});
push (@constraints, 'initDate <= '.$self->session->db->quote($criteria->{initStop})) if (defined $criteria->{initStop});
push (@constraints, 'completionDate >= '.$self->session->db->quote($criteria->{completionStart})) if (defined $criteria->{completionStart});
push (@constraints, 'completionDate <= '.$self->session->db->quote($criteria->{completionStop})) if (defined $criteria->{completionStop});
push (@constraints, 'status='.$self->session->db->quote($criteria->{paymentStatus})) if (defined $criteria->{paymentStatus});
push (@constraints, 'shippingStatus='.$self->session->db->quote($criteria->{shippingStatus})) if (defined $criteria->{shippingStatus});
$sql = 'select transactionId from transaction';
$sql .= ' where '.join(' and ', @constraints) if (@constraints);
$sql .= ' order by initDate desc';
@transactionIds = $self->session->db->buildArray($sql);
foreach (@transactionIds) {
push(@transactions, WebGUI::Commerce::Transaction->new($self->session, $_));
}
return @transactions;
}
#-------------------------------------------------------------------
=head2 isRecurring ( recurring )
Returns a boolean indcating whether the transaction is recurring. If recurring is given, the isRecurring flag
will be set to it.
=head3 recurring
A boolean which sets the transaction as recurring if true.
=cut
sub isRecurring {
my ($self, $recurring);
$self = shift;
$recurring = shift;
if (defined $recurring) {
$self->{_properties}{recurring} = $recurring;
$self->session->db->write("update transaction set recurring=".$self->session->db->quote($recurring)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{recurring};
}
#-------------------------------------------------------------------
=head2 lastPayedTerm ( term )
Returns the last term number that has been paid. If term is given this number will be set to it.
-head3 term
The number which to set tha last payed term to.
=cut
sub lastPayedTerm {
my ($self, $lastPayedTerm);
$self = shift;
$lastPayedTerm = shift;
if (defined $lastPayedTerm) {
$self->{_properties}{lastPayedTerm} = $lastPayedTerm;
$self->session->db->write("update transaction set lastPayedTerm=".$self->session->db->quote($lastPayedTerm)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{lastPayedTerm};
}
#-------------------------------------------------------------------
=head2 message ( message )
Returns the message connected to the transaction. If message is given the message property is set to that.
Presently, this is only used by the ITransact module.
=head3 message
The message of the current transaction.
=cut
sub message {
my ($self, $message) = @_;
if ($message) {
$self->{_properties}{message} = $message;
$self->session->db->write("update transaction set message=? where transactionId=?",[$message, $self->{_transactionId}]);
}
return $self->{_properties}{message};
}
#-------------------------------------------------------------------
=head2 new ( transactionId, [ gateway, [ userId ] ] )
Constructor. Returns a transaction object. If transactionId is set to 'new' a new transaction is created.
=head3 transactionId
The transaction ID of the transaction you want. Set to 'new' for a new transaction.
=head3 gateway
The payment gateway to use for this transaction. Only needed for new transactions.
=head3 userId
The userId of the user for whom to create this transaction. Defaults to the current user. Only optional for
new transactions.
=cut
sub new {
my ($class, $transactionId, $gatewayId, $userId, $properties, $sth, $row, @items);
$class = shift;
my $session = shift;
$transactionId = shift;
$gatewayId = shift;
$userId = shift || $session->user->userId;
if ($transactionId eq 'new') {
$transactionId = $session->id->generate;
$session->db->write("insert into transaction ".
"(transactionId, userId, amount, gatewayId, initDate, completionDate, status) values ".
"(".$session->db->quote($transactionId).",".$session->db->quote($userId).",0,".$session->db->quote($gatewayId).",".$session->db->quote(time).",NULL,'Pending')");
}
$properties = $session->db->quickHashRef("select * from transaction where transactionId=".$session->db->quote($transactionId));
$sth = $session->db->read("select * from transactionItem where transactionId=".$session->db->quote($transactionId));
while ($row = $sth->hashRef) {
push(@items, $row);
}
bless {_session => $session, _transactionId => $transactionId, _properties => $properties, _items => \@items}, $class;
}
#-------------------------------------------------------------------
=head2 pendingTransactions ( )
Returns a reference to an array which contains transaction objects of all pending transactions. This
is a class method.
=cut
sub pendingTransactions {
my (@transactionIds, @transactions);
my ($class, $session) = @_;
@transactionIds = $session->db->buildArray("select transactionId from transaction where status = 'Pending'");
foreach (@transactionIds) {
push(@transactions, WebGUI::Commerce::Transaction->new($session, $_));
}
return \@transactions;
}
#-------------------------------------------------------------------
=head2 session ( )
Returns the cached, local session variable.
=cut
sub session {
my $self = shift;
return $self->{_session};
}
#-------------------------------------------------------------------
=head2 shippingCost ( [amount] )
Returns the shipping cost for this transaction. If amount is supplied the sipping cost will
be set to that value.
=head3 amount
If supplied the shipping cost of the transaction will be set to this value.
=cut
sub shippingCost {
my ($self, $shippingCost);
$self = shift;
$shippingCost = shift;
if ($shippingCost) {
$self->{_properties}{shippingCost} = $shippingCost;
$self->session->db->write("update transaction set shippingCost=".$self->session->db->quote($shippingCost)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{shippingCost};
}
#-------------------------------------------------------------------
=head2 shippingMethod ( [ method ] )
Returns the shipping method for this transaction. If amount is supplied the shipping method will
be set to it.
=head3 method
If supplied the shipping method of the transaction will be set to this value.
=cut
sub shippingMethod {
my ($self, $shippingMethod);
$self = shift;
$shippingMethod = shift;
if ($shippingMethod) {
$self->{_properties}{shippingMethod} = $shippingMethod;
$self->session->db->write("update transaction set shippingMethod=".$self->session->db->quote($shippingMethod)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{shippingMethod};
}
#-------------------------------------------------------------------
=head2 shippingOptions ( [ options ] )
Returns the shipping options for this transaction. If options is supplied the shipping options will
be set to it.
=head3 options
If supplied the shipping options of the transaction will be set to this value. The value passed will
be serialized/un-serialized for you.
=cut
sub shippingOptions {
my ($self, $shippingOptions);
$self = shift;
$shippingOptions = shift;
if (scalar (keys %{$shippingOptions})) {
$self->{_properties}{shippingOptions} = encode_json($shippingOptions);
$self->session->db->write("update transaction set shippingOptions=? where transactionId=?",[$self->{_properties}{shippingOptions},$self->{_transactionId}]);
}
return {} unless defined $self->{_properties}{shippingOptions};
return decode_json($self->{_properties}{shippingOptions});
}
#-------------------------------------------------------------------
=head2 shippingStatus ( [ status ] )
Returns the shipping status for this transaction. If status is supplied the shipping status will
be set to it.
=head3 status
If supplied the shipping status of the transaction will be set to this value.
=cut
sub shippingStatus {
my ($self, $shippingStatus);
$self = shift;
$shippingStatus = shift;
if ($shippingStatus) {
$self->{_properties}{shippingStatus} = $shippingStatus;
$self->session->db->write("update transaction set shippingStatus=".$self->session->db->quote($shippingStatus)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{shippingStatus};
}
#-------------------------------------------------------------------
=head2 status ( status )
Returns the status of the transaction. If status is given the transaction status will be set to it.
=head3 status
The value to set the transaction status to.
=cut
sub status {
my ($self, $status);
$self = shift;
$status = shift;
if ($status) {
$self->{_properties}{status} = $status;
$self->session->db->write("update transaction set status=".$self->session->db->quote($status)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{status};
}
#-------------------------------------------------------------------
=head2 trackingNumber ( [ number ] )
Returns the tracking number of the shipped transaction. If numer is supplied the tracking number will
be set to it.
=head3 number
If supplied the tracking number of the transaction will be set to this value.
=cut
sub trackingNumber {
my ($self, $trackingNumber);
$self = shift;
$trackingNumber = shift;
if ($trackingNumber) {
$self->{_properties}{trackingNumber} = $trackingNumber;
$self->session->db->write("update transaction set trackingNumber=".$self->session->db->quote($trackingNumber)." where transactionId=".$self->session->db->quote($self->{_transactionId}));
}
return $self->{_properties}{trackingNumber};
}
#-------------------------------------------------------------------
=head2 transactionId ( )
Returns the transactionId of the transaction.
=cut
sub transactionId {
my $self = shift;
return $self->{_transactionId};
}
#-------------------------------------------------------------------
=head2 transactionsByUser ( userId )
Returns a reference to an array containing transaction objects of all tranactions by the user corresponding to userId.
=head3 userId
The ID of the user you want the transaction of.
=cut
sub transactionsByUser {
my (@transactionIds, @transactions);
my $self = shift;
my $userId = shift;
@transactionIds = $self->session->db->buildArray("select transactionId from transaction where userId =".$self->session->db->quote($userId));
foreach (@transactionIds) {
push (@transactions, WebGUI::Commerce::Transaction->new($self->session, $_));
}
return \@transactions;
}
#-------------------------------------------------------------------
=head2 xid ( xid )
Returns the xid connected to the transaction. If xid is given the xid property is set to that.
Presently, this is only used by the ITransact module.
=head3 xid
The xid of the current transaction.
=cut
sub xid {
my ($self, $xid) = @_;
if ($xid) {
$self->{_properties}{xid} = $xid;
$self->session->db->write("update transaction set xid=? where transactionId=?",[$xid, $self->{_transactionId}]);
}
return $self->{_properties}{xid};
}
1;

View file

@ -1,87 +0,0 @@
package WebGUI::Help::Commerce;
use strict;
our $HELP = {
'cancel template' => {
title => 'help cancel checkout template title',
body => '',
variables => [ { 'name' => 'message' } ],
fields => [],
related => []
},
'confirm template' => {
title => 'help checkout confirm template title',
body => '',
fields => [],
variables => [
{ 'name' => 'title' },
{ 'name' => 'normalItems' },
{ 'name' => 'normalItemLoop',
'variables' => [
{ 'name' => 'quantity' },
{ 'name' => 'period' },
{ 'name' => 'name' },
{ 'name' => 'salesTax' },
{ 'name' => 'price' },
{ 'name' => 'totalPrice' }
]
},
{ 'name' => 'recurringItems' },
{ 'name' => 'recurringItemLoop' },
{ 'name' => 'form' },
{ 'name' => 'salesTaxRate' },
{ 'name' => 'totalSalesTax' },
],
related => [],
},
'error template' => {
title => 'help checkout error template title',
body => '',
fields => [],
variables => [
{ 'name' => 'title', },
{ 'name' => 'statusExplanation' },
{ 'name' => 'resultLoop',
'variables' => [
{ 'name' => 'purchaseDescription' },
{ 'name' => 'status' },
{ 'name' => 'error' },
{ 'name' => 'errorCode' }
]
}
],
related => []
},
'select payment gateway template' => {
title => 'help select payment template title',
body => '',
fields => [],
variables => [
{ 'name' => 'message',
'description' => 'gateway message'
},
{ 'name' => 'pluginsAvailable' },
{ 'name' => 'noPluginsMessage' },
{ 'name' => 'formHeader' },
{ 'name' => 'formFooter' },
{ 'name' => 'formSubmit' },
{ 'name' => 'pluginLoop',
'variables' => [
{ 'name' => 'name',
'description' => 'plugin name'
},
{ 'name' => 'namespace' },
{ 'name' => 'formElement' }
]
}
],
related => []
},
};
1;

View file

@ -1,38 +0,0 @@
package WebGUI::Help::Macro_Product;
use strict;
our $HELP = {
'product' => {
title => 'product title',
body => '',
variables => [
{ 'name' => 'variants.message' },
{ 'name' => 'variantLoop',
'variables' => [
{ 'name' => 'variant.compositionLoop',
'variables' => [ { 'name' => 'parameter' }, { 'name' => 'value' } ]
},
{ 'name' => 'variant.variantId' },
{ 'name' => 'variant.price' },
{ 'name' => 'variant.weight' },
{ 'name' => 'variant.sku' },
{ 'name' => 'variant.addToCart.url' },
{ 'name' => 'variant.addToCart.label' }
]
},
{ 'name' => 'productId' },
{ 'name' => 'title' },
{ 'name' => 'description' },
{ 'name' => 'price' },
{ 'name' => 'weight' },
{ 'name' => 'sku' }
],
fields => [],
related => []
},
};
1;

View file

@ -1,17 +0,0 @@
package WebGUI::Help::Macro_SubscriptionItem;
use strict;
our $HELP = {
'subscription item' => {
title => 'subscription item title',
body => '',
variables =>
[ { 'name' => 'url' }, { 'name' => 'name' }, { 'name' => 'description' }, { 'name' => 'price' } ],
fields => [],
related => []
},
};
1;

View file

@ -1,16 +0,0 @@
package WebGUI::Help::ProductManager;
use strict;
our $HELP = {
'edit sku template' => {
title => 'help edit sku template title',
body => 'help edit sku template body',
fields => [],
related => []
},
};
1;

View file

@ -1,15 +0,0 @@
package WebGUI::Help::Subscription;
use strict;
our $HELP = {
'redeem code' => {
title => 'help redeem code template title',
body => 'help redeem code template body',
fields => [],
related => []
},
};
1;

View file

@ -1,82 +0,0 @@
package WebGUI::Macro::Product;
use strict;
use WebGUI::Product;
use WebGUI::Asset::Template;
use WebGUI::International;
=head1 NAME
Package WebGUI::Macro::Product
=head1 DESCRIPTION
This macro looks up a Product in the Product Manager
=head2 process ( ID/SKU [,templateId] )
=head3 productId or SKU
The productId or SKU of the project to look up.
=head3 templateId
An alternate template to use for formatting the link, referenced by templateId. If this
is left blank, a default template from the Macro/Product namespace will be used.
=cut
sub process {
my $session = shift;
my (@param, $productId, $variantId, $product, $variant, $output, $templateId, @variantLoop, %var);
@param = @_;
my $i18n = WebGUI::International->new($session,'Macro_Product');
return $i18n->get('no sku or id') unless ($_[0]);
($productId, $variantId) = $session->db->quickArray("select productId, variantId from productVariants where sku=".$session->db->quote($_[0]));
($productId) = $session->db->quickArray("select productId from products where sku=".$session->db->quote($_[0])) unless ($productId);
($productId) = $session->db->quickArray("select productId from products where productId=".$session->db->quote($_[0])) unless ($productId);
return $i18n->get('cannot find product') unless ($productId);
$product = WebGUI::Product->new($session,$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' => $session->url->page('op=addToCart;itemType=Product;itemId='.$_->{variantId}),
'variant.addToCart.label' => $i18n->get('add to cart'),
}) if ($_->{available});
}
%var = %{$product->get};
$var{variantLoop} = \@variantLoop;
$var{'variants.message'} = $i18n->get('available product configurations');
$templateId = $_[1] || $product->get('templateId');
return WebGUI::Asset::Template->new($session,$templateId)->process(\%var);
}
1;

View file

@ -1,60 +0,0 @@
package WebGUI::Macro::SubscriptionItem;
use strict;
use WebGUI::Asset::Template;
=head1 NAME
Package WebGUI::Macro::SubscriptionItem;
=head1 DESCRIPTION
Macro for displaying information about subscription items.
=head2 process ( subscriptionId [,templateId ] )
process takes two optional parameters for customizing the content and layout
of the account link.
=head3 subscriptionId
The text of the link. If no text is displayed an internationalized default will be used.
=head3 templateId
A templateId to use for formatting the link. If this is empty, a default template will
be used from the Macro/SubscriptionItem namespace.
=cut
sub process {
my $session = shift;
my $subscriptionId = shift;
my $templateId = shift || 'PBtmpl0000000000000046';
# Fetch subscription asset
my $subscription = WebGUI::Asset->newByDynamicClass( $session, $subscriptionId );
return "Could not find subscription with id: [$subscriptionId]" unless $subscription;
return "Only Subscription assets can be used with this macro."
unless $subscription->get('className') =~ m{^WebGUI::Asset::Sku::Subscription};
# Setup template vars
my $var;
$var->{ subscriptionId } = $subscription->getId;
$var->{ name } = $subscription->get('title');
$var->{ price } = $subscription->getPrice;
$var->{ description } = $subscription->get('description');
$var->{ subscriptionGroup } = $subscription->get('subscriptionGroup');
$var->{ duration } = $subscription->get('duration');
$var->{ karma } = $subscription->get('karma');
$var->{ useSalesTax } = $subscription->get('useSalesTax');
$var->{ url } = $subscription->getUrl('func=purchaseSubscription');
# Fetch template
my $template = WebGUI::Asset::Template->new( $session, $templateId );
return "Could not instantiate template with id:[$templateId]" unless $template;
return $template->process( $var );
}
1;

View file

@ -1,38 +0,0 @@
package WebGUI::Macro::SubscriptionItemPurchaseUrl;
use strict;
=head1 NAME
Package WebGUI::Macro::SubscriptionItemPurchaseUrl
=head1 DESCRIPTION
Macro that returns a URL to purchase a subscription item.
=head2 process ( subscriptionId )
process returns a URL that is the current page with an operation appended
to purchase the requested subscription item.
=head3 subscriptionId
The ID of the subscription item to purchase.
=cut
sub process {
my $session = shift;
my $subscriptionId = shift;
# Fetch subscription asset
my $subscription = WebGUI::Asset->newByDynamicClass( $session, $subscriptionId );
return "Could not find subscription with id: [$subscriptionId]" unless $subscription;
return "Only Subscription assets can be used with this macro."
unless $subscription->get('className') =~ m{^WebGUI::Asset::Sku::Subscription};
# Construct and output the purchase url for this subscription
return $subscription->getUrl('func=purchaseSubscription');
}
1;

File diff suppressed because it is too large Load diff

View file

@ -1,905 +0,0 @@
package WebGUI::Operation::ProductManager;
use strict;
use WebGUI::SQL;
use WebGUI::HTMLForm;
use WebGUI::Form;
use WebGUI::International;
use WebGUI::AdminConsole;
use Tie::IxHash;
use WebGUI::Product;
use WebGUI::HTML;
#-------------------------------------------------------------------
=head2 _submenu ( $session )
Returns a rendered Admin Console view, with a standard list of five submenu items.
=head3 $session
The current WebGUI session object.
=head3 workarea
A scalar of HTML that defines the current workarea.
=head3 title
The i18n key of the title of this workarea.
=cut
sub _submenu {
my $session = shift;
my $i18n = WebGUI::International->new($session, "ProductManager");
my $workarea = shift;
my $title = shift;
$title = $i18n->get($title) if ($title);
my $ac = WebGUI::AdminConsole->new($session,"productManager");
my $productId = $session->form->process("productId") || $session->scratch->get('managingProduct');
undef $productId if ($productId eq 'new');
$ac->addSubmenuItem($session->url->page('op=editProduct;productId=new'), $i18n->get('add product'));
$ac->addSubmenuItem($session->url->page('op=listProducts'), $i18n->get('list products'));
$ac->addSubmenuItem($session->url->page('op=manageProduct;productId='.$productId), $i18n->get('manage product')) if ($productId);
$ac->addSubmenuItem($session->url->page('op=listProductVariants;productId='.$productId), $i18n->get('list variants')) if ($productId);
return $ac->render($workarea, $title);
}
#----------------------------------------------------------------------------
=head2 canView ( session [, user] )
Returns true if the user can administrate this operation. user defaults to
the current user.
=cut
sub canView {
my $session = shift;
my $user = shift || $session->user;
return $user->isInGroup( $session->setting->get("groupIdAdminProductManager") );
}
#-------------------------------------------------------------------
=head2 www_deleteProductParameterOption ( $session )
Deletes a product parameter option specified by form parameter 'optionId'.
=head3 $session
The current WebGUI session object.
=cut
sub www_deleteProductParameterOption {
my $session = shift;
my $optionId = $session->form->process("optionId");
return $session->privilege->insufficient unless canView($session);
WebGUI::Product->getByOptionId($session,$optionId)->deleteOption($optionId);
return WebGUI::Operation::execute($session,'manageProduct');
}
#-------------------------------------------------------------------
=head2 www_deleteProductParameter ( $session )
Deletes a product parameter specified by form parameter 'parameterId'.
=head3 $session
The current WebGUI session object.
=cut
sub www_deleteProductParameter {
my $session = shift;
my $parameterId = $session->form->process("parameterId");
return $session->privilege->insufficient unless canView($session);
WebGUI::Product->getByParameterId($session,$parameterId)->deleteParameter($parameterId);
return WebGUI::Operation::execute($session,'manageProduct');
}
#-------------------------------------------------------------------
=head2 www_deleteProduct ( $session )
Deletes a product specified by form parameter 'productId'.
=head3 $session
The current WebGUI session object.
=cut
sub www_deleteProduct {
my $session = shift;
my $productId = $session->form->process("productId");
return $session->privilege->insufficient unless canView($session);
WebGUI::Product->new($session,$productId)->delete;
return WebGUI::Operation::execute($session,'listProducts');
}
#-------------------------------------------------------------------
=head2 www_editProduct ( $session )
Returns a form to edit or add a new product.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProduct {
my $session = shift;
my ($productId, $product, $f, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
$productId = $session->form->process("productId");
unless ($productId eq 'new') {
$product = WebGUI::Product->new($session,$productId)->get;
}
$f = WebGUI::TabForm->new($session);
$f->addTab("properties","Properties");
$f->addTab("actions","Actions");
$f->submit;
$f->hidden({
name => 'op',
value => 'editProductSave'
});
$f->hidden({
name => 'productId',
value => $productId
});
$f->getTab("properties")->text(
-name => 'title',
-label => $i18n->get('title'),
-hoverHelp => $i18n->get('title description'),
-value => $session->form->process("title") || $product->{title},
-maxlength => 255,
);
$f->getTab("properties")->textarea(
-name => 'description',
-label => $i18n->get('description'),
-hoverHelp => $i18n->get('description description'),
-value => $session->form->process("decsription") || $product->{description},
);
$f->getTab("properties")->float(
-name => 'price',
-label => $i18n->get('price'),
-hoverHelp => $i18n->get('price description'),
-value => $session->form->process("price") || $product->{price},
-maxlength => 13,
);
$f->getTab("properties")->yesNo(
-name => 'useSalesTax',
-label => $i18n->get('useSalesTax'),
-hoverHelp => $i18n->get('useSalesTax description'),
-value => $session->form->process("useSalesTax") || $product->{useSalesTax},
);
$f->getTab("properties")->float(
-name => 'weight',
-label => $i18n->get('weight'),
-hoverHelp => $i18n->get('weight description'),
-value => $session->form->process("weight") || $product->{weight},
-maxlength => 9,
);
$f->getTab("properties")->text(
-name => 'sku',
-label => $i18n->get('sku'),
-hoverHelp => $i18n->get('sku description'),
-value => $session->form->process("sku") || $product->{sku},
-maxlength => 64,
);
$f->getTab("properties")->template(
-name => 'templateId',
-label => $i18n->get('template'),
-hoverHelp => $i18n->get('template description'),
-value => $session->form->process("templateId") || $product->{templateId},
-namespace => 'Commerce/Product',
);
$f->getTab("properties")->text(
-name => 'skuTemplate',
-label => $i18n->get('sku template'),
-hoverHelp => $i18n->get('sku template description'),
-value => $session->form->process("skuTemplate") || $product->{skuTemplate},
-maxlength => 255,
);
$f->getTab("actions")->group(
-name => 'groupId',
-label => $i18n->get('group id'),
-hoverHelp => $i18n->get('group id description'),
-value => $session->form->process("groupId") || $product->{groupId},
);
my %groupExpiresOffsetOptions;
tie %groupExpiresOffsetOptions, 'Tie::IxHash',
'1month' => $i18n->get("1 month"),
'6month' => $i18n->get("6 months"),
'1year' => $i18n->get("1 year"),
'2year' => $i18n->get("2 years"),
'3year' => $i18n->get("3 years"),
'5year' => $i18n->get("5 years"),
'10year' => $i18n->get("10 years"),
'1000year' => $i18n->get("lifetime"),
;
$f->getTab("actions")->selectBox(
-name => 'groupExpiresOffset',
-label => $i18n->get('group expires offset'),
-hoverHelp => $i18n->get('group expires offset description'),
-value => $session->form->process("groupExpiresOffset") || $product->{groupExpiresOffset},
-options => \%groupExpiresOffsetOptions,
-defaultValue => '1000year',
);
return _submenu($session,$f->print, 'edit product');
}
#-------------------------------------------------------------------
=head2 www_editProductSave ( $session )
Saves the properties of a product.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductSave {
my $session = shift;
my ($self, @error, $productId, $product, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
push(@error, $i18n->get('edit product title error')) unless $session->form->process("title");
push(@error, $i18n->get('edit product price error')) unless ($session->form->process("price") && $session->form->process("price") =~ /^\d+(\.\d+)?$/);
push(@error, $i18n->get('edit product weight error')) unless (defined $session->form->process("weight") && $session->form->process("price") =~ /^\d+(\.\d+)?$/);
push(@error, $i18n->get('edit product sku error')) unless ($session->form->process("sku"));
return '<ul><li>'.join('</li><li>', @error).'</li></ul><br />'.WebGUI::Operation::execute($session,'editProduct') if (@error);
$productId = $session->form->process("productId");
$product = WebGUI::Product->new($session,$productId);
$product->set({
title => $session->form->process("title"),
description => $session->form->process("description"),
price => $session->form->process("price"),
useSalesTax => $session->form->process("useSalesTax"),
weight => $session->form->process("weight"),
sku => $session->form->process("sku"),
templateId => $session->form->process("templateId"),
skuTemplate => $session->form->process("skuTemplate"),
groupId => $session->form->process('groupId'),
groupExpiresOffset => $session->form->process('groupExpiresOffset'),
});
return www_manageProduct($session, $product->get('productId'));
}
#-------------------------------------------------------------------
=head2 www_editProductParameter ( $session )
Returns a form to edit a product parameter.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductParameter {
my $session = shift;
my ($parameterId, $product, $productId, $parameter, $f, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
$parameterId = $session->form->process("parameterId");
$productId = $session->form->process("productId");
unless ($parameterId eq 'new') {
$product = WebGUI::Product->getByParameterId($session,$parameterId);
$parameter = $product->getParameter($parameterId);
$productId = $product->get('productId');
}
$f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'editProductParameterSave',
);
$f->hidden(
-name => 'parameterId',
-value => $parameterId,
);
$f->hidden(
-name => 'productId',
-value => $productId,
);
$f->readOnly(
-label => $i18n->get('parameter ID'),
-value => $parameterId,
);
$f->text(
-name => 'name',
-label => $i18n->get('edit parameter name'),
-hoverHelp => $i18n->get('edit parameter name description'),
-value => $session->form->process("name") || $parameter->{name},
-maxlength => 64,
);
$f->submit;
return _submenu($session,$f->print, 'edit parameter');
}
#-------------------------------------------------------------------
=head2 www_editProductParameterSave ( $session )
Saves the properties of a product parameter.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductParameterSave {
my $session = shift;
my (@error, $parameterId, $product, $i18n, $skuTemplate, $oldName, $newName);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
$parameterId = $session->form->process("parameterId");
push (@error, $i18n->get('edit parameter name error')) unless $session->form->process("name");
push (@error, $i18n->get('edit parameter productId error')) unless $session->form->process("productId");
return "<ul><li>".join('</li><li>', @error)."</li></ul>".WebGUI::Operation::execute($session,'editProductParameter') if (@error);
$product = WebGUI::Product->new($session,$session->form->process("productId"));
$skuTemplate = $product->get('skuTemplate');
if ($parameterId eq 'new') {
$parameterId = $product->addParameter;
} else {
($oldName = $product->getParameter($parameterId)->{name}) =~ s/[ ><]/\./g;
($newName = $session->form->process("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->process("name")
});
return WebGUI::Operation::execute($session,'editSkuTemplate') if ($session->form->process("parameterId") eq 'new');
return WebGUI::Operation::execute($session,'manageProduct');
}
#-------------------------------------------------------------------
=head2 www_editProductParameterOption ( $session )
Edits the options of a product parameter.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductParameterOption {
my $session = shift;
my ($self, $optionId, $option, $f, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
$optionId = $session->form->process("optionId");
unless ($optionId eq 'new') {
$option = WebGUI::Product->getByOptionId($session,$optionId)->getOption($optionId);
}
$f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'editProductParameterOptionSave',
);
$f->hidden(
-name => 'optionId',
-value => $optionId,
);
$f->hidden(
-name => 'parameterId',
-value => $session->form->process("parameterId"),
);
$f->readOnly(
-label => $i18n->get('option ID'),
-value => $optionId
);
$f->text(
-name => 'value',
-label => $i18n->get('edit option value'),
-hoverHelp => $i18n->get('edit option value description'),
-value => $session->form->process("value") || $option->{value},
-maxlength => 64,
);
$f->float(
-name => 'priceModifier',
-label => $i18n->get('edit option price modifier'),
-hoverHelp => $i18n->get('edit option price modifier description'),
-value => $session->form->process("priceModifier") || $option->{priceModifier},
-maxlength => 11,
);
$f->float(
-name => 'weightModifier',
-label => $i18n->get('edit option weight modifier'),
-hoverHelp => $i18n->get('edit option weight modifier description'),
-value => $session->form->process("weightModifier") || $option->{weightModifier},
-maxlength => 7,
);
$f->text(
-name => 'skuModifier',
-label => $i18n->get('edit option sku modifier'),
-hoverHelp => $i18n->get('edit option sku modifier description'),
-value => $session->form->process("skuModifier") || $option->{skuModifier},
-maxlength => 64,
);
$f->submit;
return _submenu($session,$f->print, 'edit option');
}
#-------------------------------------------------------------------
=head2 www_editProductParameterOptionSave ( $session )
Saves the properties of a Product Parameter Option
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductParameterOptionSave {
my $session = shift;
my ($self, @error, $optionId, $product, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
push (@error, $i18n->get('edit option value error')) unless ($session->form->process("value"));
push (@error, $i18n->get('edit option parameterId error')) unless ($session->form->process("parameterId"));
return '<ul><li>'.join('</li><li>', @error).'</li></ul><br />'.WebGUI::Operation::execute($session,'editProduct') if (@error);
$product = WebGUI::Product->getByParameterId($session,$session->form->process("parameterId"));
$optionId = $session->form->process("optionId");
$optionId = $product->addOptionToParameter($session->form->process("parameterId")) if ($optionId eq 'new');
$product->setOption($optionId, {
value => $session->form->process("value"),
priceModifier => $session->form->process("priceModifier"),
weightModifier => $session->form->process("weightModifier"),
skuModifier => $session->form->process("skuModifier")
});
return WebGUI::Operation::execute($session,'manageProduct');
}
#-------------------------------------------------------------------
=head2 www_editProductVariant ( $session )
Returns a form to edit a Product Variant.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductVariant {
my $session = shift;
my ($variantId, $variant, $f, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, "ProductManager");
$variantId = $session->form->process("variantId");
$variant = WebGUI::Product->getByVariantId($session,$variantId)->getVariant($variantId);
$f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'editProductVariantSave'
);
$f->hidden(
-name => 'variantId',
-value => $variantId
);
$f->readOnly(
-label => $i18n->get('variant ID'),
-value => $variant->{variantId}
);
$f->float(
-name => 'price',
-label => $i18n->get('price override'),
-hoverHelp => $i18n->get('price override description'),
-value => $variant->{priceOverride} ? $variant->{price} : ''
);
$f->float(
-name => 'weight',
-label => $i18n->get('weight override'),
-hoverHelp => $i18n->get('weight override description'),
-value => $variant->{weightOverride} ? $variant->{weight} : ''
);
$f->text(
-name => 'sku',
-label => $i18n->get('sku override'),
-hoverHelp => $i18n->get('sku override description'),
-value => $variant->{skuOverride} ? $variant->{sku} : ''
);
$f->yesNo(
-name => 'available',
-label => $i18n->get('available'),
-hoverHelp => $i18n->get('available description'),
-value => $variant->{available}
);
$f->submit;
return _submenu($session,$f->print, 'edit variant');
}
#-------------------------------------------------------------------
=head2 www_editProductVariantSave ( $session )
Saves the properties of a Product Variant.
=head3 $session
The current WebGUI session object.
=cut
sub www_editProductVariantSave {
my $session = shift;
my $variantId = $session->form->process("variantId");
return $session->privilege->insufficient unless canView($session);
WebGUI::Product->getByVariantId($session,$variantId)->setVariant($variantId, $session->form->paramsHashRef);
return WebGUI::Operation::execute($session,'listProductVariants');
}
#-------------------------------------------------------------------
=head2 www_editSkuTemplate ( $session )
Returns a form to edit a Sku Template.
=head3 $session
The current WebGUI session object.
=cut
sub www_editSkuTemplate {
my $session = shift;
my ($product, $productId, $output, $f, $name, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, "ProductManager");
$productId = $session->form->process("productId");
$product = WebGUI::Product->new($session,$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($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'editSkuTemplateSave'
);
$f->hidden(
-name => 'productId',
-value => $productId
);
$f->text(
-name => 'skuTemplate',
-value => $product->get('skuTemplate'),
-label => $i18n->get('sku template'),
);
$f->submit;
$output .= $f->print;
return _submenu($session,$output, 'edit sku composition label');
}
#-------------------------------------------------------------------
=head2 www_editSkuTemplateSave ( $session )
Saves the properties of a Sku Template.
=head3 $session
The current WebGUI session object.
=cut
sub www_editSkuTemplateSave {
my $session = shift;
my ($productId) = $session->form->process("productId");
return $session->privilege->insufficient unless canView($session);
WebGUI::Product->new($session,$productId)->set({
skuTemplate => $session->form->process("skuTemplate"),
});
return WebGUI::Operation::execute($session,'manageProduct');
}
#-------------------------------------------------------------------
=head2 www_listProducts ( $session )
Returns a list of products with manage and delete buttons.
=head3 $session
The current WebGUI session object.
=cut
sub www_listProducts {
my $session = shift;
my ($self, $sth, $output, $row, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, 'ProductManager');
$session->scratch->delete('managingProduct');
$sth = $session->db->read('select * from products order by title');
$output .= '<table>';
while ($row = $sth->hashRef) {
$output .= '<tr>';
$output .= '<td>';
$output .= $session->icon->delete('op=deleteProduct;productId='.$row->{productId}, undef, $i18n->get("confirm delete product"));
$output .= $session->icon->edit('op=manageProduct;productId='.$row->{productId});
$output .= '</td>';
$output .= '<td>'.$row->{title}.'</td>';
$output .= '</tr>';
}
$output .= '</table>';
return _submenu($session,$output, 'list products');
}
#-------------------------------------------------------------------
=head2 www_listProductVariants ( $session )
Returns a list of Product Variants.
=head3 $session
The current WebGUI session object.
=cut
sub www_listProductVariants {
my $session = shift;
my ($productId, $product, @variants, %parameters, %options, $output, %composition, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, "ProductManager");
$productId = $session->form->process("productId") || $session->scratch->get('managingProduct');
return WebGUI::Operation::execute($session,'listProducts') if ($productId eq 'new' || !$productId);
$product = WebGUI::Product->new($session,$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($session);
$output .= WebGUI::Form::hidden($session,{
name => 'op',
value => 'listProductVariantsSave',
});
$output .= WebGUI::Form::hidden($session,{
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($session,{
name => 'available',
value => $_->{variantId},
checked => $_->{available},
}).$session->icon->edit('op=editProductVariant;variantId='.$_->{variantId})."</td>";
$output .= "</tr>";
}
$output .= "</table>";
$output .= WebGUI::Form::submit($session,);
$output .= WebGUI::Form::formFooter($session,);
return _submenu($session,$output, 'list variants label');
}
#-------------------------------------------------------------------
=head2 www_listProductVariantsSave ( $session )
Saves the properties of some product variants.
=head3 $session
The current WebGUI session object.
=cut
sub www_listProductVariantsSave {
my $session = shift;
return $session->privilege->insufficient unless canView($session);
my %availableVariants = map {$_ => 1} $session->form->selectList('available');
my $product = WebGUI::Product->new($session,$session->form->process("productId"));
my @variants = @{$product->getVariant};
foreach (@variants) {
$product->setVariant($_->{variantId}, {
available => $availableVariants{$_->{variantId}} ? '1' : '0'});
}
return WebGUI::Operation::execute($session,'listProductVariants');
}
#-------------------------------------------------------------------
=head2 www_manageProduct ( $session )
Returns a screen that displays lots of options for editing all aspects of a product.
=head3 $session
The current WebGUI session object.
=cut
sub www_manageProduct {
my $session = shift;
my ($product, $output, $option, $i18n);
return $session->privilege->insufficient unless canView($session);
$i18n = WebGUI::International->new($session, "ProductManager");
my $productId = shift || $session->form->process("productId") || $session->scratch->get('managingProduct');
return WebGUI::Operation::execute($session,'listProducts') if ($productId eq 'new' || !$productId);
$session->scratch->set('managingProduct', $productId);
$product = WebGUI::Product->new($session,$productId);
$output .= "<h1>".$product->get('title')."</h1>";
$output .= "<h2>".$i18n->get('properties').$session->icon->edit('op=editProduct;productId='.$productId)."</h2>";
$output .= "<table>";
$output .= "<tr><td>".$i18n->get('productId')."</td><td>".$productId."</td></tr>";
$output .= "<tr><td>".$i18n->get('price')."</td><td>".$product->get('price')."</td></tr>";
my $useSalesTax = $product->get('useSalesTax')
? $i18n->get(138, 'WebGUI')
: $i18n->get(139, 'WebGUI');
$output .= "<tr><td>".$i18n->get('useSalesTax')."</td><td>".$useSalesTax."</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="'.$session->url->page('op=editProductParameter;parameterId=new;productId='.$product->get('productId')).'">'.
$i18n->get('add parameter').'</a><br />';
foreach my $parameter (@{$product->getParameter}) {
$output .= $session->icon->delete('op=deleteProductParameter;parameterId='.$parameter->{parameterId}).
$session->icon->edit('op=editProductParameter;parameterId='.$parameter->{parameterId});
$output .= '<span style="margin-left: 10px"><b>'.$parameter->{name}.'</b></span><br />';
$output .= '<a style="margin-left: 20px" href="'.
$session->url->page('op=editProductParameterOption;optionId=new;parameterId='.$parameter->{parameterId}).'">'.
$i18n->get('add option').'</a><br />';
foreach my $optionId (@{$parameter->{options}}) {
$option = $product->getOption($optionId);
$output .= '<span style="margin-left: 20px">'.
$session->icon->delete('op=deleteProductParameterOption;optionId='.$option->{optionId}).
$session->icon->edit('op=editProductParameterOption;parameterId='.$parameter->{parameterId}.';optionId='.$option->{optionId}).$option->{value}.'</span><br />';
}
$output .= '<br />';
}
return _submenu($session,$output, 'manage product');
}
1;

View file

@ -1,669 +0,0 @@
package WebGUI::Operation::Subscription;
use strict;
use WebGUI::SQL;
use WebGUI::HTMLForm;
use Tie::IxHash;
use WebGUI::Paginator;
use WebGUI::Subscription;
use WebGUI::Commerce::ShoppingCart;
use WebGUI::AdminConsole;
use WebGUI::Asset::Template;
use WebGUI::Form;
use WebGUI::International;
=head1 NAME
Package WebGUI::Operation::Subscription
=head1 DESCRIPTION
Operational handler for viewing, editing, listing, purchasing/redeeming, and deleting Subscriptions and Subscription Code Batches.
=head2 _generateCode ( $session, codeLength )
Generates a human-readable subscription code, meant to be typed/pasted in somewhere.
=head3 $session
The current WebGUI session object.
=head3 codeLength
The whole number amount of characters you want returned.
=cut
#-------------------------------------------------------------------
sub _generateCode {
my $session = shift;
my ($codeLength, @codeElements, $code, $i);
$codeLength = shift || 64;
@codeElements = ('A'..'Z', 'a'..'z', 0..9, '-');
for ($i=0; $i < $codeLength; $i++) {
$code .= $codeElements[rand(63)];
}
return $code;
}
=head2 _submenu ( $session )
Returns a rendered Admin Console view, with a standard list of five submenu items.
=head3 $session
The current WebGUI session object.
=head3 workarea
A scalar of HTML that defines the current workarea.
=head3 title
The i18n key of the title of this workarea.
=cut
#-------------------------------------------------------------------
sub _submenu {
my $session = shift;
my $i18n = WebGUI::International->new($session, "Subscription");
my $workarea = shift;
my $title = shift;
$title = $i18n->get($title) if ($title);
my $ac = WebGUI::AdminConsole->new($session,"subscriptions");
$ac->addSubmenuItem($session->url->page('op=editSubscription;sid=new'), $i18n->get('add subscription'));
$ac->addSubmenuItem($session->url->page('op=createSubscriptionCodeBatch'), $i18n->get('generate batch'));
$ac->addSubmenuItem($session->url->page('op=listSubscriptionCodes'), $i18n->get('manage codes'));
$ac->addSubmenuItem($session->url->page('op=listSubscriptionCodeBatches'), $i18n->get('manage batches'));
$ac->addSubmenuItem($session->url->page('op=listSubscriptions'), 'Manage Subscriptions');
return $ac->render($workarea, $title);
}
#----------------------------------------------------------------------------
=head2 canView ( session [, user] )
Returns true if the user can administrate this operation. user defaults to
the current user.
=cut
sub canView {
my $session = shift;
my $user = shift || $session->user;
return $user->isInGroup( $session->setting->get("groupIdAdminSubscription") );
}
#----------------------------------------------------------------------------
=head2 www_createSubscriptionCodeBatch ( $session, error )
Form to accept parameters to create a batch of subscription codes.
=head3 $session
The current WebGUI session object.
=head3 error
An HTML scalar of an error message to be returned to the user.
=cut
sub www_createSubscriptionCodeBatch {
my $session = shift;
my (%subscriptions, $f, $error, $errorMessage);
return $session->privilege->adminOnly() unless canView($session);
$error = shift;
my $i18n = WebGUI::International->new($session, "Subscription");
$errorMessage = $i18n->get('create batch error').'<ul><li>'.join('</li><li>', @{$error}).'</li></ul>' if ($error);
tie %subscriptions, "Tie::IxHash";
%subscriptions = $session->db->buildHash("select subscriptionId, name from subscription where deleted != 1 order by name");
$f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'createSubscriptionCodeBatchSave'
);
$f->integer(
-name => 'noc',
-label => $i18n->get('noc'),
-hoverHelp => $i18n->get('noc description'),
-value => $session->form->process("noc") || 1
);
$f->integer(
-name => 'codeLength',
-label => $i18n->get('code length'),
-hoverHelp => $i18n->get('code length description'),
-value => $session->form->process("codeLength") || 64
);
$f->interval(
-name => 'expires',
-label => $i18n->get('codes expire'),
-hoverHelp => $i18n->get('codes expire description'),
-value => $session->form->process("expires") || $session->datetime->intervalToSeconds(1, 'months')
);
my @sub = $session->form->selectList("subscriptionId");
$f->selectList(
-name => 'subscriptionId',
-label => $i18n->get('association'),
-hoverHelp => $i18n->get('association description'),
-options=> \%subscriptions,
-multiple=>1,
-size => 5,
-value => \@sub
);
$f->textarea(
-name => 'description',
-label => $i18n->get('batch description'),
-hoverHelp => $i18n->get('batch description description'),
-value => $session->form->process("description")
);
$f->submit;
return _submenu($session,$errorMessage.$f->print, 'create batch menu');
}
=head2 www_createSubscriptionCodeBatchSave ( $session )
Method that accepts the form parameters to create a batch of subscription codes.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_createSubscriptionCodeBatchSave {
my $session = shift;
my ($numberOfCodes, $description, $expires, $batchId, @codeElements, $currentCode, $code, $i, @subscriptions,
@error, $creationEpoch);
return $session->privilege->adminOnly() unless canView($session);
my $i18n = WebGUI::International->new($session, "Subscription");
$numberOfCodes = $session->form->process("noc");
$description = $session->form->process("description");
$expires = $session->form->interval('expires');
$batchId = $session->id->generate;
push(@error, $i18n->get('no description error')) unless ($description);
push(@error, $i18n->get('no association error')) unless ($session->form->process("subscriptionId"));
push(@error, $i18n->get('code length error')) unless ($session->form->process("codeLength") >= 10 && $session->form->process("codeLength") <= 64 && $session->form->process("codeLength") =~ m/^\d\d$/);
return www_createSubscriptionCodeBatch($session,\@error) if (@error);
$creationEpoch =$session->datetime->time();
$session->db->write("insert into subscriptionCodeBatch (batchId, description) values (".
$session->db->quote($batchId).", ".$session->db->quote($description).")");
for ($currentCode=0; $currentCode < $numberOfCodes; $currentCode++) {
$code = _generateCode($session,$session->form->process("codeLength"));
$code = _generateCode($session,$session->form->process("codeLength")) while ($session->db->quickArray("select code from subscriptionCode where code=".$session->db->quote($code)));
$session->db->write("insert into subscriptionCode (batchId, code, status, dateCreated, dateUsed, expires, usedBy)".
" values (".$session->db->quote($batchId).",".$session->db->quote($code).", 'Unused', ".$session->db->quote($creationEpoch).", 0, ".$session->db->quote($expires).", 0)");
@subscriptions = $session->form->selectList('subscriptionId');
foreach (@subscriptions) {
$session->db->write("insert into subscriptionCodeSubscriptions (code, subscriptionId) values (".
$session->db->quote($code).", ".$session->db->quote($_).")");
}
}
return www_listSubscriptionCodeBatches($session);
}
=head2 www_deleteSubscription ( $session )
Method that deletes the subscription passed by the user through the form variable 'sid'.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_deleteSubscription {
my $session = shift;
return $session->privilege->adminOnly() unless canView($session);
WebGUI::Subscription->new($session,$session->form->process("sid"))->delete;
return www_listSubscriptions($session);
}
=head2 www_deleteSubscriptionCodeBatch ( $session )
Method that deletes the subscription code batch passed by the user through the form variable 'bid'.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_deleteSubscriptionCodeBatch {
my $session = shift;
return $session->privilege->adminOnly() unless canView($session);
$session->db->write("delete from subscriptionCodeBatch where batchId=".$session->db->quote($session->form->process("bid")));
$session->db->write("delete from subscriptionCode where batchId=".$session->db->quote($session->form->process("bid")));
return www_listSubscriptionCodeBatches($session);
}
=head2 www_deleteSubscriptionCodes ( $session )
Method that deletes some subscription codes.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_deleteSubscriptionCodes {
my $session = shift;
return $session->privilege->adminOnly() unless canView($session);
if ($session->form->process("selection") eq 'dc') {
$session->db->write("delete from subscriptionCode where dateCreated >= ".$session->db->quote($session->form->process("dcStart")).
' and dateCreated <= '.$session->db->quote($session->form->process("dcStop")));
} elsif ($session->form->process("selection") eq 'du') {
$session->db->write("delete from subscriptionCode where dateUsed >= ".$session->db->quote($session->form->process("duStart")).
' and dateUsed <= '.$session->db->quote($session->form->process("duStop")));
}
return www_listSubscriptionCodes($session);
}
=head2 www_editSubscription ( $session )
Returns a form so the user can edit the properties of a subscription. Uses the form variable 'sid'.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_editSubscription {
my $session = shift;
my ($properties, $subscriptionId, $durationInterval, $durationUnits, $f);
return $session->privilege->adminOnly() unless canView($session);
my $i18n = WebGUI::International->new($session, "Subscription");
unless ($session->form->process("sid") eq 'new') {
$properties = WebGUI::Subscription->new($session,$session->form->process("sid"))->get;
}
$subscriptionId = $session->form->process("sid") || 'new';
$f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->hidden(
-name => 'op',
-value => 'editSubscriptionSave'
);
$f->hidden(
-name => 'sid',
-value => $subscriptionId
);
$f->readOnly(
-label => $i18n->get('subscriptionId'),
-value => $subscriptionId
);
$f->text(
-name => 'name',
-label => $i18n->get('subscription name'),
-hoverHelp => $i18n->get('subscription name description'),
-value => $properties->{name}
);
$f->float(
-name => 'price',
-label => $i18n->get('subscription price'),
-hoverHelp => $i18n->get('subscription price description'),
-value => $properties->{price} || '0.00'
);
$f->yesNo(
-name => 'useSalesTax',
-label => $i18n->get('useSalesTax'),
-hoverHelp => $i18n->get('useSalesTax description'),
-value => $properties->{useSalesTax} || 0,
);
$f->textarea(
-name => 'description',
-label => $i18n->get('subscription description'),
-hoverHelp => $i18n->get('subscription description description'),
-value => $properties->{description}
);
$f->group(
-name => 'subscriptionGroup',
-label => $i18n->get('subscription group'),
-hoverHelp => $i18n->get('subscription group description'),
-value => [$properties->{subscriptionGroup} || 2]
);
$f->selectBox(
-name => 'duration',
-label => $i18n->get('subscription duration'),
-hoverHelp => $i18n->get('subscription duration description'),
-value => $properties->{duration} || 'Monthly',
-options=> WebGUI::Commerce::Payment->recurringPeriodValues($session),
);
$f->text(
-name => 'executeOnSubscription',
-label => $i18n->get('execute on subscription'),
-hoverHelp => $i18n->get('execute on subscription description'),
-value => $properties->{executeOnSubscription}
);
if ($session->setting->get("useKarma")) {
$f->integer(
-name => 'karma',
-label => $i18n->get('subscription karma'),
-hoverHelp => $i18n->get('subscription karma description'),
-value => $properties->{karma} || 0
);
}
$f->submit;
return _submenu($session,$f->print, 'edit subscription title');
}
=head2 www_editSubscriptionSave ( $session )
Saves the properties of a subscription.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_editSubscriptionSave {
my $session = shift;
my (@relevantFields);
return $session->privilege->adminOnly() unless canView($session);
my $properties = {};
@relevantFields = qw(subscriptionId name useSalesTax price description subscriptionGroup duration executeOnSubscription karma);
foreach (@relevantFields) {
$properties->{$_} = $session->form->process($_) if (defined $session->form->process($_));
}
WebGUI::Subscription->new($session,$session->form->process("sid"))->set($properties);
return www_listSubscriptions($session);
}
=head2 www_listSubscriptionCodeBatches ( $session )
Returns a paginated list of batches of subscription codes, along with various links for each one.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_listSubscriptionCodeBatches {
my $session = shift;
my ($p, $batches, $output);
return $session->privilege->adminOnly() unless canView($session);
my $i18n = WebGUI::International->new($session, "Subscription");
$p = WebGUI::Paginator->new($session,$session->url->page('op=listSubscriptionCodeBatches'));
$p->setDataByQuery("select * from subscriptionCodeBatch");
$batches = $p->getPageData;
$output = $p->getBarTraditional($session->form->process("pn"));
$output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">';
foreach (@{$batches}) {
$output .= '<tr><td>';
$output .= $session->icon->delete('op=deleteSubscriptionCodeBatch;bid='.$_->{batchId}, undef, $i18n->get('delete batch confirm'));
$output .= '<td>'.$_->{description}.'</td>';
$output .= '<td><a href="'.$session->url->page('op=listSubscriptionCodes;selection=b;bid='.$_->{batchId}).'">'.$i18n->get('list codes in batch').'</a></td>';
$output .= '</tr>';
}
$output .= '</table>';
$output .= $p->getBarTraditional($session->form->process("pn"));
$output = $i18n->get('no subscription code batches') unless (@{$batches});
return _submenu($session,$output, 'manage batches');
}
=head2 www_listSubscriptionCodes ( $session )
Non-templated. Returns a paginated list of subscription codes.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_listSubscriptionCodes {
my $session = shift;
my ($p, $codes, $output, $where, $ops, $delete);
return $session->privilege->adminOnly() unless canView($session);
my $i18n = WebGUI::International->new($session, "Subscription");
my $dcStart = $session->form->date('dcStart');
my $dcStop = $session->datetime->addToTime($session->form->date('dcStop'),23,59);
my $duStart = $session->form->date('duStart');
my $duStop = $session->datetime->addToTime($session->form->date('duStop'),23,59);
my $batches = $session->db->buildHashRef("select batchId, description from subscriptionCodeBatch");
$output .= $i18n->get('selection message');
$output .= WebGUI::Form::formHeader($session);
$output .= WebGUI::Form::hidden($session,{name=>'op', value=>'listSubscriptionCodes'});
$output .= '<table>';
$output .= '<td>'.WebGUI::Form::radio($session,{name=>'selection', value => 'du', checked=>($session->form->process("selection") eq 'du')}).'</td>';
$output .= '<td align="left">'.$i18n->get('selection used').'</td>';
$output .= '<td>'.WebGUI::Form::date($session,{name=>'duStart', value=>$duStart}).' '.$i18n->get('and').' '.WebGUI::Form::date($session,{name=>'duStop', value=>$duStop}).'</td>';
$output .= '</tr><tr>';
$output .= '<td>'.WebGUI::Form::radio($session,{name=>'selection', value => 'dc', checked=>($session->form->process("selection") eq 'dc')}).'</td>';
$output .= '<td align="left">'.$i18n->get('selection created').'</td>';
$output .= '<td>'.WebGUI::Form::date($session,{name=>'dcStart', value=>$dcStart}).' '.$i18n->get('and').' '.WebGUI::Form::date($session,{name=>'dcStop', value=>$dcStop}).'</td>';
$output .= '</tr><tr>';
$output .= '<td>'.WebGUI::Form::radio($session,{name=>'selection', value => 'b', checked=>($session->form->process("selection") eq 'b')}).'</td>';
$output .= '<td align="left">'.$i18n->get('selection batch id').'</td>';
$output .= '<td>'.WebGUI::Form::selectList($session,{name => 'bid', value => [$session->form->process("bid")], options => $batches});
$output .= '</tr><tr>';
$output .= '<td></td>';
$output .= '<td>'.WebGUI::Form::submit($session,{value=>$i18n->get('select')}).'</td>';
$output .= '</tr>';
$output .= '</table>';
$output .= WebGUI::Form::formFooter;
if ($session->form->process("selection") eq 'du') {
$where = " and dateUsed >= ".$session->db->quote($duStart)." and dateUsed <= ".$session->db->quote($duStop);
$ops = ';duStart='.$duStart.';duStop='.$duStop.';selection=du';
$delete = '<a href="'.$session->url->page('op=deleteSubscriptionCodes'.$ops).'">'.$i18n->get('delete codes').'</a>';
} elsif ($session->form->process("selection") eq 'dc') {
$where = " and dateCreated >= ".$session->db->quote($dcStart)." and dateCreated <= ".$session->db->quote($dcStop);
$ops = ';dcStart='.$dcStart.';dcStop='.$dcStop.';selection=dc';
$delete = '<a href="'.$session->url->page('op=deleteSubscriptionCodes'.$ops).'">'.$i18n->get('delete codes').'</a>';
} elsif ($session->form->process("selection") eq 'b') {
$where = " and t1.batchId=".$session->db->quote($session->form->process("bid"));
$ops = ';bid='.$session->form->process("bid").';selection=b';
$delete = '<a href="'.$session->url->page('op=deleteSubscriptionCodeBatch'.$ops).'">'.$i18n->get('delete codes').'</a>';
} else {
return _submenu($session,$output, 'listSubscriptionCodes title');
}
$p = WebGUI::Paginator->new($session,$session->url->page('op=listSubscriptionCodes'.$ops));
$p->setDataByQuery("select t1.*, t2.* from subscriptionCode as t1, subscriptionCodeBatch as t2 where t1.batchId=t2.batchId ".$where);
$codes = $p->getPageData;
$output .= '<br />'.$delete.'<br />' if ($delete);
$output .= $p->getBarTraditional($session->form->process("pn"));
$output .= '<br />';
$output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">';
$output .= '<tr>';
$output .= '<th>'.$i18n->get('batch id').'</th><th>'.$i18n->get('code').'</th><th>'.$i18n->get('creation date').
'</th><th>'.$i18n->get('dateUsed').'</th><th>'.$i18n->get('status').'</th>'; $output .= '</tr>';
foreach (@{$codes}) {
$output .= '<tr>';
$output .= '<td>'.$_->{batchId}.'</td>';
$output .= '<td>'.$_->{code}.'</td>';
$output .= '<td>'.$session->datetime->epochToHuman($_->{dateCreated}).'</td>';
$output .= '<td>';
$output .= $session->datetime->epochToHuman($_->{dateUsed}) if ($_->{dateUsed});
$output .= '</td>';
$output .= '<td>'.$_->{status}.'</td>';
$output .= '</tr>';
}
$output .= '</table>';
$output .= $p->getBarTraditional($session->form->process("pn"));
return _submenu($session,$output, 'listSubscriptionCodes title');
}
=head2 www_listSubscriptions ( $session )
Returns a paginated list of subscriptions along with edit and delete links.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_listSubscriptions {
my $session = shift;
my ($p, $subscriptions, $output);
return $session->privilege->adminOnly() unless canView($session);
my $i18n = WebGUI::International->new($session, "Subscription");
$p = WebGUI::Paginator->new($session,$session->url->page('op=listSubscriptions'));
$p->setDataByQuery('select subscriptionId, name from subscription where deleted != 1');
$subscriptions = $p->getPageData;
$output = $p->getBarTraditional($session->form->process("pn"));
$output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">';
foreach (@{$subscriptions}) {
$output .= '<tr>';
$output .= '<td>'.$session->icon->edit('op=editSubscription;sid='.$_->{subscriptionId});
$output .= $session->icon->delete('op=deleteSubscription;sid='.$_->{subscriptionId}, undef, $i18n->get('delete subscription confirm')).'</td>';
$output .= '<td>'.$_->{name}.'</td>';
$output .= '</tr>';
}
$output .= '</table>';
$output .= $p->getBarTraditional($session->form->process("pn"));
$output = $i18n->get('no subscriptions') unless (@{$subscriptions});
return _submenu($session,$output, 'manage subscriptions');
}
=head2 www_purchaseSubscription ( $session )
Adds subscription 'sid' to the user's shopping cart and returns the checkout screen.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_purchaseSubscription {
my $session = shift;
WebGUI::Commerce::ShoppingCart->new($session)->add($session->form->process("sid"), 'Subscription');
$session->http->setRedirect($session->url->page('op=checkout'));
return undef;
}
=head2 www_redeemSubscriptionCode ( $session )
Returns a form so the user can redeem a subscription code, or actually redeems the subscription code.
=head3 $session
The current WebGUI session object.
=cut
#-------------------------------------------------------------------
sub www_redeemSubscriptionCode {
my $session = shift;
my (%codeProperties, @subscriptions, %var, $f);
my $i18n = WebGUI::International->new($session, "Subscription");
if ($session->form->process("code")) {
%codeProperties = $session->db->quickHash("select * from subscriptionCode as t1, subscriptionCodeBatch as t2 where ".
"t1.batchId = t2.batchId and t1.code=".$session->db->quote($session->form->process("code"))." and (t1.dateCreated + t1.expires) > ".$session->db->quote(time));
if ($codeProperties{status} eq 'Unused') {
# Code is ok
@subscriptions = $session->db->buildArray("select subscriptionId from subscriptionCodeSubscriptions where code=".$session->db->quote($session->form->process("code")));
foreach (@subscriptions) {
WebGUI::Subscription->new($session,$_)->apply;
}
# Set code to Used
$session->db->write("update subscriptionCode set status='Used', dateUsed=".$session->db->quote(time)." where code=".$session->db->quote($session->form->process("code")));
$var{batchDescription} = $codeProperties{description};
$var{message} = $i18n->get('redeem code success');
} else {
$var{message} = $i18n->get('redeem code failure');
}
} else {
$var{message} = $i18n->get('redeem code ask for code');
}
$f = WebGUI::HTMLForm->new($session);
$f->hidden(
-name => 'op',
-value => 'redeemSubscriptionCode'
);
$f->text(
-name => 'code',
-label => $i18n->get('code'),
-hoverHelp => $i18n->get('code description'),
-maxLength => 64,
-size => 30
);
$f->submit;
$var{codeForm} = $f->print;
return $session->style->userStyle(WebGUI::Asset::Template->new($session,"PBtmpl0000000000000053")->process(\%var));
}
1;

View file

@ -1,432 +0,0 @@
package WebGUI::Product;
use strict;
use WebGUI::Asset::Template;
#-------------------------------------------------------------------
sub _permute {
my ($currentSet, @permutations, @result);
$currentSet = shift;
@permutations = (@_) ? _permute(@_) : [];
foreach my $permutation (@permutations) {
foreach my $value (@$currentSet) {
push(@result, [$value, @{$permutation}]);
}
}
return @result;
}
#-------------------------------------------------------------------
sub addOptionToParameter {
my ($self, $parameterId, $properties, $optionId);
$self = shift;
$parameterId = shift;
$properties = shift || {};
$optionId = $self->session->id->generate;
$self->session->db->write("insert into productParameterOptions ".
"(optionId, parameterId) values ".
"(".$self->session->db->quote($optionId).", ".$self->session->db->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 = $self->session->id->generate;
$self->session->db->write("insert into productParameters (parameterId, productId) values ".
"(".$self->session->db->quote($parameterId).", ".$self->session->db->quote($self->get('productId')).")");
$self->{_parameters}->{$parameterId}->{parameterId} = $parameterId;
$self->{_parameters}->{$parameterId}->{options} = [];
return $parameterId;
}
#-------------------------------------------------------------------
sub delete {
my ($self) = shift;
foreach (@{$self->getParameter}) {
$self->session->db->write("delete from productParameterOptions where parameterId=".$self->session->db->quote($_->{parameterId}));
}
$self->session->db->write("delete from productParameters where productId=".$self->session->db->quote($self->get('productId')));
$self->session->db->write("delete from productVariants where productId=".$self->session->db->quote($self->get('productId')));
$self->session->db->write("delete from products where productId=".$self->session->db->quote($self->get('productId')));
return undef;
}
#-------------------------------------------------------------------
sub deleteParameter {
my ($self, $parameterId);
$self = shift;
$parameterId = shift;
$self->session->db->write("delete from productParameterOptions where parameterId=".$self->session->db->quote($parameterId));
$self->session->db->write("delete from productParameters where parameterId=".$self->session->db->quote($parameterId));
$self->updateVariants;
return undef;
}
#-------------------------------------------------------------------
sub deleteOption {
my ($self, $optionId, @options, $parameterId);
$self = shift;
$optionId = shift;
$self->session->db->write("delete from productParameterOptions where optionId=".$self->session->db->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;
my $session = shift;
$optionId = shift;
($productId) = $session->db->quickArray("select productId from productParameters as t1, productParameterOptions as t2 ".
"where t1.parameterId=t2.parameterId and t2.optionId=".$session->db->quote($optionId));
return undef unless ($productId);
return WebGUI::Product->new($session,$productId);
}
#-------------------------------------------------------------------
sub getByParameterId {
my ($class, $parameterId, $productId);
$class = shift;
my $session = shift;
$parameterId = shift;
($productId) = $session->db->quickArray("select productId from productParameters where parameterId=".$session->db->quote($parameterId));
return WebGUI::Product->new($session,$productId);
}
#-------------------------------------------------------------------
sub getByVariantId {
my ($class, $productId, $variantId);
$class = shift;
my $session = shift;
$variantId = shift;
($productId) = $session->db->quickArray("select productId from productVariants where variantId=".$session->db->quote($variantId));
return WebGUI::Product->new($session,$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;
my $session = shift;
$productId = shift;
$session->errorHandler->fatal('no productId') unless ($productId);
$parameters = {};
$variants = {};
$options = {};
if ($productId eq 'new') {
$productId = $session->id->generate;
$properties = {productId => $productId};
$session->db->write("insert into products (productId) values (".$session->db->quote($productId).")");
} else {
$properties = $session->db->quickHashRef("select * from products where productId=".$session->db->quote($productId));
# fetch parameters and options
$sth = $session->db->read("select opt.*, param.* from productParameters as param left join productParameterOptions as opt ".
"on param.parameterId=opt.parameterId where param.productId=".$session->db->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 = $session->db->read("select * from productVariants where productId=".$session->db->quote($productId));
while (%row = $sth->hash) {
$variants->{$row{variantId}} = {%row};
}
$new = 0;
}
bless {_session=> $session, _properties => $properties, _parameters => $parameters, _options => $options, _variants => $variants, _new => $new}, $class;
}
#-------------------------------------------------------------------
=head2 session ( )
Returns a reference to the session.
=cut
sub session {
my $self = shift;
return $self->{_session};
}
#-------------------------------------------------------------------
sub set {
my ($self, $properties);
$self = shift;
$properties = shift;
$self->session->db->write("update products set ".join(', ', map {$_."=".$self->session->db->quote($properties->{$_})} keys(%$properties)).
" where productId=".$self->session->db->quote($self->get('productId')));
foreach (keys(%$properties)) {
$self->{_properties}->{$_} = $properties->{$_};
}
$self->updateVariants;
}
#-------------------------------------------------------------------
sub setParameter {
my ($self, $parameterId, $properties);
$self = shift;
$parameterId = shift;
$properties = shift;
$self->session->db->write("update productParameters set ".join(', ', map {$_."=".$self->session->db->quote($properties->{$_})} keys(%$properties)).
" where parameterId=".$self->session->db->quote($parameterId));
map {$self->{_parameter}->{$parameterId}->{$_} = $properties->{$_}} keys %$properties;
}
#-------------------------------------------------------------------
sub setOption {
my ($self, $optionId, $properties);
$self = shift;
$optionId = shift;
$properties = shift;
$self->session->db->write("update productParameterOptions set ".join(', ', map {$_."=".$self->session->db->quote($properties->{$_})} keys(%$properties)).
" where optionId=".$self->session->db->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->session, $self->get('skuTemplate'), \%sku );
if (defined $properties->{price}) {
if ($properties->{price} ne '') {
push(@pairs, 'price='.$self->session->db->quote($properties->{price}).', priceOverride=1');
} else {
push(@pairs, 'price='.$self->session->db->quote($original->{price}).', priceOverride=0');
}
}
if (defined $properties->{weight}) {
if ($properties->{weight} ne '') {
push(@pairs, 'weight='.$self->session->db->quote($properties->{weight}).', weightOverride=1');
} else {
push(@pairs, 'weight='.$self->session->db->quote($original->{weight}).', weightOverride=0');
}
}
if (defined $properties->{sku}) {
if ($properties->{sku} ne '') {
push(@pairs, 'sku='.$self->session->db->quote($properties->{sku}).', skuOverride=1');
} else {
push(@pairs, 'sku='.$self->session->db->quote($original->{sku}).', skuOverride=0');
}
}
push(@pairs, 'available='.$self->session->db->quote($properties->{available})) if (defined $properties->{available});
$self->session->db->write("update productVariants set ".join(', ', @pairs)." where variantId=".$self->session->db->quote($variantId)) if (@pairs);
$self->{_variants}->{$variantId} = {%{$self->{_variants}->{$variantId}}, %$properties};
}
#-------------------------------------------------------------------
sub updateVariants {
my ($self, %variants, @optionSets, @variants, %var, @composition, @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 my $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 my $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->session, $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} = $self->session->id->generate;
}
push (@newVariants, {%var});
$newVariants{$var{variantId}} = {%var};
}
$self->session->db->write("delete from productVariants where productId=".$self->session->db->quote($self->get('productId')));
foreach (values %newVariants) {
$self->session->db->write("insert into productVariants (variantId, productId, composition, price, weight, sku, available) values ".
"(".$self->session->db->quote($_->{variantId}).", ".$self->session->db->quote($_->{productId}).", ".$self->session->db->quote($_->{composition}).", ".$self->session->db->quote($_->{price}).
", ".$self->session->db->quote($_->{weight}).", ".$self->session->db->quote($_->{sku}).", ".$self->session->db->quote($_->{available}).")");
}
$self->{_variants} = \%newVariants;
}
1;

View file

@ -1,220 +0,0 @@
package WebGUI::Subscription;
use strict;
use WebGUI::Macro;
use WebGUI::Utility;
use WebGUI::Commerce::Payment;
=head1 NAME
Package WebGUI::Subscription
=head1 DESCRIPTION
Base class for subscriptions
=head2 _getDuration ( duration, time )
Internal utility function for calculating when a subscription expires.
Returns the date in epoch format when it expires.
=head3 duration
Text description of how long the subscription lasts.
=head3 time
time from which to calculate expiration date
=cut
sub _getDuration {
my $self = shift;
my $duration = shift;
my $now = shift || time();
return $self->session->datetime->addToDate($now,0,0,7) if $duration eq 'Weekly';
return $self->session->datetime->addToDate($now,0,0,14) if $duration eq 'BiWeekly';
return $self->session->datetime->addToDate($now,0,0,28) if $duration eq 'FourWeekly';
return $self->session->datetime->addToDate($now,0,1,0) if $duration eq 'Monthly';
return $self->session->datetime->addToDate($now,0,3,0) if $duration eq 'Quarterly';
return $self->session->datetime->addToDate($now,0,6,0) if $duration eq 'HalfYearly';
return $self->session->datetime->addToDate($now,1,0,0) if $duration eq 'Yearly';
}
#-------------------------------------------------------------------
=head2 _getExpireOffset (durationType)
Returns the offset in seconds based on what is passed in
=head3 durationType
Text descriptoin of how long the subscription lasts
=cut
sub _getExpireOffset {
my $self = shift;
my $duration = shift;
my $now = time();
my $durationExpirationDate = $self->_getDuration($duration,$now);
return ($durationExpirationDate - $now);
}
#-------------------------------------------------------------------
=head2 apply ( [ $userId ] )
Method for subscribing a user. Adds user to the proper group and sets the expiration date,
adds karma to the user for purchasing a subscription, and then runs any external commands
as specified by the executeOnSubscription property. Macros in executeOnSubscription are
expanded before the command is executed.
=head3 userId
ID of the user purchasing the subscription. If omitted, uses the current user as
specified by the session variable.
=cut
sub apply {
my ($self, $userId, $groupId);
$self = shift;
$userId = shift || $self->session->user->userId;
$groupId = $self->{_properties}{subscriptionGroup};
my $group = WebGUI::Group->new($self->session,$groupId);
# Make user part of the right group
$group->addUsers([$userId], $self->_getExpireOffset($self->{_properties}{duration}));
# Add karma
WebGUI::User->new($self->session,$userId)->karma($self->{_properties}{karma}, 'Subscription', 'Added for purchasing subscription '.$self->{_properties}{name});
# Process executeOnPurchase field
my $command = $self->{_properties}{executeOnSubscription};
WebGUI::Macro::process($self->session,\$command);
system($command) if ($self->{_properties}{executeOnSubscription} ne "");
}
#-------------------------------------------------------------------
=head2 delete
Method for deleting a subscription. Marks the subscription as deleted in the database
but does not remove it from the database.
=cut
sub delete {
my ($self);
$self = shift;
$self->session->db->write("update subscription set deleted=1 where subscriptionId=".$self->session->db->quote($self->{_subscriptionId}));
$self->{_properties}{deleted} = 1;
}
#-------------------------------------------------------------------
=head2 get ( $key )
Generic assessor method for Subscription objects.
=head3 key
Returns only the requested property. Returns undef if the key does not exist
in the object properties. Returns the entire property hash if the key is
false (0, undef, '');
=cut
sub get {
my ($self, $key) = @_;
return $self->{_properties}{$key} if ($key);
return $self->{_properties};
}
#-------------------------------------------------------------------
=head2 new ( session, subscriptionId )
Object creation method.
=head3 session
A reference to the current session.
=head3 subscriptionId
ID of the subscription to create. If this subscriptionId exists in the
database, the object created will be fully populated with properties
from the database.
=cut
sub new {
my ($class, $subscriptionId, %properties);
$class = shift;
my $session = shift;
$subscriptionId = shift;
if ($subscriptionId eq 'new') {
$subscriptionId = $session->id->generate;
$session->db->write("insert into subscription (subscriptionId) values (".$session->db->quote($subscriptionId).")");
}
%properties = $session->db->quickHash("select * from subscription where subscriptionId=".$session->db->quote($subscriptionId));
bless {_session=>$session, _subscriptionId => $subscriptionId, _properties => \%properties}, $class;
}
#-------------------------------------------------------------------
=head2 session ( )
Returns a reference to the current session.
=cut
sub session {
my $self = shift;
return $self->{_session};
}
#-------------------------------------------------------------------
=head2 set ( $properties )
Returns the date in epoch format when it expires.
=head3 $properties
A hashref containing properties to set in the object. Only valid properties will be
set. Also updates the subscription record in the database with properties that have
been set.
=head3 Valid Object properties
name price description subscriptionGroup duration executeOnSubscription karma
=cut
sub set {
my ($self, $properties, @fieldsToUpdate);
$self = shift;
$properties = shift;
foreach (keys(%{$properties})) {
if (isIn($_, qw(name price useSalesTax description subscriptionGroup duration executeOnSubscription karma))) {
$self->{_properties}{$_} = $properties->{$_};
push(@fieldsToUpdate, $_);
}
}
$self->session->db->write("update subscription set ".
join(',', map {"$_=".$self->session->db->quote($properties->{$_})} @fieldsToUpdate).
" where subscriptionId=".$self->session->db->quote($self->{_subscriptionId}));
}
1;

View file

@ -1,660 +0,0 @@
package WebGUI::i18n::English::Commerce;
use strict;
our $I18N = {
'purchase history template' => {
message => q|View Purchase History Template|,
lastUpdated => 0,
context => q|the title for the workflow activity that processes recurring payments|
},
'purchase history template description' => {
message => q|Controls the layout of the View Purchase History screen. This screen is displayed to the user after a successful checkout is made and shows them all of their past purchases.|,
lastUpdated => 0,
context => q|the title for the workflow activity that processes recurring payments|
},
'process recurring payments' => {
message => q|Process Recurring Payments|,
lastUpdated => 0,
context => q|the title for the workflow activity that processes recurring payments|
},
'commerce settings' => {
message => q|Commerce (beta)|,
lastUpdated => 1101772584,
context => q|The displayed title of the Commerce Settings in the Admin Console|
},
'pay button' => {
message => q|Pay|,
lastUpdated => 0,
context => q|The button on the checkout form.|
},
'checkout confirm title' => {
message => q|Please fill in the form below to purchase these products.|,
lastUpdated => 0,
context => q|Message in the checkout form.|
},
'general tab' => {
message => q|General|,
lastUpdated => 0,
context => q|The name of the 'general' tab in editCommerce.|
},
'payment tab' => {
message => q|Payment Plugins|,
lastUpdated => 0,
context => q|The name of the 'payment plugins' tab in editCommerce.|
},
'payment plugin' => {
message => q|Payment Plugin|,
lastUpdated => 0,
context => q|The name of the 'payment plugin' form option in editCommerce.|
},
'confirm checkout template' => {
message => q|Confirm checkout template|,
lastUpdated => 0,
context => q|Form label indicating the Confirm checkout template.|
},
'checkout canceled template' => {
message => q|Checkout canceled template|,
lastUpdated => 0,
context => q|Form label indicating the Checkout canceled template.|
},
'transaction error template' => {
message => q|Transaction error template|,
lastUpdated => 0,
context => q|Form label indicating the Transaction error template.|
},
'no payment gateway' => {
message => q|No payment gateway selected.|,
lastUpdated => 0,
context => q|An error message that shows up during checkout process if no payment gateway has been selected|
},
'edit commerce settings title' => {
message => q|Manage Commerce Settings|,
lastUpdated => 0,
context => q|Title of the Commerce part of the Admin Console.|
},
'confirm checkout template description' => {
message => q|<p>This template is shown when a user is asked to confirm his purchase. The form data for the payment gateway is also shown here.</p>|,
lastUpdated => 1138922899,
},
'transaction error template description' => {
message => q|<p>This is the template that's shown if any error occurs during the payment process. This could be a declined credit card or a false cvv2 code, for instance. Also an 'error' is triggered by a fraud protection filter or some other service that requires manual interaction from the merchant.</p>|,
lastUpdated => 1138922899,
},
'checkout canceled template description' => {
message => q|<p>This is the template that the user sees when he cancels the transaction. This normally only occurs with remote-side payment gateways (like PayPal). This is because a site-side payment gateway usually uses a single step process.</p>|,
lastUpdated => 1138922899,
},
'checkout select payment template description' => {
message => q|<p>This is the template that the user sees when he selects a payment after confirming checkout.</p>|,
lastUpdated => 1138923865,
},
'checkout select shipping template description' => {
message => q|<p>This is the template that the user sees when he selects a shipping method.</p>|,
lastUpdated => 1138923865,
},
'view shopping cart template description' => {
message => q|<p>This is the template to customize the display of the user's shopping cart.</p>|,
lastUpdated => 1138923865,
},
'shipping plugin label description' => {
message => q|<p>Select all plugins that can be used for shipping on your site.</p>|,
lastUpdated => 1138924101,
},
'daily report email description' => {
message => q|<p>Everyday the scheduler plugin that checks and updates subscriptions sends a report with the successful and failed term payments. Here you can set to which email address it should send this report.</p>|,
lastUpdated => 1138922899,
},
'payment plugin description' => {
message => q|<p>You can select the payment plugin to use here. Please note that you have to enable the plugins you want to choose from in the WebGUI configuration file. If you don't do this they won't show up here.</p>
|,
lastUpdated => 1147797861,
},
'manage commerce settings' => {
message => q|Manage commerce settings.|,
lastUpdated => 1101772609,
context => q|The menu title for 'Manage commerce settings' in the AdminConsole side menu.|
},
'pending transactions' => {
message => q|Show pending transactions.|,
lastUpdated => 1101772617,
context => q|The menu title for 'Show pending transactions' in the AdminConsole side menu.|
},
'username' => {
message => q|User|,
lastUpdated => 0,
},
'transactionId' => {
message => q|TransactionId|,
lastUpdated => 0,
context => q|TransactionId, just leave it as it is.|
},
'gatewayId' => {
message => q|Gateway ID|,
lastUpdated => 0,
context => q|Gateway ID is the ID the transaction is given by the payment gateway.|,
},
'init date' => {
message => q|Initiation Date|,
lastUpdated => 0,
context => q|The date on which the transaction was started|
},
'gateway' => {
message => q|Gateway|,
lastUpdated => 0,
context => q|Table header of the column that identifies the gateway through which the transaction went.|
},
'weekly' => {
message => q|Week|,
lastUpdated => 0,
context => q|Period name for a weekly subscription.|
},
'biweekly' => {
message => q|Two weeks|,
lastUpdated => 0,
context => q|Period name for a biweekly subscription.|
},
'fourweekly' => {
message => q|Four weeks|,
lastUpdated => 0,
context => q|Period name for a four weekly subscription.|
},
'monthly' => {
message => q|Month|,
lastUpdated => 0,
context => q|Period name for a monthly subscription.|
},
'quarterly' => {
message => q|Three months|,
lastUpdated => 0,
context => q|Period name for a Quarterly subscription.|
},
'halfyearly' => {
message => q|Half year|,
lastUpdated => 0,
context => q|Period name for a semi yearly subscription.|
},
'yearly' => {
message => q|Year|,
lastUpdated => 0,
context => q|Period name for a yearly subscription.|
},
'transaction error' => {
message => q|Transaction Error|,
lastUpdated => 0,
context => q|Name for 'transaction error' status in the Commerce/TransactionError template.|
},
'connection error' => {
message => q|Connection Error|,
lastUpdated => 0,
context => q|Name for 'connection error' status in the Commerce/TransactionError template.|
},
'pending' => {
message => q|Pending|,
lastUpdated => 0,
context => q|Name for 'pending' status in the Commerce/TransactionError template.|
},
'ok' => {
message => q|OK|,
lastUpdated => 0,
context => q|Name for 'OK' status in the Commerce/TransactionError template.|
},
'transaction error title' => {
message => q|An error has occurred in one or more transactions|,
lastUpdated => 0,
context => q|The title used in the transaction error template.|
},
'status codes information' => {
message => q|<p>The status codes have the following meaning:</p>
<table border="0" cellspacing="0" cellpadding="5">
<tr>
<td valign="top" align="right"><b>^International("ok","Commerce");</b></td>
<td valign="top" align="left">This means that this transaction has been completed successfully. You have purchased the product.</td>
</tr><tr>
<td valign="top" align="right"><b>^International("pending","Commerce");</b></td>
<td valign="top" align="left">This means that this transaction is under review. This could have a number of causes, and normally this transaction is processed within a short time.</td>
</tr><tr>
<td valign="top" align="right"><b>^International("transaction error","Commerce");</b></td>
<td valign="top" align="left">An unrecoverable error happened while processing the transaction.</td>
</tr><tr>
<td valign="top" align="right"><b>^International("transaction error","Commerce");</b></td>
<td valign="top" align="left">Something went wrong with the connection to the payment gateway. The admin has been notified.</td>
</tr>
</table>|,
lastUpdated => 1110148219,
context => q|A message that explains the status codes that are returned in the transaction error template.|
},
'daily report email' => {
message => q|Send daily report to|,
lastUpdated => 0,
context => q|Form label that asks whom to send the daily recurring payments report to.|
},
'checkout canceled message' => {
message => q|The checkout process has been canceled.|,
lastUpdated => 0,
context => q|A message that's shown to users that cancel their checkout.|
},
'complete pending transaction' => {
message => q|Complete transaction|,
lastUpdated => 0,
context => q|Label for the link that allows you to complete a pending transaction.|
},
'list pending transactions' => {
message => q|List pending transactions|,
lastUpdated => 0,
},
'help cancel checkout template title' => {
message => q|Cancel checkout template variables|,
lastUpdated => 1184790373,
context => q|The title of the help page of the cancel checkout template.|
},
'message' => {
message => q|The internationalized cancellation message.|,
lastUpdated => 1149221050,
},
'title' => {
message => q|The title to use for this template.|,
lastUpdated => 1149221320,
},
'normalItems' => {
message => q|The number of normal items in the shopping cart.|,
lastUpdated => 1149221320,
},
'normalItemLoop' => {
message => q|A loop containing the normal items in the shopping-cart. The following template variables are available in this loop:|,
lastUpdated => 1149221320,
},
'quantity' => {
message => q|The quantity of the current item in the shopping cart.<br />|,
lastUpdated => 1161319738,
},
'period' => {
message => q|The period of the recurring payment.<br />|,
lastUpdated => 1161319740,
},
'name' => {
message => q|The name of this item.<br />|,
lastUpdated => 1161319741,
},
'price' => {
message => q|The price of one item.<br />|,
lastUpdated => 1161319747,
},
'totalPrice' => {
message => q|The price of the quantity of this item. (totalPrice = quantity * price)|,
lastUpdated => 1161319749,
},
'salesTax' => {
message => q|The amount of sales tax for this item.|,
lastUpdated => 1161319799,
},
'salesTaxRate' => {
message => q|The sales tax rate, as determined by the user's homeState in his/her profile.|,
lastUpdated => 1165449949,
},
'totalSalesTax' => {
message => q|The sum of all sales taxes applied to eligible items.|,
lastUpdated => 1161319799,
},
'recurringItems' => {
message => q|The number of recurring items in the shopping cart.|,
lastUpdated => 1149221320,
},
'recurringItemLoop' => {
message => q|A loop containing the recurring items in the shopping cart. For available template variables see <p><b>normalItemLoop</b>|,
lastUpdated => 1161320125,
},
'form' => {
message => q|The form that's generated by the selected payment plugin.|,
lastUpdated => 1149221320,
},
'help checkout confirm template title' => {
message => q|Confirm checkout template variables|,
lastUpdated => 0,
context => q|The title of the help page of the confirm checkout template.|
},
'statusExplanation' => {
message => q|A message which explains the possible statuses an item can have|,
lastUpdated => 1149221449,
},
'resultLoop' => {
message => q|A template loop containing the items that were checked out.|,
lastUpdated => 1149221449,
},
'purchaseDescription' => {
message => q|The description of this transaction.<br />|,
lastUpdated => 1161319762,
},
'status' => {
message => q|The status of this item.<br />|,
lastUpdated => 1161319763,
},
'error' => {
message => q|The error text returned from the payment plugin.<br />|,
lastUpdated => 1161319765,
},
'errorCode' => {
message => q|The error code returned from the payment plugin.<br />|,
lastUpdated => 1161319767,
},
'help checkout error template title' => {
message => q|Checkout error template variables|,
lastUpdated => 1101791348,
context => q|The title of the help page of the checkout error template.|
},
'no payment plugins selected' => {
message => q|There are no payment plugins to select. Please enable plugins in the config file.|,
lastUpdated => 0,
context => q|The message that's shown in the AdminConsole/Commerce menu when there are no payment plugins enabled.|
},
'failed payment plugins' => {
message => q|The following Payment Plugins failed to compile, please check your log for more information: |,
lastUpdated => 1101881907,
context => q|The message that says which payment plugins did not compile.|
},
'select payment gateway'=> {
message => q|Please select a payment gateway.|,
lastUpdated => 0,
context => q|The message that asks the user to select a payment gateway.|
},
'payment gateway select' => {
message => q|Select gateway|,
lastUpdated => 0,
context => q|The text on the submit button of the select gateway form.|
},
'checkout select payment template' => {
message => q|Select payment gateway template|,
lastUpdated => 0,
context => q|The formlabel for the 'select payment gateway template' option in the commerce part of the admin console.|
},
'help select payment template title' => {
message => q|Select payment gateway template variables|,
lastUpdated => 0,
context => q|The title of the 'select payment gateway' help page.|
},
'gateway message' => {
message => q|This is the message that ask the user to select a payment gateway.|,
lastUpdated => 1149221607,
},
'pluginsAvailable' => {
message => q|A boolean value that is true when one or more payment plugins can be loaded and are enabled.|,
lastUpdated => 1149221607,
},
'noPluginsMessage' => {
message => q|A message that says that there are no payment plugins that ca be used.|,
lastUpdated => 1149221607,
},
'formHeader' => {
message => q|This contains the form header and all hidden form variables that are needed for a successful checkout.|,
lastUpdated => 1149221607,
},
'formFooter' => {
message => q|The form footer.|,
lastUpdated => 1149221607,
},
'formSubmit' => {
message => q|The submit button for this form.|,
lastUpdated => 1149221607,
},
'pluginLoop' => {
message => q|A template loop containing all enabled payment plugins. Within this loop the following template variables are provided:|,
lastUpdated => 1149221607,
},
'plugin name' => {
message => q|The name of the plugin.|,
lastUpdated => 1149221607,
},
'namespace' => {
message => q|The namespace of the plugin. You only need this if you want to create your own custom form elements.|,
lastUpdated => 1149221607,
},
'formElement' => {
message => q|A radio button tied to this plugin.|,
lastUpdated => 1149221607,
},
'shipping tab' => {
message => q|Shipping|,
lastUpdated => 0,
context => q|The label of the SHipping tab in the commerce settings manager.|
},
'salesTax tab' => {
message => q|SalesTax|,
lastUpdated => 1159845482,
context => q|The label of the sales tax tab in the commerce settings manager.|
},
'enable sales tax' => {
message => q|Enable Sales Tax?|,
lastUpdated => 1160189717,
context => q|The label field in the commerce setting for enabling sales tax.|
},
'enable sales tax description' => {
message => q|Set this to "Yes" if you would like Sales Tax enabled in the Commerce System. Sales Tax will be applied to any product, subscription or EMS event that has it enabled.|,
lastUpdated => 1160189808,
context => q|The label field in the commerce setting for enabling sales tax.|
},
'shipping plugin label' => {
message => q|Shipping plugin|,
lastUpdated => 0,
context => q|The label of the shipping plugin selection box in the commerce settings manager.|
},
'no shipping plugins selected' => {
message => q|There are no shipping plugins to select. Please enable plugins in the config file.|,
lastUpdated => 0,
context => q|The message that's shown in the AdminConsole/Commerce menu when there are no shipping plugins enabled.|
},
'select shipping method' => {
message => q|Please select a shipping method.|,
lastUpdated => 0,
context => q|The message asking the user to choose a shipping method during checkout.|
},
'no shipping methods available' => {
message => q|Shipping is not possible because no shipping plugins are enabled.|,
lastUpdated => 0,
context => q|A message that is shown when a user tries to checkout but no shipping plugins are enabled.|
},
'shipping select button' => {
message => q|Select shipping method|,
lastUpdated => 0,
context => q|The label of the select button of the select shipping form the user sees during checkout.|
},
'enable' => {
message => q|Enable|,
lastUpdated => 0,
context => q|The label of the enable option of the commerce plugins.|
},
'change payment gateway' => {
message => q|Change payment gateway|,
lastUpdated => 0,
context => q|The label for the change payament gateway url.|
},
'change shipping method' => {
message => q|Change shipping method|,
lastUpdated => 0,
context => q|The label for the change shipping method url.|
},
'checkout select shipping template' => {
message => q|Select shipping method template|,
lastUpdated => 0,
context => q|The formlabel for the 'select shipping method template' option in the commerce part of the admin console.|
},
'view shopping cart template' => {
message => q|Select view shopping cart template|,
lastUpdated => 1134599960,
context => q|The formlabel for the 'view shopping cart template' option in the commerce part of the admin console.|
},
'shopping cart empty' => {
message => q|Your shopping cart is empty.|,
lastUpdated => 1134599958,
context => q|A message indicating that the shopping cart is empty.|
},
'update cart' => {
message => q|Update cart|,
lastUpdated => 0,
context => q|The label of the update cart button.|
},
'checkout' => {
message => q|Checkout|,
lastUpdated => 0,
context => q|The label of the checkout button.|
},
'list transactions' => {
message => q|List transactions|,
lastUpdated => 0,
context => q|List transactions label|
},
'view shopping cart' => {
message => q|View shopping cart|,
lastUpdated => 0,
context => q|The label for the view shopping cart link in the confirm checkout screen.|
},
'topicName' => {
message => q|Commerce|,
lastUpdated => 1128920490,
},
'label' => {
message => q|Label|,
lastUpdated => 0,
context => q|Commerce Payment Plugin Label|
},
'label hoverhelp' => {
message => q|Label for displaying payment plugin to users. This will be the display if user can choose from different payment gateways available.|,
lastUpdated => 0,
context => q|Hoverhelp for Commerce Payment Plugin Label|
},
};
1;

View file

@ -1,126 +0,0 @@
package WebGUI::i18n::English::Macro_Product;
use strict;
our $I18N = {
'add to cart' => {
message => q|Add to cart|,
lastUpdated => 0,
context => q|The label for the add to cart link.|
},
'available product configurations' => {
message => q|Available product configurations|,
lastUpdated => 0,
context => q|Message indicatin the available configurations.|
},
'macroName' => {
message => q|Product|,
lastUpdated => 1128918830,
},
'no sku or id' => {
message => q|No SKU or productId passed|,
lastUpdated => 1135117939,
},
'cannot find product' => {
message => q|Cannot find product|,
lastUpdated => 1128976376,
},
'product title' => {
message => q|Product Macro|,
lastUpdated => 1128965480,
},
'variants.message' => {
message => q|The internationalized text "^International("available product configurations","Macro_Product");"|,
lastUpdated => 1149217564,
},
'variantLoop' => {
message => q|A loop containing information about all variants about the Product.|,
lastUpdated => 1149217564,
},
'variant.compositionLoop' => {
message => q|A loop containing information about all variants about the Product.|,
lastUpdated => 1149217564,
},
'parameter' => {
message => q|The parameter that defines this variant, for example, size.|,
lastUpdated => 1149217564,
},
'value' => {
message => q|The value of the parameter, for the example of size, XL.|,
lastUpdated => 1149217564,
},
'variant.variantId' => {
message => q|The Id for this variant of the Product.|,
lastUpdated => 1149217564,
},
'variant.price' => {
message => q|The price for this variant of the Product.|,
lastUpdated => 1149217564,
},
'variant.weight' => {
message => q|The weight for this variant of the Product.|,
lastUpdated => 1149217564,
},
'variant.sku' => {
message => q|The SKU for this variant of the Product.|,
lastUpdated => 1149217564,
},
'variant.addToCart.url' => {
message => q|A URL to add this variant of the Product to the user's shopping cart.|,
lastUpdated => 1149217564,
},
'variant.addToCart.label' => {
message => q|An internationalized label, "^International("add to cart","Macro_Product");",
to display to the user for adding this variant
of the Product to their shopping cart.|,
lastUpdated => 1149217564,
},
'productId' => {
message => q|The unique identifier of this Product.|,
lastUpdated => 1149217564,
},
'title' => {
message => q|The title for this Product.|,
lastUpdated => 1149217564,
},
'description' => {
message => q|The description of this Product.|,
lastUpdated => 1149217564,
},
'price' => {
message => q|The Product's base cost.|,
lastUpdated => 1149217564,
},
'weight' => {
message => q|The Product's base weight.|,
lastUpdated => 1149217564,
},
'sku' => {
message => q|The Product's base SKU.|,
lastUpdated => 1149217564,
},
};
1;

View file

@ -1,38 +0,0 @@
package WebGUI::i18n::English::Macro_SubscriptionItem;
use strict;
our $I18N = {
'macroName' => {
message => q|Subscription Item|,
lastUpdated => 1128919093,
},
'subscription item title' => {
message => q|Subscription Item Macro Template Variables|,
lastUpdated => 1184712144,
},
'url' => {
message => q|The URL to purchase a subscription to this item.|,
lastUpdated => 1149217400,
},
'name' => {
message => q|The name of the item.|,
lastUpdated => 1149217400,
},
'description' => {
message => q|The description of the item.|,
lastUpdated => 1149217400,
},
'price' => {
message => q|The price of the item.|,
lastUpdated => 1149217400,
},
};
1;

View file

@ -1,435 +0,0 @@
package WebGUI::i18n::English::ProductManager;
use strict;
our $I18N = {
'confirm delete product' => {
message => q|Are you certain you wish to delete this product?|,
lastUpdated => 0,
context => q|displayed when deleting a product|
},
'manage products' => {
message => q|Products (beta)|,
lastUpdated => 0,
context => q|The admin console label of the product manager.|
},
'title' => {
message => q|Title|,
lastUpdated => 1101772584,
context => q|The form label for the title field in editProduct|
},
'description' => {
message => q|Description|,
lastUpdated => 1101772584,
context => q|The form label for the description field in editProduct|
},
'price' => {
message => q|Price|,
lastUpdated => 1101772584,
context => q|The form label for the price field in editProduct|
},
'weight' => {
message => q|Weight|,
lastUpdated => 1101772584,
context => q|The form label for the weight field in editProduct|
},
'sku' => {
message => q|SKU|,
lastUpdated => 1101772584,
context => q|The form label for the SKU (Stock Keeping Unit) field in editProduct|
},
'template' => {
message => q|Template|,
lastUpdated => 1101772584,
context => q|The form label for the template field in editProduct|
},
'edit product' => {
message => q|Edit product|,
lastUpdated => 1101772584,
context => q|The name of the edit product form|
},
'edit product title error' => {
message => q|You must enter a product title.|,
lastUpdated => 1101772584,
context => q|An errormessage when no product title is given.|
},
'edit product price error' => {
message => q|You must enter a price.|,
lastUpdated => 1101772584,
context => q|An errormessage when no product price is given.|
},
'edit product weight error' => {
message => q|You must enter a weight.|,
lastUpdated => 1101772584,
context => q|An errormessage when no product weight is given.|
},
'edit product sku error' => {
message => q|You must enter a SKU|,
lastUpdated => 1101772584,
context => q|An error message when no product SKU is given.|
},
'edit parameter name' => {
message => q|Name|,
lastUpdated => 0000,
context => q|The form label for the name field in editProductParameter|
},
'edit parameter' => {
message => q|Edit product parameter|,
lastUpdated => 0000,
context => q|The name of the editProductParameter form|
},
'edit parameter name error' => {
message => q|You must enter a parameter name.|,
lastUpdated => 0000,
context => q|An errormessage when no parameter name is given.|
},
'edit parameter productId error' => {
message => q|No product ID supplied.|,
lastUpdated => 0000,
context => q|An errormessage when no productId for a parameter is given.|
},
'edit option value' => {
message => q|Value|,
lastUpdated => 0000,
context => q|The form label for the value field in editProductParameterOption|
},
'edit option price modifier' => {
message => q|Price modifier|,
lastUpdated => 0000,
context => q|The form label for the priceModifier field in editProductParameterOption|
},
'edit option weight modifier' => {
message => q|Weight modifier|,
lastUpdated => 0000,
context => q|The form label for the weightModifier field in editProductParameterOption|
},
'edit option sku modifier' => {
message => q|SKU modifier|,
lastUpdated => 0000,
context => q|The form label for the skuModifier field in editProductParameterOption|
},
'edit option' => {
mesaage => q|Edit parameter option|,
lastUpdated => 0000,
context => q|The name of the edit parameter option form|
},
'edit option value error' => {
message => q|You must enter a value.|,
lastupdated => 0000,
context => q|An error message when no value for an option is given.|
},
'edit option parameterId error' => {
message => q|No parameter ID given.|,
lastUpdated => 0000,
context => q|An error message when no parameterId for a parameter is given.|
},
'list products' => {
message => q|List products|,
lastUpdated => 0000,
context => q|The title of the list product screen|
},
'add product' => {
message => q|Add a new product|,
lastUpdated => 0,
context => q|The label for the add product link in de productmanager menu.|
},
'list products' => {
message => q|List products|,
lastUpdated => 0,
context => q|The label for the list products link in de productmanager menu.|
},
'manage product' => {
message => q|Manage product|,
lastUpdated => 0,
context => q|The label for the manage product link in de productmanager menu.|
},
'list variants' => {
message => q|List variants|,
lastUpdated => q|List variants|,
context => q|The label for the list variants in de productmanager menu.|
},
'sku template' => {
message => q|SKU Template|,
lastUpdated => 0,
context => q|The label for the sku template field in the edit product screen.|
},
'edit sku composition label' => {
message => q|Edit SKU Composition|,
lastUpdated => 0,
context => q|The label of the edit sku composition|
},
'list variants label' => {
message => q|List product variants|,
lastUpdated => 0,
context => q|The label of the list variants screen.|
},
'available' => {
message => q|Available|,
lastUpdated => 0,
context => q|A message indicating that a variant is available.|
},
'variant ID' => {
message => q|variantId|,
lastUpdated => 1118937717,
},
'parameter ID' => {
message => q|parameterId|,
lastUpdated => 1118937717,
},
'option ID' => {
message => q|optionId|,
lastUpdated => 1118937717,
},
'properties' => {
message => q|Properties|,
lastUpdated => 0,
context => q|Properties|
},
'add parameter' => {
message => q|Add parameter|,
lastUpdated => 0,
context => q|The label of the add parameter link in manage product.|
},
'add option' => {
message => q|Add option|,
lastUpdated => 0,
context => q|The label of the add option link in manage product.|
},
'manage product label' => {
message => q|Manage product|,
lastUpdated => 0,
context => q|The label of the manage product screen.|
},
'price override' => {
message => q|Price override|,
lastUpdated => 0,
context => q|Form label in the edit variant screen.|
},
'weight override' => {
message => q|Weight override|,
lastUpdated => 0,
context => q|Form label in the edit variant screen.|
},
'sku override' => {
message => q|SKU override|,
lastUpdated => 0,
context => q|Form label in the edit variant screen.|
},
'edit variant' => {
message => q|Edit product variant|,
lastUpdated => 0,
context => q|Label of the edit variant screen.|
},
'title description' => {
message => q|The name of the product.|,
lastUpdated => 1120449422,
},
'description description' => {
message => q|A description of the product.|,
lastUpdated => 1120449422,
},
'price description' => {
message => q|The default price of the product.|,
lastUpdated => 1120449422,
},
'useSalesTax' => {
message => q|Use Sales Tax?|,
lastUpdated => 1159844899,
},
'useSalesTax description' => {
message => q|Should this product have sales tax applied to it?|,
lastUpdated => 1159844899,
},
'weight description' => {
message => q|The default weight of the product.|,
lastUpdated => 1120449422,
},
'sku description' => {
message => q|The base SKU of the product.|,
lastUpdated => 1120449422,
},
'template description' => {
message => q|The default template associated with product.|,
lastUpdated => 1120449422,
},
'sku template description' => {
message => q|This field defines how the SKU for each
product variant will be composed. The syntax is the same as that of
normal templates.|,
lastUpdated => 1120449422,
},
'edit parameter name description' => {
message => q|<p>The name of this parameter.</p>|,
lastUpdated => 1122609059,
},
'edit option value description' => {
message => q|<p>The value of this option (ie. 'Blue').</p>|,
lastUpdated => 1122609417,
},
'edit option price modifier description' => {
message => q|<p>The amount this option adds to the
default price for product variants containig this option.</p>|,
lastUpdated => 1146606364,
},
'edit option weight modifier description' => {
message => q|<p>The weight this option adds to the
default weight for product variants consisting of this option.</p>|,
lastUpdated => 1122609417,
},
'edit option sku modifier description' => {
message => q|<p>When this option is called in the SKU template as a template variable, the value that will be displayed.</p>|,
lastUpdated => 1165513384,
},
'price override description' => {
message => q|The price for this variant.|,
lastUpdated => 1165513644,
},
'weight override description' => {
message => q|The weight of this variant.|,
lastUpdated => 1165513603,
},
'sku override description' => {
message => q|The SKU of this variant.|,
lastUpdated => 1165513642,
},
'available description' => {
message => q|This sets whether this variant is available for purchase.|,
lastUpdated => 1146607104,
},
'help edit sku template title' => {
message => q|Edit SKU template|,
lastUpdated => 0,
context => q|The title of the edit sku template help page|
},
'help edit sku template body' => {
message => q|The SKU template defines how the SKU for each product variant will be
composed. Since parameters are components of the SKU template you'll
probably want to change the SKU template when you add a parameter. This
is the place to do this. Note that you can also edit the SKU template
through the properties of the product.<br />
<br />
The syntax is the same as that of normal templates. Available
template variables are:<br />
<br />
<span style="font-weight: bold;">&lt;tmpl_var base&gt;</span><br />
<div style="margin-left: 40px;">The default SKU defined above.<br />
<br />
</div>
<span style="font-weight: bold;">&lt;tmpl_var param.MyParameterName&gt;</span>
<br />
<div style="margin-left: 40px;">For each parameter a template variable
of this format is generated. Spaces in the parameter name are converted
to dots. For example if you have defined a parameter called 'Color' its
template variable is called <span style="font-style: italic;">&lt;tmpl_var
param.color&gt;</span>. If you have defined a parameter with name
'Number of pins' the template variable containing its SKU modifier is
called <span style="font-style: italic;">&lt;tmpl_var
param.number.of.pins&gt;.</span><br />
<br />
</div>
The complete list of available template variables is also printed above
the form.<br />|,
lastUpdated => 1164742227,
context => q|The body of the edit sku template help page|
},
'topicName' => {
message => q|Product Manager|,
lastUpdated => 1128919931,
},
'group id' => {
message => "Add to Group",
lastUpdated => 0,
context => "Label for add to group action",
},
'group id description' => {
message => "Add purchasers of this product to this group. Set to 'everyone' to disable.",
lastUpdated => 0,
context => "Hover help for add to group action",
},
'group expires offset' => {
message => "Group Expires Offset",
lastUpdated => 0,
context => "Label for group expires offset",
},
'group expires offset description' => {
message => "Length of time added to user's expiration from the above group each time this product is purchased.",
lastUpdated => 0,
context => "Hover help for group expires offset",
},
'6 months' => {
message => "6 months",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'1 year' => {
message => "1 year",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'1 month' => {
message => "1 month",
lastUpdated => 1160615577,
context => "A time period for group expires offset",
},
'2 years' => {
message => "2 years",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'3 years' => {
message => "3 years",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'5 years' => {
message => "5 years",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'10 years' => {
message => "10 years",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'lifetime' => {
message => "lifetime",
lastUpdated => 0,
context => "A time period for group expires offset",
},
'productId' => {
message => "Product ID",
lastUpdated => 0,
context => "Unique identifier for a Product",
},
};
1;

View file

@ -1,387 +0,0 @@
package WebGUI::i18n::English::Subscription;
use strict;
our $I18N = {
'expire subscription codes' => {
message => q|Expire Subscription Codes|,
lastUpdated => 0,
context => q|the title of the expire subscription codes workflow activity|
},
'no subscription code batches' => {
message => q|No subscription code batches have been created yet. Use the submenu on the right to generate a batch.|,
lastUpdated => 1101228391,
context => q|Displayed if no subscription code batches have been created|
},
'listSubscriptionCodes title' => {
message => q|Manage Subscription Codes|,
lastUpdated => 1101228391,
context => q|Title of listSubscriptionCodes.|
},
'batch id' => {
message => q|BatchId|,
lastUpdated => 1101228391,
context => q|Shows up in the table header in listSubscriptionCodes.|
},
'subscription description' => {
message => q|Description|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'manage codes' => {
message => q|Manage subscription codes|,
lastUpdated => 1101228391,
context => q|A submenu option in the Subscriptions Admin Console menu.|
},
'delete subscription confirm' => {
message => q|Are you sure to delete this subscription?|,
lastUpdated => 1101754598,
context => q|Confirmation question when deleting a subscription.|
},
'subscriptionId' => {
message => q|Subscription Id|,
lastUpdated => 1101228391,
context => q|Just leave it Subscription Id.|
},
'generate batch' => {
message => q|Generate a batch of subscription codes|,
lastUpdated => 1101228391,
context => q|A submenu option in the Subscriptions Admin Console menu.|
},
'subscription name' => {
message => q|Subscription name|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'code' => {
message => q|Code|,
lastUpdated => 1101228391,
context => q|Shows up in the table header in listSubscriptionCodes.|
},
'code description' => {
message => q|The subscription code that you want to redeem|,
lastUpdated => 1101228391,
},
'delete batch confirm' => {
message => q|Are you sure to delete this batch?|,
lastUpdated => 1101228391,
context => q|Confirmation question when deleting a code batch.|
},
'selection used' => {
message => q|date of usage between|,
lastUpdated => 1101228391,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'batch description' => {
message => q|Batch description|,
lastUpdated => 1101228391,
context => q|Form option in createSubscriptionCodeBatch.|
},
'redeem code' => {
message => q|Redeem a subscription code.|,
lastUpdated => 1101228391,
context => q|The title of the URL in displayLogin that points to code redemption.|
},
'selection message' => {
message => q|You can make a selection of codes by:|,
lastUpdated => 1101228391,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'subscription name description' => {
message => q|<p>Name of the subscription.</p>|,
lastUpdated => 1120861450,
},
'subscription price description' => {
message => q|<p>Price to pay for the subscription.</p>|,
lastUpdated => 1120861450,
},
'useSalesTax' => {
message => q|Use Sales Tax?|,
lastUpdated => 1159845025,
},
'useSalesTax description' => {
message => q|Should this subscription have sales tax applied to it?|,
lastUpdated => 1159845045,
},
'subscription description description' => {
message => q|<p>Detailed description of the subscription.</p>|,
lastUpdated => 1120861450,
},
'subscription group description' => {
message => q|<p>When a user paid the fee, he/she will be added to this group.</p>|,
lastUpdated => 1167190387,
},
'subscription duration description' => {
message => q|<p>This sets the length of one subscription term. ie. You pay every month, or every half year.</p>|,
lastUpdated => 1120861450,
},
'execute on subscription description' => {
message => q|<p>A (Perl) script to call when someone has subscribed and paid.</p>|,
lastUpdated => 1167190394,
},
'subscription karma description' => {
message => q|<p>The amount of karma which is added to the user after he/she subscribes.</p>|,
lastUpdated => 1120861450,
},
'codes expire' => {
message => q|Codes expire after|,
lastUpdated => 1101228392,
context => q|Form option in createSubscriptionCodeBatch.|
},
'no association error' => {
message => q|You have to associate this batch to at least one subscription.|,
lastUpdated => 1101228391,
context => q|An error that cab occur when creating a code batch.|
},
'subscription duration' => {
message => q|Subscription period|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'creation date' => {
message => q|Creation date|,
lastUpdated => 1101228391,
context => q|Shows up in the table header in listSubscriptionCodes.|
},
'and' => {
message => q|and|,
lastUpdated => 1101228391,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'subscription group' => {
message => q|Subscribe to group|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'manage subscriptions' => {
message => q|Subscriptions (beta)|,
lastUpdated => 1101228391,
context => q|A submenu option in the Subscriptions Admin Console menu.|
},
'execute on subscription' => {
message => q|Execute on subscription|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'status' => {
message => q|Status|,
lastUpdated => 1101228391,
context => q|Shows up in the table header in listSubscriptionCodes.|
},
'noc' => {
message => q|Number of codes in batch|,
lastUpdated => 1101228391,
context => q|Form option in createSubscriptionCodeBatch.|
},
'selection created' => {
message => q|date of creation between|,
lastUpdated => 1101228391,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'manage batches' => {
message => q|Manage subscription code batches|,
lastUpdated => 1101228391,
context => q|A submenu option in the Subscriptions Admin Console menu.|
},
'association' => {
message => q|Associate with subscription|,
lastUpdated => 1101228391,
context => q|Form option in createSubscriptionCodeBatch.|
},
'no description error' => {
message => q|You must enter a description.|,
lastUpdated => 1101228391,
context => q|An error that cab occur when creating a code batch.|
},
'subscription price' => {
message => q|Price|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'dateUsed' => {
message => q|Date of usage|,
lastUpdated => 1101228391,
context => q|Shows up in the table header in listSubscriptionCodes.|
},
'create batch error' => {
message => q|An error has occurred:|,
lastUpdated => 1101754822,
context => q|Identifies an error in createSubscriptionCodeBatch.|
},
'select' => {
message => q|Show selection|,
lastUpdated => 1101228391,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'edit subscription title' => {
message => q|Edit Subscription|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'add subscription' => {
message => q|Add a new subscription|,
lastUpdated => 1101228391,
context => q|A submenu option in the Subscriptions Admin Console menu.|
},
'list codes in batch' => {
message => q|List the codes in this batch|,
lastUpdated => 1101228391,
context => q|In listSubscriptionCodeBatches|
},
'delete codes' => {
message => q|Delete selected codes|,
lastUpdated => 1101228391,
context => q|Shows up in listSubscriptionCodes.|
},
'subscription karma' => {
message => q|Karma|,
lastUpdated => 1101228391,
context => q|Form label in editSubscription|
},
'create batch menu' => {
message => q|Create a batch of subscription codes|,
lastUpdated => 1101228391,
context => q|Menu name for createSubscriptionCodeBatch.|
},
'noc description' => {
message => q|<p>Number of codes to create</p>|,
lastUpdated => 1120858265,
},
'code length description' => {
message => q|<p>The number of characters in the generated codes. Codes must be at least 10
characters long.</p>|,
lastUpdated => 1120858265,
},
'codes expire description' => {
message => q|<p>The code must be used before this date.</p>|,
lastUpdated => 1132353871,
},
'association description' => {
message => q|<p>Which subscription(s) are made with the generated codes.</p>|,
lastUpdated => 1120858265,
},
'batch description description' => {
message => q|Description of the batch.|,
lastUpdated => 1120858265,
},
'no subscriptions' => {
message => q|There are no subscriptions yet. You can add subscriptions by using the 'Add Subscription' option in the menu on the right of the screen.|,
lastUpdated => 0,
context => q|A message that shows up in manage subscriptions indicating that there are no subscriptions at all.|
},
'redeem code success' => {
message => q|You've successfully subscribed to the subscriptions. You can enter another code below.|,
lastUpdated => 0,
context => q|The success message for the code redemption function.|
},
'redeem code failure' => {
message => q|You've entered a code that's wrong, already being used or expired. Please enter another code below.|,
lastUpdated => 1101754837,
context => q|The failure message for the code redemption function.|
},
'redeem code ask for code' => {
message => q|Please enter your subscription code below.|,
lastUpdated => 0,
context => q|The enter a code message for the code redemption function.|
},
'selection batch id' => {
message => q|batch ID|,
lastUpdated => 0,
context => q|Shows up in the selection part of listSubscriptionCodes.|
},
'help redeem code template body' => {
message => q|The following template variables are available through this template:<br />
<br />
<b>batchDescription</b><br />
The description of the batch tied to the subscription code.<br />
<br />
<b>message</b><br />
The message that gives the result of your action. Depending on what you've done it says that you can enter a code, you've entered the wrong code, or you've successfully redeemed your code.<br />
<br />
<b>codeForm</b>
The form in which the user can enter his subscription code.<br />|,
lastUpdated => 1146593261,
context => q|The body of the help page of the code redemption template.|
},
'help redeem code template title' => {
message => q|Redeem subscription code template|,
lastUpdated => 1101754848,
context => q|The title of the help page of the code redemption template.|
},
'code length' => {
message => q|Subscription code length|,
lastUpdated => 1102660410,
context => q|The label of the form field in which the length of a subscription code is entered.|
},
'code length error' => {
message => q|You must enter a subscription code length between 10 and 64 (border values included).|,
lastUpdated => 0,
context => q|The error message that shows up when a wrong code length is specified.|
},
'topicName' => {
message => q|Subscriptions|,
lastUpdated => 1128920064,
},
};
1;