[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