Adding the subscription asset

This commit is contained in:
Martin Kamerbeek 2008-05-21 08:29:40 +00:00
parent b7840e7ed9
commit a6bd5d0b99
5 changed files with 1569 additions and 0 deletions

View file

@ -18,6 +18,7 @@ use WebGUI::DateTime;
use WebGUI::Asset::Sku::Product;
use WebGUI::Workflow;
use WebGUI::User;
use WebGUI::Utility;
use File::Find;
use File::Spec;
use File::Path;
@ -58,6 +59,7 @@ addCoupon( $session );
addVendors($session);
modifyThingyPossibleValues( $session );
removeLegacyTable($session);
migrateSubscriptions( $session );
finish($session); # this line required
@ -1107,6 +1109,223 @@ sub removeLegacyTable {
print "Done.\n" unless $quiet;
}
#-------------------------------------------------
sub migrateSubscriptions {
my $session = shift;
print "\tMigrating subscriptions to the new commerce system..." unless ($quiet);
# Check if codes are tied to multiple subscriptions.
my ($hasDoubles) = $session->db->buildArray(
'select count(*) as cnt from subscriptionCodeSubscriptions group by code order by cnt desc'
);
print "\n\t\t!!WARNING: There are subscription codes that link to multiple subscriptions!!"
." Please refer to gotcha.txt!\n" if $hasDoubles > 1;
# Rename old subscription table so we can reuse it for the Sku
$session->db->write('alter table subscription rename to Subscription_OLD');
# Create the new subscription table
$session->db->write(<<EOSQL);
create table Subscription (
assetId varchar(22) binary not null,
revisionDate bigint(20) not null,
templateId varchar(22) not null default '',
thankYouMessage mediumtext,
price float not null default 0.00,
subscriptionGroup varchar(22) not null default 2,
duration varchar(12) not null default 'Monthly',
executeOnSubscription varchar(255),
karma int(6) default 0,
PRIMARY KEY (assetId, revisionDate)
);
EOSQL
# Create the new subsction code table
$session->db->write(<<EOSQL2);
create table Subscription_code (
code varchar(64) not null,
batchId varchar(22) not null,
status varchar(10) not null default 'Unused',
dateUsed bigint(20),
usedBy varchar(22),
PRIMARY KEY (code)
);
EOSQL2
# Create the new subscription code batch table
$session->db->write(<<EOSQL3);
create table Subscription_codeBatch (
batchId varchar(22) not null,
name varchar(255),
description mediumtext,
subscriptionId varchar(22) not null,
expirationDate bigint(20) not null,
dateCreated bigint(20) not null,
PRIMARY KEY (batchId)
);
EOSQL3
# Add a folder to the import node for the migrated subscriptions
my $subscriptionsFolder = WebGUI::Asset->getImportNode( $session )->addChild({
className => 'WebGUI::Asset::Wobject::Folder',
menuTitle => 'Migrated subscriptions',
title => 'Migrated subscriptions',
ownerUserId => 3,
});
# Migrate all subscriptions
print "\t\tConverting subscriptions to assets:\n";
my $subscriptions = $session->db->read( 'select * from Subscription_OLD' );
while (my $subscription = $subscriptions->hashRef) {
# Don't migrate deleted subscriptions
next if $subscription->{ deleted };
# Add a new subscription sku
my $sku = $subscriptionsFolder->addChild(
{
className => 'WebGUI::Asset::Sku::Subscription',
ownerUserId => 3,
url => 'subscriptions/'.$subscription->{ description },
menuTitle => $subscription->{ description },
title => $subscription->{ description },
price => $subscription->{ price },
description => $subscription->{ description },
subscriptionGroup => $subscription->{ subscriptionGroup },
duration => $subscription->{ duration },
executeOnSubscription => $subscription->{ executeOnSubscription },
karma => $subscription->{ karma },
templateId => 'eqb9sWjFEVq0yHunGV8IGw',
overrideTaxRate => $subscription->{ useSalesTax } ? 0 : 1,
taxRateOverride => 0,
},
$subscription->{ subscriptionId },
);
# Log and print migration data
my $message = "Migrated subscription '$subscription->{ description }' ($subscription->{ subscriptionId }) "
. " to '" . $sku->getUrl . "' (" . $sku->getId . ")";
$session->errorHandler->warn( $message );
print "\t\t--> $message\n";
}
$subscriptions->finish;
# Subscriptions are migrated, now migrate the subscription codes
# First find batches with multiple subscriptions per code
my @multiBatches = $session->db->buildArray(
'select distinct batchId from subscriptionCode where code in '
.' (select code from subscriptionCodeSubscriptions group by code having count(subscriptionId) > 1)'
);
# Migrate subscription codes batch by batch
print "\t\tMigrating subscription codes.\n";
my @batches = $session->db->buildArray('select distinct batchId from subscriptionCodeBatch');
foreach my $batchId ( @batches ) {
my $subscriptionId;
# Fetch batch properties and the number of code. Discard used or expired codes.
my ($numberOfCodes, $codeLength, $expirationDate, $dateCreated, $name, $description) =
$session->db->quickArray(
'select count(*), length(t1.code), (t1.dateCreated + t1.expires), '
.' t1.dateCreated, t2.name, t2.description '
.' from subscriptionCode as t1, subscriptionCodeBatch as t2 '
.' where t1.batchId=t2.batchId and t1.batchId=? '
.' and t1.status=\'Unused\' '
.' and from_unixtime(t1.dateCreated + t1.expires) > now() '
.' group by t1.batchId',
[
$batchId,
]
);
# Skip expired or fully used batches;
next unless $numberOfCodes;
# Check if the codes in this batch link to multiple subscriptions
if ( isIn( $batchId, @multiBatches ) ) {
my $message = "\t\tBatch $batchId has codes linking to multiple subscriptions:\n";
# Find the subscriptions the code in this batch are attached to
my @subscriptions = $session->db->buildArray(
'select distinct subscriptionId from subscriptionCodeSubscriptions where code in '
.' (select distinct code from subscriptionCode where batchId=?)',
[
$batchId,
]
);
# Migrate the codes for the first subscription in the list (this is done below)
$subscriptionId = shift @subscriptions;
my $subscription = WebGUI::Asset::Sku::Subscription->new($session, $subscriptionId);
$message .= "\t\t--> Keeping codes for subscription "
. "'" . $subscription->get('title') . "' (" . $subscription->getUrl . ") \n";
# And generate new codes for the remaining subscriptions
foreach my $assetId ( @subscriptions ) {
my $subscription = WebGUI::Asset::Sku::Subscription->new($session, $assetId);
$message .= "\t\t--> Generating new codes for subscription "
. "'" . $subscription->get('title') . "' (" . $subscription->getUrl . "): \n";
my $batchId = $subscription->generateSubscriptionCodeBatch(
$numberOfCodes,
$codeLength,
$expirationDate,
$name,
$description
);
$message .= "\t\t\t" . join( "\n\t\t\t", keys %{ $subscription->getCodesInBatch( $batchId ) } ). "\n";
}
# Log and print migration info
$session->errorHandler->warn( $message );
print $message;
}
else {
$subscriptionId = $session->db->quickScalar(
'select distinct subscriptionId from subscriptionCodeSubscriptions '
.' where code in (select code from subscriptionCode where batchId=?)',
[
$batchId,
]
);
}
# Migrate the batch itself
$session->db->write(
'insert into Subscription_codeBatch '
. ' (batchId, name, description, subscriptionId, expirationDate, dateCreated) '
. ' values (? , ? , ? , ? , ? , ? ) ',
[
$batchId,
$name,
$description,
$subscriptionId,
$expirationDate,
$dateCreated,
]
);
# Migrate the codes
$session->db->write(
'insert into Subscription_code (batchId, code, status, dateUsed, usedBy) '
.' select batchId, code, status, dateUsed, usedBy from subscriptionCode where batchId=?',
[
$batchId,
]
);
}
print "\tDone.\n";
}
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
#----------------------------------------------------------------------------
@ -1115,6 +1334,7 @@ sub addPackage {
my $session = shift;
my $file = shift;
print "Importing package: $file...";
# Make a storage location for the package
my $storage = WebGUI::Storage->createTemp( $session );
$storage->addFileFromFilesystem( $file );
@ -1124,6 +1344,8 @@ sub addPackage {
# Make the package not a package anymore
$package->update({ isPackage => 0 });
print "Done\n";
}
#-------------------------------------------------

View file

@ -0,0 +1,898 @@
package WebGUI::Asset::Sku::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
-------------------------------------------------------------------
=cut
use strict;
use Tie::IxHash;
use base 'WebGUI::Asset::Sku';
use WebGUI::Asset::Template;
use WebGUI::Form;
use WebGUI::Shop::Pay;
=head1 NAME
Package WebGUI::Asset::Sku::Subscription
=head1 DESCRIPTION
This asset makes subscriptionss possible.
=head1 SYNOPSIS
use WebGUI::Asset::Sku::Subscription;
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=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 = shift;
my $userId = shift || $self->session->user->userId;
my $groupId = $self->get('subscriptionGroup');
# Make user part of the right group and adjust the expiration date
my $group = WebGUI::Group->new($self->session,$groupId);
$group->addUsers( [$userId], $self->getExpirationOffset );
# Add karma to the user's account
WebGUI::User->new($self->session,$userId)->karma($self->get('karma'), 'Subscription', 'Added for purchasing subscription '.$self->get('title'));
# Process the executeOnPurchase field
my $command = $self->get('executeOnSubscription');
WebGUI::Macro::process($self->session,\$command);
system($command) if ($self->get('executeOnSubscription') ne "");
}
#-------------------------------------------------------------------
=head2 definition
Adds templateId, thankYouMessage, and defaultPrice fields.
=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_Subscription");
%properties = (
templateId => {
tab => "display",
fieldType => "template",
namespace => "Subscription",
defaultValue => 'eqb9sWjFEVq0yHunGV8IGw',
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 help"),
},
price => {
fieldType => 'float',
label => $i18n->get('subscription price'),
hoverHelp => $i18n->get('subscription price description'),
defaultValue => '0.00',
},
subscriptionGroup => {
fieldType => 'group',
label => $i18n->get('subscription group'),
hoverHelp => $i18n->get('subscription group description'),
defaultvalue => [ 2 ]
},
duration => {
fieldType => 'selectBox',
label => $i18n->get('subscription duration'),
hoverHelp => $i18n->get('subscription duration description'),
defaultValue => 'Monthly',
options => WebGUI::Shop::Pay->new( $session )->getRecurringPeriodValues,
},
executeOnSubscription => {
fieldType => 'text',
label => $i18n->get('execute on subscription'),
hoverHelp => $i18n->get('execute on subscription description'),
defaultValue => '',
},
);
# Show the karma field only if karma is enabled
if ($session->setting->get("useKarma")) {
$properties{ karma } = {
type => 'integer',
label => $i18n->get('subscription karma'),
hoverHelp => $i18n->get('subscription karma description'),
defaultvalue => 0,
};
}
push(@{$definition}, {
assetName => $i18n->get('assetName'),
icon => 'subscription.gif',
autoGenerateForms => 1,
tableName => 'Subscription',
className => 'WebGUI::Asset::Sku::Subscription',
properties => \%properties,
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
=head2 generateSubscriptionCode ( length )
Generates a subscription code with the given length. Does not save to the db.
=head3 length
The length of the code.
=cut
sub generateSubscriptionCode {
my $self = shift;
my $codeLength = shift || 64;
my @codeElements = ('A'..'Z', 'a'..'z', 0..9, '-');
my $code;
for (1 .. $codeLength) {
$code .= $codeElements[rand(63)];
}
return $code;
}
#-------------------------------------------------------------------
=head2 generateSubscriptionCodeBatch ( numberOfCodes, length, expirationDate, name, description )
Creates a batch of subscription codes.
=head3 numberOfCodes
The number of codes in this batch.
=head3 length
The length of each code.
=head3 expirationDate
The epoch for the date when the codes expire.
=head3 name
The name for this batch.
=head3 description
The batch description.
=cut
sub generateSubscriptionCodeBatch {
my $self = shift;
my $numberOfCodes = shift;
my $codeLength = shift;
my $expirationDate = shift;
my $name = shift || 'Untitled';
my $description = shift;
my $session = $self->session;
my $now = time;
# Create a new batch and write its properties to the db
my $batchId = $session->db->setRow( 'Subscription_codeBatch', 'batchId', {
batchId => 'new',
name => $name,
description => $description,
subscriptionId => $self->getId,
expirationDate => $expirationDate,
dateCreated => $now
});
# Generate the codes for this batch
for ( 1 .. $numberOfCodes ) {
# Generate a code
my $code = $self->generateSubscriptionCode( $codeLength );
# Make sure the code is unique
while ( $session->db->quickScalar("select code from Subscription_code where code=?", [ $code ] ) ) {
$code = $self->generateSubscriptionCode( $codeLength );
}
# Code is unique so store it
$session->db->setRow( 'Subscription_code', 'code',
{
batchId => $batchId,
status => 'Unused',
dateUsed => 0,
usedBy => 0,
},
$code
);
}
return $batchId;
}
#-------------------------------------------------------------------
=head2 getAdminConsoleWithSubmenu ( )
Returns an admin console with management links added to the submenu.
=cut
sub getAdminConsoleWithSubmenu {
my $self = shift;
my $session = $self->session;
my $ac = $self->getAdminConsole;
my $i18n = WebGUI::International->new( $session, 'Asset_Subscription' );
$ac->addSubmenuItem( $self->getUrl('func=createSubscriptionCodeBatch'), $i18n->get('generate batch'));
$ac->addSubmenuItem( $self->getUrl('func=listSubscriptionCodes'), $i18n->get('manage codes') );
$ac->addSubmenuItem( $self->getUrl('func=listSubscriptionCodeBatches'), $i18n->get('manage batches'));
return $ac;
}
#-------------------------------------------------------------------
=head2 getCode ( code )
Returns a hashref with the properties of the passed code.
=head3 code
The code for which the properties hould be returned.
=cut
sub getCode {
my $self = shift;
my $code = shift;
my $session = $self->session;
my $codeProperties = $session->db->quickHashRef(
" select * from Subscription_code as t1, Subscription_codeBatch as t2 "
." where t1.batchId = t2.batchId and t1.code=? and t2.subscriptionId=?",
[
$code,
$self->getId,
]
);
return $codeProperties || {};
}
#-------------------------------------------------------------------
=head2 getCodesInBatch ( batchId )
Returns a hashref of hashrefs containing the properties of all the codes in a batch.
The format is as follows:
$codes->{ CODE }->{ PROPERTY }
=head3 batchId
The id of the batch.
=cut
sub getCodesInBatch {
my $self = shift;
my $batchId = shift;
my $session = $self->session;
my $codes = {};
my $sth = $session->db->read('select * from Subscription_code where batchId=?', [
$batchId
]);
while (my $row = $sth->hashRef) {
$codes->{ $row->{code} } = $row;
}
$sth->finish;
return $codes;
}
#-------------------------------------------------------------------
=head2 getConfiguredTitle
Returns title + price
=cut
sub getConfiguredTitle {
my $self = shift;
return $self->getTitle." (".$self->getOptions->{price}.")";
}
#-------------------------------------------------------------------
sub getExpirationOffset {
my $self = shift;
my $duration = shift || $self->get('duration');
# y, m, d
return $self->session->datetime->addToDate( 1, 0, 0, 7 ) - 1 if $duration eq 'Weekly';
return $self->session->datetime->addToDate( 1, 0, 0, 14 ) - 1 if $duration eq 'BiWeekly';
return $self->session->datetime->addToDate( 1, 0, 0, 28 ) - 1 if $duration eq 'FourWeekly';
return $self->session->datetime->addToDate( 1, 0, 1, 0 ) - 1 if $duration eq 'Monthly';
return $self->session->datetime->addToDate( 1, 0, 3, 0 ) - 1 if $duration eq 'Quarterly';
return $self->session->datetime->addToDate( 1, 0, 6, 0 ) - 1 if $duration eq 'HalfYearly';
return $self->session->datetime->addToDate( 1, 1, 0, 0 ) - 1 if $duration eq 'Yearly';
# TODO: Throw exception
}
#-------------------------------------------------------------------
=head2 getPrice
Returns configured price, 0.00 if neither of those are available.
=cut
sub getPrice {
my $self = shift;
return $self->get('price') || 0.00;
}
#-------------------------------------------------------------------
=head2 onCompletePurchase
Applies the first term of the subscription. This method is called when the payment is successful.
=cut
sub onCompletePurchase {
my $self = shift;
$self->apply;
}
#-------------------------------------------------------------------
=head2 prepareView
Prepares the template.
=cut
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;
}
#-------------------------------------------------------------------
=head2 redeemCode ( code )
Redeems a subscription code. Returns undef if redemption is successful, otherwise an error message is returned.
=head3 code
The code that should be redeemed.
=cut
sub redeemCode {
my $self = shift;
my $code = shift;
my $session = $self->session;
my $i18n = my $i18n = WebGUI::International->new($session, "Asset_Subscription");
my $properties = $self->getCode( $code );
if ($properties->{ status } eq 'Unused' && $properties->{ expirationDate } >= time) {
# Code is ok so apply the subscription
$self->apply;
# Set code to Used
$session->db->write("update Subscription_code set status='Used', dateUsed=? where code =?", [
time,
$code,
]);
} else {
return $i18n->get('redeem code failure');
}
return undef;
}
#-------------------------------------------------------------------
=head2 view
Displays the donation form.
=cut
sub view {
my ($self) = @_;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, "Asset_Subscription");
my %var = (
formHeader => WebGUI::Form::formHeader($session, { action=>$self->getUrl })
. WebGUI::Form::hidden( $session, { name=>"func", value=>"purchaseSubscription" }),
formFooter => WebGUI::Form::formFooter($session),
purchaseButton => WebGUI::Form::submit( $session, { value => $i18n->get("purchase button") }),
hasAddedToCart => $self->{_hasAddedToCart},
codeControls => join (' &middot; ', (
'<a href="'.$self->getUrl('func=createSubscriptionCodeBatch') .'">'.$i18n->get('generate batch').'</a>',
'<a href="'.$self->getUrl('func=listSubscriptionCodes') .'">'.$i18n->get('manage codes').'</a>',
'<a href="'.$self->getUrl('func=listSubscriptionCodeBatches') .'">'.$i18n->get('manage batches').'</a>',
)),
redeemCodeLabel => $i18n->get('redeem code'),
redeemCodeUrl => $self->getUrl('func=redeemSubscriptionCode'),
);
return $self->processTemplate(\%var,undef,$self->{_viewTemplate});
}
#----------------------------------------------------------------------------
=head2 www_createSubscriptionCodeBatch ( $error )
Form to accept parameters to create a batch of subscription codes.
=head3 error
An HTML array ref of an error message to be returned to the user.
=cut
sub www_createSubscriptionCodeBatch {
my $self = shift;
my $error = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, "Asset_Subscription");
# Check privs
return $session->privilege->adminOnly() unless $self->canEdit;
# Generate error message if errors occurred
my $errorMessage = $i18n->get('create batch error').'<ul><li>'.join('</li><li>', @{$error}).'</li></ul>' if ($error);
# Generate the properties form for this subscription code batch
my $f = WebGUI::HTMLForm->new( $session );
$f->submit;
$f->hidden(
-name => 'func',
-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')
);
$f->text(
-name => 'name',
-label => $i18n->get('batch name'),
-hoverHelp => $i18n->get('batch name description'),
-value => $session->form->process('name'),
);
$f->textarea(
-name => 'description',
-label => $i18n->get('batch description'),
-hoverHelp => $i18n->get('batch description description'),
-value => $session->form->process("description"),
);
$f->submit;
return $self->getAdminConsoleWithSubmenu->render( $errorMessage.$f->print, $i18n->get('create batch menu') );
}
=head2 www_createSubscriptionCodeBatchSave ( )
Method that accepts the form parameters to create a batch of subscription codes.
=cut
#-------------------------------------------------------------------
sub www_createSubscriptionCodeBatchSave {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, "Asset_Subscription");
# Check privs
return $session->privilege->adminOnly() unless $self->canEdit;
my $numberOfCodes = $session->form->process("noc");
my $description = $session->form->process("description");
my $name = $session->form->process("name");
my $expires = $session->form->interval('expires');
my $batchId = $session->id->generate;
my $codeLength = $session->form->process("codeLength");
# Sanity check input
my @error;
push(@error, $i18n->get('no description error')) unless ($description);
push(@error, $i18n->get('code length error'))
unless (
$codeLength >= 10
&& $codeLength <= 64
&& $codeLength =~ m/^\d\d$/
);
# Return an error message if an error occurred
return $self->www_createSubscriptionCodeBatch( \@error ) if @error;
# Create the code batch
$self->generateSubscriptionCodeBatch(
$numberOfCodes,
$codeLength,
time() + $expires,
$name,
$description,
);
return $self->www_listSubscriptionCodeBatches;
}
#-------------------------------------------------------------------
=head2 www_deleteSubscriptionCodeBatch ( )
Deletes a batch of subscription codes.
=cut
sub www_deleteSubscriptionCodeBatch {
my $self = shift;
my $session = $self->session;
my $batchId = $session->form->process('bid');
return $session->privilege->insufficient unless $self->canEdit;
# Remove code batch properties and codes in batch
$session->db->write( 'delete from Subscription_codeBatch where batchId=?', [ $batchId ] );
$session->db->write( 'delete from Subscription_code where batchId=?', [ $batchId ] );
return $self->www_listSubscriptionCodeBatches;
}
#-------------------------------------------------------------------
=head2 www_deleteSubscriptionCodes ( )
Deletes subscription codes based on either their creation date or their usage date.
=cut
sub www_deleteSubscriptionCodes {
my $self = shift;
my $session = $self->session;
return $session->privilege->insufficient unless $self->canEdit;
my $selectBy = $session->form->process('selection');
if ($selectBy eq 'dc') {
# Delete codes by creation date
my $from = $session->form->date( 'dcStart' );
my $to = $session->form->date( 'dcStop' );
$session->db->write(
'delete from Subscription_code where batchId in '
.' ( select batchId from Subscription_codeBatch '
.' where dateCreated >= ? and dateCreated <= ? and subscriptionId=? '
.' )',
[
$from,
$to,
$self->getId,
]
);
}
elsif ($selectBy eq 'du') {
# Delete codes by usage date
my $from = $session->form->date( 'duStart' );
my $to = $session->form->date( 'duStop' );
$session->db->write(
'delete from Subscription_code where dateUsed >= ? and dateUsed <= ? and batchId in '
.'( select batchId from Subscription_codeBatch where subscriptionId=? )',
[
$from,
$to,
]
);
}
return $self->www_listSubscriptionCodes;
}
#-------------------------------------------------------------------
=head2 www_listSubscriptionCodeBatches
Display a list of code batches for this subscription.
=cut
sub www_listSubscriptionCodeBatches {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new( $session, "Asset_Subscription" );
# Check privs
return $session->privilege->insufficient unless $self->canEdit;
# Set up a paginator to paginate the list of batches
my $p = WebGUI::Paginator->new( $session, $self->getUrl('func=listSubscriptionCodeBatches') );
$p->setDataByQuery( 'select * from Subscription_codeBatch where subscriptionId=?', undef, 1, [
$self->getId,
]);
# Fetch the list of batches at the current paginition index
my $batches = $p->getPageData;
my $output = $p->getBarTraditional($session->form->process("pn"));
$output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">';
foreach my $batch ( @{$batches} ) {
$output .= '<tr><td>';
$output .= $session->icon->delete(
'func=deleteSubscriptionCodeBatch;bid='.$batch->{batchId},
$self->getUrl,
$i18n->get('delete batch confirm'));
$output .= '<td>' . $batch->{ description } . '</td>';
$output .= '<td>'
. '<a href="' . $self->getUrl('func=listSubscriptionCodes;selection=b;bid=' . $batch->{ 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 $self->getAdminConsoleWithSubmenu->render( $output, $i18n->get('manage batches') );
}
#-------------------------------------------------------------------
=head2 www_listSubscriptionCodes ( )
Displays a list of subscription codes for this subscription.
=cut
sub www_listSubscriptionCodes {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, "Asset_Subscription");
my ($p, $codes, $output, $where, $ops, $delete);
return $session->privilege->insufficient unless $self->canEdit;
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 $batchId = $session->form->process('bid');
my $selection = $session->form->process('selection');
my $batches =
$session->db->buildHashRef('select batchId, description from Subscription_codeBatch where subscriptionId=?',
[
$self->getId,
]);
# Build a subscription code selection form
my $f = WebGUI::HTMLForm->new( $session );
$f->hidden(
name => 'func',
value => 'listSubscriptionCodes',
);
#--- Selection by date created
$f->readOnly(
label =>
WebGUI::Form::radio( $session, { name => 'selection', value => 'du', checked => ($selection eq 'du') } )
. $i18n->get('selection used'),
value =>
WebGUI::Form::date( $session, { name => 'duStart', value=> $duStart } )
. ' ' . $i18n->get( 'and' ) . ' '
. WebGUI::Form::date( $session, { name => 'duStop', value=> $duStop } ),
);
#--- Selection by date used
$f->readOnly(
label =>
WebGUI::Form::radio( $session, { name => 'selection', value => 'dc', checked => ($selection eq 'dc') } )
. $i18n->get('selection created'),
value =>
WebGUI::Form::date( $session, { name => 'dcStart', value=> $dcStart } )
. ' ' . $i18n->get( 'and' ) . ' '
. WebGUI::Form::date( $session, { name => 'dcStop', value=> $dcStop } ),
);
#--- Selection by batch
$f->readOnly(
label =>
WebGUI::Form::radio( $session, { name => 'selection', value => 'b', checked => ($selection eq 'b') } )
. $i18n->get('selection batch id'),
value =>
WebGUI::Form::selectBox( $session, { name => 'bid', value => $batchId, options => $batches } ),
);
#--- Submit button
$f->submit(
value => $i18n->get('select'),
);
if ($session->form->process("selection") eq 'du') {
$where = " and dateUsed >= ".$session->db->quote($duStart)." and dateUsed <= ".$session->db->quote($duStop);
$ops = ';duStart='.$session->form->process('duStart').';duStop='.$session->form->process('duStop').';selection=du';
$delete = '<a href="'.$self->getUrl('func=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='.$session->form->process('dcStart').';dcStop='.$session->form->process('dcStop').';selection=dc';
$delete = '<a href="'.$self->getUrl('func=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="'.$self->getUrl('func=deleteSubscriptionCodeBatch'.$ops).'">'.$i18n->get('delete codes').'</a>';
} else {
return $self->getAdminConsoleWithSubmenu->render( $output, $i18n->get('listSubscriptionCodes title') );
}
$p = WebGUI::Paginator->new( $session, $self->getUrl('func=listSubscriptionCodes'.$ops) );
$p->setDataByQuery(
"select t1.*, t2.* from Subscription_code as t1, Subscription_codeBatch as t2 ".
" where t1.batchId=t2.batchId and subscriptionId=?".$where,
undef, undef,
[
$self->getId,
]
);
$codes = $p->getPageData;
$output = $i18n->get('selection message');
$output .= $f->print;
$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 $self->getAdminConsoleWithSubmenu->render( $output, $i18n->get('listSubscriptionCodes title') );
}
#-------------------------------------------------------------------
=head2 wwww_purchaseSubscription
Add this subscription to the cart.
=cut
sub www_purchaseSubscription {
my $self = shift;
if ($self->canView) {
$self->{_hasAddedToCart} = 1;
$self->addToCart({price => $self->getPrice});
}
return $self->www_view;
}
#-------------------------------------------------------------------
=head2 www_redeemSubscriptionCode ( )
Redeems a subscription code or returns an error.
=cut
sub www_redeemSubscriptionCode {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, "Asset_Subscription");
my $code = $session->form->process("code");
my $var = {};
if ($code) {
my $error = $self->redeemCode( $code );
my $codeProperties = $self->getCode( $code );
$var->{ batchDescription } = $codeProperties->{ description };
$var->{ message } = $error || $i18n->get('redeem code success');
} else {
$var->{ message } = $i18n->get('redeem code ask for code');
}
my $f = WebGUI::HTMLForm->new( $session );
$f->hidden(
-name => 'func',
-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 $self->processStyle($self->processTemplate($var, 'PBtmpl0000000000000053'));
}
1;

View file

@ -166,6 +166,38 @@ sub getPaymentGateways {
return \@drivers;
}
#-------------------------------------------------------------------
=head2 getRecurringPeriodValues ( period )
A utility method that returns the internationalized name for period.
=head3 period
The period you want the name for.
=cut
sub getRecurringPeriodValues {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new($session, 'Commerce');
tie my %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 new ( $session )

View file

@ -0,0 +1,417 @@
package WebGUI::i18n::English::Asset_Subscription;
use strict;
our $I18N = {
'assetName' => {
message => q|Subscription|,
lastUpdated => 0,
context => q|The name of the subscription asset|,
},
'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,
},
'purchase button' => {
message => q|Add to cart|,
lastUpdates => 0,
context => q|The label on the add to cart button|,
},
'default thank you message' => {
message => q|The subsciption has been added to the cart.|,
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 teh message shown when a subscription is purchased|,
},
'thank you message help' => {
message => q|Use this field to define the message that informs users that they've just put a subscription into the cart. Please note that the subscription will not be applied until the user checks out.|,
lastUpdated => 0,
context => q|help for the thank you message field|,
},
};
1;