[wellwell-devel] [wellwell] Add coupons plugin, first alpha release.
Stefan Hornburg
wellwell-devel at rt.icdevgroup.org
Tue Jul 20 14:02:23 UTC 2010
commit 336b3881ad4f00f3ce7c3eb9679e78f8a65f2ed6
Author: Stefan Hornburg (Racke) <racke at linuxia.de>
Date: Tue Jul 20 16:01:43 2010 +0200
Add coupons plugin, first alpha release.
lib/WellWell/Coupon.pm | 224 ++++++++++++++++++++
plugins/coupons/code/coupons.sub | 20 ++
plugins/coupons/coupons.info | 4 +
plugins/coupons/database/mysql/coupon_dates.sql | 8 +
.../coupons/database/mysql/coupon_discounts.sql | 9 +
plugins/coupons/database/mysql/coupon_log.sql | 9 +
plugins/coupons/database/mysql/coupons.sql | 5 +
plugins/coupons/pages/coupons/redeem.itl | 4 +
plugins/coupons/plugin.cfg | 13 ++
9 files changed, 296 insertions(+), 0 deletions(-)
---
diff --git a/lib/WellWell/Coupon.pm b/lib/WellWell/Coupon.pm
new file mode 100644
index 0000000..2260677
--- /dev/null
+++ b/lib/WellWell/Coupon.pm
@@ -0,0 +1,224 @@
+# WellWell::Coupon - WellWell Coupons
+#
+# Copyright (C) 2010 Stefan Hornburg (Racke) <racke at linuxia.de>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package WellWell::Coupon;
+
+use strict;
+use warnings;
+
+use Vend::Data;
+use Vend::Tags;
+
+# define [coupons] tag
+Vend::Config::parse_tag('UserTag', 'coupons Order function code');
+Vend::Config::parse_tag('UserTag', 'coupons AddAttr');
+Vend::Config::parse_tag('UserTag', 'coupons HasEndTag');
+Vend::Config::parse_tag('UserTag', 'coupons MapRoutine WellWell::Coupon::coupons');
+
+my $last_error;
+
+# [coupons]
+
+sub coupons {
+ my ($function, $code, $opt, $body) = @_;
+ my ($coupon, $repo);
+
+ if ($function eq 'validate' || $function eq 'redeem') {
+ if ($coupon = lookup($code)) {
+ if ($function eq 'validate') {
+ return $coupon->code();
+ }
+ else {
+ $coupon->redeem();
+ }
+ }
+ else {
+ Vend::Tags->error({name => 'coupons', set => $last_error, overwrite => 1});
+ }
+ }
+ elsif ($function eq 'cancel') {
+ # noop right now
+ }
+ elsif ($function eq 'display') {
+ my (@out);
+
+ if (exists $Vend::Session->{coupons}) {
+ $repo = $Vend::Session->{coupons};
+
+ for (@{$repo->[0]}) {
+ my %hash = %{$repo->[1]->{$_}};
+
+ push (@out, Vend::Tags->uc_attr_list({hash => \%hash, body => $body}));
+ }
+
+ return join('', @out);
+ }
+ }
+
+ return;
+}
+
+# Constructor for WellWell::Coupon class
+sub new {
+ my ($class) = shift;
+ my ($self) = {code => shift};
+
+ bless $self;
+
+ while (@_ >= 2) {
+ my $key = shift;
+ $self->{$key} = shift;
+ }
+
+ return $self;
+}
+
+# Methods for WellWell::Coupon class
+sub code {
+ shift->{code};
+}
+
+sub redeem {
+ my ($self) = shift;
+
+ $self->log();
+ $self->apply_discounts();
+}
+
+# apply_discounts - Apply discounts for coupon
+
+sub apply_discounts {
+ my ($self) = shift;
+ my ($dbif, $set);
+
+ unless ($dbif = database_exists_ref('coupon_discounts')) {
+ die ::errmsg('Database missing: %s', 'coupon_discounts');
+ }
+
+ $set = $dbif->query(q{select code,subject,mode,value from coupon_discounts where coupon_code = '%s'}, $self->{code});
+
+ for (@$set) {
+ my ($code, $subject, $mode, $value) = @$_;
+
+ if ($subject eq 'subtotal' && $mode eq 'percents') {
+ if ($value <= 0 || $value >= 100) {
+ ::logError("Invalid coupon discount %s: $value%");
+ next;
+ }
+
+ my $factor;
+
+ $factor = 1 - $value / 100;
+
+ Vend::Tags->discount({code => 'ALL_ITEMS', body => '$s * ' . $factor});
+
+ $self->{discount} = $value;
+ $Vend::Session->{coupons}->[1]->{$self->{code}}->{discount} = $value;
+ }
+ }
+}
+
+
+# Auxiliary functions
+sub lookup {
+ my ($coupon_number) = @_;
+ my ($dbif, $set, $now, @clist, $coupon, $before_all);
+
+ unless ($dbif = database_exists_ref('coupons')) {
+ die ::errmsg('Database missing: %s', 'coupons');
+ }
+
+ $set = $dbif->query(q{select C.code,D.valid_from,D.valid_to from coupons C left join coupon_dates D on (C.code = D.coupon_code) where C.coupon_code = '%s' and C.inactive is FALSE order by D.valid_from ASC},
+ $coupon_number);
+
+ if (@$set) {
+ $now = Vend::Tags->time({format => '%Y-%m-%d %H:%M:%S'});
+
+ for (@$set) {
+ # look for a proper candidate
+ my ($code, $valid_from, $valid_to) = @$_;
+
+ if ($valid_from) {
+ if ($now lt $valid_from) {
+ $before_all = 1;
+ last;
+ }
+ }
+
+ if ($valid_to) {
+ next if $now gt $valid_to;
+ }
+
+ push (@clist, $_);
+ }
+ }
+
+ unless (@clist) {
+ if (@$set) {
+ if ($before_all) {
+ $last_error = ::errmsg('Coupon not yet active');
+ }
+ else {
+ $last_error = ::errmsg('Coupon expired');
+ }
+ }
+ else {
+ $last_error = ::errmsg('Invalid coupon number.');
+ }
+ return;
+ }
+
+ return new WellWell::Coupon ($clist[0]->[0],
+ coupon_number => $coupon_number,
+ valid_to => $clist[0]->[1]);
+}
+
+# log - Log the coupon into the database and the session.
+
+sub log {
+ my ($self) = shift;
+ my ($dbif, $entered, %record, $code);
+
+ unless ($dbif = database_exists_ref('coupon_log')) {
+ die ::errmsg('Database missing: %s', 'coupon_log');
+ }
+
+ $entered = Vend::Tags->time({format => '%Y-%m-%d %H:%M:%S'});
+
+ %record = (coupon_code => $self->{code},
+ uid => $Vend::Session->{username} || 0,
+ session_id => $Vend::Session->{id},
+ entered => $entered);
+
+ $code = $dbif->set_slice([{dml => 'insert'}], \%record);
+
+ # apply discounts
+
+ $Vend::Session->{coupons} ||= [[], {}];
+
+ push (@{$Vend::Session->{coupons}->[0]}, $self->{code});
+ $Vend::Session->{coupons}->[1]->{$self->{code}} = {coupon_number => $self->{coupon_number},
+ valid_to => $self->{valid_to}};
+
+ return $code;
+}
+
+
+
+1;
diff --git a/plugins/coupons/code/coupons.sub b/plugins/coupons/code/coupons.sub
new file mode 100644
index 0000000..ded331b
--- /dev/null
+++ b/plugins/coupons/code/coupons.sub
@@ -0,0 +1,20 @@
+Sub coupons <<EOS
+sub {
+ my ($action, $function, @params) = split('/', shift);
+
+ if ($function eq 'redeem') {
+ if ($CGI->{coupon_number}) {
+ $Tag->coupons('redeem', $CGI->{coupon_number});
+ }
+ else {
+ $Tag->error({name => 'coupon', set => errmsg('Please enter coupon number.')});
+ }
+ }
+ elsif ($function eq 'cancel') {
+ $Tag->coupons('cancel', $CGI->{coupon_number});
+ }
+
+ $CGI->{mv_nextpage} = $Config->{Special}->{order};
+ return 1;
+}
+EOS
\ No newline at end of file
diff --git a/plugins/coupons/coupons.info b/plugins/coupons/coupons.info
new file mode 100644
index 0000000..44d3a95
--- /dev/null
+++ b/plugins/coupons/coupons.info
@@ -0,0 +1,4 @@
+name = Coupons
+version = 0.1
+author = Stefan Hornburg (Racke) <racke at linuxia.de>
+require = WellWell::Coupon
diff --git a/plugins/coupons/database/mysql/coupon_dates.sql b/plugins/coupons/database/mysql/coupon_dates.sql
new file mode 100644
index 0000000..7dfdfc4
--- /dev/null
+++ b/plugins/coupons/database/mysql/coupon_dates.sql
@@ -0,0 +1,8 @@
+CREATE TABLE coupon_dates (
+ code int NOT NULL auto_increment,
+ coupon_code int NOT NULL,
+ valid_from datetime,
+ valid_to datetime,
+ PRIMARY KEY(code),
+ KEY(coupon_code)
+);
diff --git a/plugins/coupons/database/mysql/coupon_discounts.sql b/plugins/coupons/database/mysql/coupon_discounts.sql
new file mode 100644
index 0000000..fbf3f40
--- /dev/null
+++ b/plugins/coupons/database/mysql/coupon_discounts.sql
@@ -0,0 +1,9 @@
+CREATE TABLE coupon_discounts (
+ code int NOT NULL auto_increment,
+ coupon_code int NOT NULL,
+ subject varchar(32) NOT NULL default '',
+ mode varchar(32) NOT NULL default '',
+ value decimal(11,2) NOT NULL default 0,
+ PRIMARY KEY(code),
+ KEY(coupon_code)
+);
diff --git a/plugins/coupons/database/mysql/coupon_log.sql b/plugins/coupons/database/mysql/coupon_log.sql
new file mode 100644
index 0000000..b417084
--- /dev/null
+++ b/plugins/coupons/database/mysql/coupon_log.sql
@@ -0,0 +1,9 @@
+CREATE TABLE coupon_log (
+ code int NOT NULL auto_increment,
+ coupon_code int NOT NULL,
+ uid int unsigned NOT NULL default 0,
+ session_id char(8) NOT NULL default '',
+ entered datetime NOT NULL,
+ PRIMARY KEY(code),
+ KEY(coupon_code)
+);
diff --git a/plugins/coupons/database/mysql/coupons.sql b/plugins/coupons/database/mysql/coupons.sql
new file mode 100644
index 0000000..7c9c6c8
--- /dev/null
+++ b/plugins/coupons/database/mysql/coupons.sql
@@ -0,0 +1,5 @@
+CREATE TABLE coupons (
+ code int NOT NULL auto_increment,
+ coupon_number varchar(32) not null default '',
+ amount decimal(11,2) NOT NULL DEFAULT 0
+);
diff --git a/plugins/coupons/pages/coupons/redeem.itl b/plugins/coupons/pages/coupons/redeem.itl
new file mode 100644
index 0000000..eaed83d
--- /dev/null
+++ b/plugins/coupons/pages/coupons/redeem.itl
@@ -0,0 +1,4 @@
+[compose
+ components.body="coupons_redeem"
+ forms.coupons_redeem.name="coupons_redeem"
+]
\ No newline at end of file
diff --git a/plugins/coupons/plugin.cfg b/plugins/coupons/plugin.cfg
new file mode 100644
index 0000000..eab7f36
--- /dev/null
+++ b/plugins/coupons/plugin.cfg
@@ -0,0 +1,13 @@
+Message Loading coupons plugin.
+
+Variable CURPLUGIN coupons
+include plugins/default.cfg
+
+Database coupons AUTO_SEQUENCE 1
+Database coupon_discounts AUTO_SEQUENCE 1
+Database coupon_dates AUTO_SEQUENCE 1
+Database coupon_log AUTO_SEQUENCE 1
+
+Filter coupon_number strip
+
+ActionMap coupons coupons
More information about the wellwell-devel
mailing list