diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 4d4084ece..383a452c5 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -2,6 +2,11 @@ Commerce merge - The getEditForm code was refactored out of WebGUI::Workflow::Activity and put into WebGUI::HTMLForm. Now any WebGUI code can dynamically generate tabless forms. + - Rewrote the commerce system from the ground up. + - Added a new donation asset which allows visitors to donate arbitrary + amounts of money using the new commerce system. + - Merged all the old shipping plugins into one "Flat Rate" shipping plugin. + See gotchas. 7.5.3 - prevent HTML and Macro injection in usernames diff --git a/docs/gotcha.txt b/docs/gotcha.txt index 02fb7f9e3..b77959708 100644 --- a/docs/gotcha.txt +++ b/docs/gotcha.txt @@ -7,6 +7,16 @@ upgrading from one version to the next, or even between multiple versions. Be sure to heed the warnings contained herein as they will save you many hours of grief. +Commerce Merge +-------------------------------------------------------------------- + * The commerce system was completely rewritten. As such you will need + to tweak some settings to get commerce back up and running. + + * Shipping configurations are going to be lost when you upgrade. You'll + need to set up a shipping option if you're using the commerce system. + + + 7.5.1 -------------------------------------------------------------------- * There was a corrupt template in a package for the 7.5.0 upgrade. diff --git a/docs/upgrades/packages-7.5.3/root_import_default-donation-template.wgpkg b/docs/upgrades/packages-7.5.3/root_import_default-donation-template.wgpkg new file mode 100644 index 000000000..473f9b92e Binary files /dev/null and b/docs/upgrades/packages-7.5.3/root_import_default-donation-template.wgpkg differ diff --git a/docs/upgrades/upgrade_7.5.2-7.5.3.pl b/docs/upgrades/upgrade_7.5.2-7.5.3.pl index a3f22fd1f..d98305391 100644 --- a/docs/upgrades/upgrade_7.5.2-7.5.3.pl +++ b/docs/upgrades/upgrade_7.5.2-7.5.3.pl @@ -28,20 +28,38 @@ insertCommerceTaxTable($session); insertCommerceShipDriverTable($session); migrateToNewCart($session); createSkuAsset($session); +createDonationAsset($session); addShippingDrivers($session); finish($session); # this line required +#------------------------------------------------- +sub createDonationAsset { + my $session = shift; + print "\tInstall Donation asset.\n" unless ($quiet); + $session->db->write("create table donation ( + assetId varchar(22) binary not null, + revisionDate bigint not null, + defaultPrice float not null default 100.00, + thankYouMessage mediumtext, + templateId varchar(22) binary not null, + primary key (assetId, revisionDate) + )"); + $session->config->addToArray("assets","WebGUI::Asset::Sku::Donation"); +} + #------------------------------------------------- sub createSkuAsset { my $session = shift; - print "\tCreate SKU asset.\n" unless ($quiet); + print "\tInstall SKU asset.\n" unless ($quiet); $session->db->write("create table sku ( assetId varchar(22) binary not null, revisionDate bigint not null, + description mediumtext, sku varchar(35) binary not null, salesAgentId varchar(22) binary, + displayTitle int not null default 1, overrideTaxRate int not null default 0, taxRateOverride float not null default 0.00, primary key (assetId, revisionDate), @@ -66,6 +84,7 @@ sub migrateToNewCart { cartId varchar(22) binary not null, assetId varchar(22) binary not null, options mediumtext, + configuredTitle varchar(255), shippingAddressId varchar(22) binary, quantity integer not null default 1, index cartId_assetId (cartId,assetId) diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index b14db2ee8..3faf3de0d 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -209,6 +209,7 @@ # Add Content menus. "assets" : [ + "WebGUI::Asset::Sku::Donation", "WebGUI::Asset::Snippet", "WebGUI::Asset::Redirect", "WebGUI::Asset::FilePile", diff --git a/lib/WebGUI/Asset/Sku.pm b/lib/WebGUI/Asset/Sku.pm index 046140e03..dac79deb4 100644 --- a/lib/WebGUI/Asset/Sku.pm +++ b/lib/WebGUI/Asset/Sku.pm @@ -17,7 +17,6 @@ package WebGUI::Asset::Sku; use strict; use Tie::IxHash; use base 'WebGUI::Asset'; -use WebGUI::Utility; @@ -68,7 +67,7 @@ sub addToCart { my ($self, $options) = @_; $self->applyOptions($options); my $cart = WebGUI::Shop::Cart->create($self->session); - my $cart->addItem($self, 1); + my $cart->addItem($self); } #------------------------------------------------------------------- @@ -104,6 +103,13 @@ sub definition { tie %properties, 'Tie::IxHash'; my $i18n = WebGUI::International->new($session, "Asset_Sku"); %properties = ( + description => { + tab=>"properties", + fieldType=>"HTMLArea", + defaultValue=>undef, + label=>$i18n->get("description"), + hoverHelp=>$i18n->get("description help") + }, sku => { tab=>"commerce", fieldType=>"text", @@ -111,10 +117,17 @@ sub definition { label=>$i18n->get("sku"), hoverHelp=>$i18n->get("sku help") }, + displayTitle => { + tab=>"display", + fieldType=>"yesNo", + defaultValue=>1, + label=>$i18n->get("display title"), + hoverHelp=>$i18n->get("display title") + }, overrideTaxRate => { tab=>"commerce", - fieldType=>"text", - defaultValue=>$session->id->generate, + fieldType=>"yesNo", + defaultValue=>0, label=>$i18n->get("override tax rate"), hoverHelp=>$i18n->get("override tax rate help") }, @@ -145,6 +158,20 @@ sub definition { } +#------------------------------------------------------------------- + +=head2 getConfiguredTitle ( ) + +Returns a configured title like "Red XL T-Shirt" rather than just "T-Shirt". Needs to be overridden by subclasses to support this. Defaultly just returns getTitle(). + +=cut + +sub getConfiguredTitle { + my $self = shift; + return $self->getTitle; +} + + #------------------------------------------------------------------- =head2 getEditTabs ( ) @@ -169,7 +196,10 @@ Returns a hash reference of configuration data that can return this sku to a con sub getOptions { my $self = shift; - return $self->{_skuOptions}; + if (ref $self->{_skuOptions} eq "HASH") { + return $self->{_skuOptions}; + } + return {}; } #------------------------------------------------------------------- @@ -280,21 +310,6 @@ sub processStyle { #------------------------------------------------------------------- -=head2 www_edit ( ) - -Web facing method which is the default edit page - -=cut - -sub www_edit { - my $self = shift; - return $self->session->privilege->insufficient() unless $self->canEdit; - return $self->session->privilege->locked() unless $self->canEditIfLocked; - return $self->getAdminConsole->render($self->getEditForm->print,WebGUI::International::get('edit asset',"Asset_NewAsset")); -} - -#------------------------------------------------------------------- - =head2 www_view ( ) Renders self->view based upon current style, subject to timeouts. Returns Privilege::noAccess() if canView is False. diff --git a/lib/WebGUI/Asset/Sku/Donation.pm b/lib/WebGUI/Asset/Sku/Donation.pm new file mode 100644 index 000000000..e5747a20e --- /dev/null +++ b/lib/WebGUI/Asset/Sku/Donation.pm @@ -0,0 +1,137 @@ +package WebGUI::Asset::Sku::Donation; + +=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 Tie::IxHash; +use base 'WebGUI::Asset::Sku'; +use WebGUI::Asset::Template; +use WebGUI::Form; + + +=head1 NAME + +Package WebGUI::Asset::Sku::Donation + +=head1 DESCRIPTION + +This asset makes donations possible. + +=head1 SYNOPSIS + +use WebGUI::Asset::Sku::Dnoation; + +=head1 METHODS + +These methods are available from this class: + +=cut + + + +#------------------------------------------------------------------- +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my %properties; + tie %properties, 'Tie::IxHash'; + my $i18n = WebGUI::International->new($session, "Asset_Donation"); + %properties = ( + templateId => { + tab => "display", + fieldType => "template", + namespace => "Donation", + defaultValue => "vrKXEtluIhbmAS9xmPukDA", + label => $i18n->get("template"), + hoverHelp => $i18n->get("template help"), + }, + thankYouMessage => { + tab => "properties", + defaultValue => $i18n->get("default thank you message"), + fieldType => "HTMLArea", + label => $i18n->get("thank you message"), + hoverHelp => $i18n->get("thank you message"), + }, + defaultPrice => { + tab => "commerce", + fieldType => "float", + defaultValue => 100.00, + label => $i18n->get("default price"), + hoverHelp => $i18n->get("default price help"), + }, + ); + push(@{$definition}, { + assetName => $i18n->get('assetName'), + icon => 'Donation.gif', + autoGenerateForms => 1, + tableName => 'donation', + className => 'WebGUI::Asset::Sku::Donation', + properties => \%properties + }); + return $class->SUPER::definition($session, $definition); +} + + +#------------------------------------------------------------------- +sub getConfiguredTitle { + my $self = shift; + return $self->getTitle." (".$self->getOptions->{price}.")"; +} + + +#------------------------------------------------------------------- +sub getPrice { + my $self = shift; + return $self->getOptions->{price} || $self->get("defaultPrice") || 100.00; +} + +#------------------------------------------------------------------- +sub prepareView { + my $self = shift; + $self->SUPER::prepareView(); + my $templateId = $self->get("templateId"); + my $template = WebGUI::Asset::Template->new($self->session, $templateId); + $template->prepare; + $self->{_viewTemplate} = $template; +} + +#------------------------------------------------------------------- +sub view { + my ($self) = @_; + my $session = $self->session; + my $i18n = WebGUI::International->new($session, "Asset_Donation"); + my %var = ( + formHeader => WebGUI::Form::formHeader($session, { action=>$self->getUrl }) + . WebGUI::Form::hidden( $session, { name=>"func", value=>"donate" }), + formFooter => WebGUI::Form::formFooter($session), + donateButton => WebGUI::Form::submit( $session, { value => $i18n->get("donate button") }), + priceField => WebGUI::Form::float($session, { name => "price", defaultValue => $self->getPrice }), + hasAddedToCart => $self->{_hasAddedToCart}, + ); + return $self->processTemplate(\%var,undef,$self->{_viewTemplate}); +} + +#------------------------------------------------------------------- +sub www_donate { + my $self = shift; + if ($self->canView) { + $self->{_hasAddedToCart} = 1; + $self->addToCart({price => ($self->session->form->get("price") || $self->getPrice) }); + } + return $self->www_view; +} + +1; diff --git a/lib/WebGUI/Shop/CartItem.pm b/lib/WebGUI/Shop/CartItem.pm index 5d142d289..d8a0af7c0 100644 --- a/lib/WebGUI/Shop/CartItem.pm +++ b/lib/WebGUI/Shop/CartItem.pm @@ -222,7 +222,7 @@ A hash reference that contains one of the following: =head4 asset -This is a special meta property. It is a reference to a WebGUI::Asset::Sku subclass object. If you pass this reference it will acquire the assetId and options properties automatically. +This is a special meta property. It is a reference to a WebGUI::Asset::Sku subclass object. If you pass this reference it will acquire the assetId, configuredTitle, and options properties automatically. =head4 assetId @@ -232,6 +232,10 @@ The assetId of the asset to add to the cart. The configuration options for this asset. +=head4 configuredTitle + +The title of this product as configured. + =head4 shippingAddressId The unique id for a shipping address attached to this cart. @@ -244,8 +248,10 @@ sub update { if (exists $newProperties->{asset}) { $newProperties->{options} = $newProperties->{asset}->getOptions; $newProperties->{assetId} = $newProperties->{asset}->getId; + $newProperties->{configuredTitle} = $newProperties->{asset}->getConfiguredTitle; } $properties{$id}{assetId} = $newProperties->{assetId} || $properties{$id}{assetId}; + $properties{$id}{configuredTitle} = $newProperties->{configuredTitle} || $properties{$id}{configuredTitle}; if (exists $newProperties->{options} && ref($newProperties->{options}) eq "HASH") { $properties{$id}{options} = JSON::to_json($newProperties->{options}); } diff --git a/lib/WebGUI/i18n/English/Asset_Donation.pm b/lib/WebGUI/i18n/English/Asset_Donation.pm new file mode 100644 index 000000000..91ab11674 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_Donation.pm @@ -0,0 +1,62 @@ +package WebGUI::i18n::English::Asset_Donation; + +use strict; + +our $I18N = { + 'donate button' => { + message => q|Add Donation To Cart|, + lastUpdated => 0, + context => q|the text that will appear on the donation button| + }, + + 'default thank you message' => { + message => q|Thank you for your kind donation.|, + lastUpdated => 0, + context => q|the default message that will go in the thank you message field| + }, + + 'thank you message' => { + message => q|Thank You Message|, + lastUpdated => 0, + context => q|the label for the field where you type in a message thanking the user for their donation| + }, + + 'thank you message help' => { + message => q|Write a thank you message to your user for donating. Be sincere. Remember they've just put the donation in the cart at this point, they haven't checked out yet.|, + lastUpdated => 0, + context => q|help for default price field| + }, + + 'template' => { + message => q|Template|, + lastUpdated => 0, + context => q|the label for the field where you select the template for this asset| + }, + + 'template help' => { + message => q|Choose a template that should be used to display the donation.|, + lastUpdated => 0, + context => q|help for default price field| + }, + + 'default price' => { + message => q|Default Price|, + lastUpdated => 0, + context => q|the label for the field that asks what the default donation amount should be.| + }, + + 'default price help' => { + message => q|How much money are you asking for per user? Note that they can type in any amount they wish, this is just a suggestion.|, + lastUpdated => 0, + context => q|help for default price field| + }, + + 'assetName' => { + message => q|Donation|, + lastUpdated => 0, + context => "The name of this asset. Used to contribute money." + }, + +}; + +1; diff --git a/lib/WebGUI/i18n/English/Asset_Sku.pm b/lib/WebGUI/i18n/English/Asset_Sku.pm index b637106eb..2d39d70ee 100644 --- a/lib/WebGUI/i18n/English/Asset_Sku.pm +++ b/lib/WebGUI/i18n/English/Asset_Sku.pm @@ -9,6 +9,18 @@ our $I18N = { context => q|The name of a tab that all Sku based assets have to put their commerce related settings.| }, + 'description' => { + message => q|Description|, + lastUpdated => 0, + context => q|The label for the description of the product.| + }, + + 'description help' => { + message => q|Describe the product or service here.|, + lastUpdated => 0, + context => q|help for description field| + }, + 'sku' => { message => q|SKU|, lastUpdated => 0, diff --git a/t/Asset/Sku.t b/t/Asset/Sku.t index 850a7f380..62640eccb 100644 --- a/t/Asset/Sku.t +++ b/t/Asset/Sku.t @@ -61,6 +61,7 @@ isnt($sku->processStyle, "", "Got some style information."); my $loadSku = WebGUI::Asset::Sku->newBySku($session, $sku->get("sku")); is($loadSku->getId, $sku->getId, "newBySku() works."); +$sku->purge; #---------------------------------------------------------------------------- # Cleanup diff --git a/t/Asset/Sku/Donation.t b/t/Asset/Sku/Donation.t new file mode 100644 index 000000000..39a28e137 --- /dev/null +++ b/t/Asset/Sku/Donation.t @@ -0,0 +1,63 @@ +# vim:syntax=perl +#------------------------------------------------------------------- +# 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 +#------------------------------------------------------------------ + +# Write a little about what this script tests. +# +# This tests WebGUI::Asset::Sku::Donation + +use FindBin; +use strict; +use lib "$FindBin::Bin/../../lib"; +use Test::More; +use WebGUI::Test; # Must use this before any other WebGUI modules +use WebGUI::Session; +use WebGUI::Asset; +use WebGUI::Asset::Sku::Donation; + +#---------------------------------------------------------------------------- +# Init +my $session = WebGUI::Test->session; + + +#---------------------------------------------------------------------------- +# Tests + +plan tests => 4; # Increment this number for each test you create + +#---------------------------------------------------------------------------- +# put your tests here +my $root = WebGUI::Asset->getRoot($session); +my $sku = $root->addChild({ + className=>"WebGUI::Asset::Sku::Donation", + title=>"Test Donation", + defaultPrice => 50.00, + }); +isa_ok($sku, "WebGUI::Asset::Sku::Donation"); + +is($sku->getPrice, 50.00, "Price should be 50.00"); + +$sku->applyOptions({ + price => 200.00 + }); +is($sku->getPrice, 200.00, "Price should be 200.00"); + +is($sku->getConfiguredTitle, "Test Donation (200)", "getConfiguredTitle()"); + +$sku->purge; + + +#---------------------------------------------------------------------------- +# Cleanup +END { + +} + +1;