summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS.pm4
-rw-r--r--FS/FS/Mason.pm1
-rw-r--r--FS/FS/Schema.pm13
-rw-r--r--FS/FS/discount.pm39
-rw-r--r--FS/MANIFEST2
-rw-r--r--httemplate/browse/discount.html3
-rw-r--r--httemplate/edit/discount.html2
-rw-r--r--httemplate/elements/menu.html1
-rw-r--r--httemplate/graph/report_cust_bill_pkg_discount.html31
-rw-r--r--httemplate/search/cust_bill_pkg_discount.html64
-rw-r--r--httemplate/search/cust_pkg_discount.html48
-rw-r--r--httemplate/search/report_cust_bill_pkg_discount.html43
-rw-r--r--httemplate/search/report_cust_pkg_discount.html31
13 files changed, 216 insertions, 66 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index b3ebf30..abba99b 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -312,7 +312,9 @@ L<FS:;cust_pkg_discount> - Customer package discount class
L<FS:;cust_bill_pkg_discount> - Customer package discount line item application class
-L<FS:;discount> - Discount class
+L<FS::discount> - Discount class
+
+L<FS::discount_class> - Discount class class
L<FS::reason_type> - Reason type class
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 398d785..fc25a86 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -357,6 +357,7 @@ if ( -e $addl_handler_use_file ) {
use FS::invoice_conf;
use FS::cable_provider;
use FS::cust_credit_void;
+ use FS::discount_class;
# Sammath Naur
if ( $FS::Mason::addl_handler_use ) {
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index cbb50e0..fcc2092 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -2008,6 +2008,7 @@ sub tables_hashref {
'columns' => [
'discountnum', 'serial', '', '', '', '',
#'agentnum', 'int', 'NULL', '', '', '',
+ 'classnum', 'int', 'NULL', '', '', '',
'name', 'varchar', 'NULL', $char_d, '', '',
'amount', @money_type, '', '',
'percent', 'decimal', '', '7,4', '', '',
@@ -2021,6 +2022,18 @@ sub tables_hashref {
'index' => [], # [ 'agentnum' ], ],
},
+ 'discount_class' => {
+ 'columns' => [
+ 'classnum', 'serial', '', '', '', '',
+ 'classname', 'varchar', '', $char_d, '', '',
+ #'categorynum', 'int', 'NULL', '', '', '',
+ 'disabled', 'char', 'NULL', 1, '', '',
+ ],
+ 'primary_key' => 'classnum',
+ 'unique' => [],
+ 'index' => [ ['disabled'] ],
+ },
+
'cust_refund' => {
'columns' => [
'refundnum', 'serial', '', '', '', '',
diff --git a/FS/FS/discount.pm b/FS/FS/discount.pm
index f6f9945..e66d78c 100644
--- a/FS/FS/discount.pm
+++ b/FS/FS/discount.pm
@@ -1,8 +1,9 @@
package FS::discount;
+use base qw( FS::Record );
use strict;
-use base qw( FS::Record );
use FS::Record qw( qsearch qsearchs );
+use FS::discount_class;
=head1 NAME
@@ -130,6 +131,7 @@ sub check {
my $error =
$self->ut_numbern('discountnum')
+ || $self->ut_foreign_keyn('classnum', 'discount_class', 'classnum')
|| $self->ut_textn('name')
|| $self->ut_money('amount')
|| $self->ut_float('percent') #actually decimal, but this will do
@@ -140,16 +142,19 @@ sub check {
;
return $error if $error;
- #discourage non-integer months for package discounts
- if ($self->discountnum) {
- my $sql =
- "SELECT count(*) FROM part_pkg_discount WHERE part_pkg_discount.discountnum = ".
- $self->discountnum;
-
- my $count = $self->scalar_sql($sql);
- return "months must be integers greater than 1"
- if ( $count && ($self->ut_number('months') || $self->months < 2) );
- }
+#causes "months must be integers greater than 1" errors when you go back and
+# try to edit an existing discount (because the months format as NN.000)
+#not worth whatever reason it came in with "prepayment discounts rt#5318" for
+# #discourage non-integer months for package discounts
+# if ($self->discountnum) {
+# my $sql =
+# "SELECT count(*) FROM part_pkg_discount WHERE part_pkg_discount.discountnum = ".
+# $self->discountnum;
+#
+# my $count = $self->scalar_sql($sql);
+# return "months must be integers greater than 1"
+# if ( $count && ($self->ut_number('months') || $self->months < 2) );
+# }
$self->SUPER::check;
}
@@ -195,6 +200,18 @@ sub description {
$desc;
}
+sub classname {
+ my $self = shift;
+ my $discount_class = $self->discount_class;
+ $discount_class ? $discount_class->classname : '(none)';
+}
+
+sub discount_class {
+ my $self = shift;
+ qsearchs('discount_class', { 'classnum' => $self->classnum });
+}
+
+
=back
=head1 BUGS
diff --git a/FS/MANIFEST b/FS/MANIFEST
index e0969f0..e635831 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -727,3 +727,5 @@ FS/cable_provider.pm
t/cable_provider.t
FS/cust_credit_void.pm
t/cust_credit_void.t
+FS/discount_class.pm
+t/discount_class.t
diff --git a/httemplate/browse/discount.html b/httemplate/browse/discount.html
index f26c161..d3cf873 100644
--- a/httemplate/browse/discount.html
+++ b/httemplate/browse/discount.html
@@ -8,8 +8,9 @@
'count_query' => 'SELECT COUNT(*) FROM discount',
'disableable' => 1,
'disabled_statuspos' => 1,
- 'header' => [ 'Name', 'Discount', ],
+ 'header' => [ 'Name', 'Class', 'Discount', ],
'fields' => [ 'name',
+ 'classname',
'description',
],
'links' => [ $link,
diff --git a/httemplate/edit/discount.html b/httemplate/edit/discount.html
index 9bcd1e7..c2853bd 100644
--- a/httemplate/edit/discount.html
+++ b/httemplate/edit/discount.html
@@ -3,6 +3,7 @@
'table' => 'discount',
'fields' => [
'name',
+ { field => 'classnum', type => 'select-discount_class' },
{ field => 'disabled', type => 'checkbox', value=>'Y', },
# a weird kind of false laziness
# w/elements/tr-select-discount.html
@@ -27,6 +28,7 @@
'labels' => {
'discountnum' => 'Discount #',
'name' => 'Name&nbsp;',
+ 'classnum' => 'Class',
'disabled' => 'Disabled&nbsp;',
'_type' => 'Type&nbsp;',
'amount' => 'Amount&nbsp;',
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 8cb9675..b857523 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -564,6 +564,7 @@ if ( $curuser->access_right('Configuration') ) {
#eo package grouping sub-menu
$config_pkg{'Discounts'} = [ $fsurl.'browse/discount.html', '' ];
+ $config_pkg{'Discount classes'} = [ $fsurl.'browse/discount_class.html', '' ];
$config_pkg{'Cancel/Suspend Reasons'} = [ \%config_pkg_reason, '' ];
}
diff --git a/httemplate/graph/report_cust_bill_pkg_discount.html b/httemplate/graph/report_cust_bill_pkg_discount.html
index c599e71..6de84f8 100644
--- a/httemplate/graph/report_cust_bill_pkg_discount.html
+++ b/httemplate/graph/report_cust_bill_pkg_discount.html
@@ -1,28 +1,35 @@
-<% include('/elements/header.html', 'Discount Report' ) %>
+<& /elements/header.html', 'Discount Report' &>
<FORM ACTION="cust_bill_pkg_discount.html" METHOD="GET">
<TABLE>
-<% include('/elements/tr-select-from_to.html' ) %>
+<!--
+ <& /elements/tr-select-discount_class.html,
+ 'field' => 'discount_classnum',
+ 'pre_options' => [ '0' => 'all' ],
+ 'empty_label' => '(none)'
+ &>
+-->
-<% include('/elements/tr-select-agent.html',
- 'label' => 'For agent: ',
- 'disable_empty' => 0,
- )
-%>
+ <& /elements/tr-select-from_to.html &>
-%# anything about line items, discounts or packages really
-%# otaker?
-%# package class?
-%# discount picker? (discount classes and categories? eek!)
+ <& /elements/tr-select-agent.html,
+ 'label' => 'For agent: ',
+ 'disable_empty' => 0,
+ &>
+
+% # anything about line items, discounts or packages really
+% # otaker?
+% # package class?
+% # discount picker? (discount classes and categories? haha yup!)
</TABLE>
<BR><INPUT TYPE="submit" VALUE="Display">
</FORM>
-<% include('/elements/footer.html') %>
+<& /elements/footer.html &>
<%init>
die "access denied"
diff --git a/httemplate/search/cust_bill_pkg_discount.html b/httemplate/search/cust_bill_pkg_discount.html
index f598341..6da5787 100644
--- a/httemplate/search/cust_bill_pkg_discount.html
+++ b/httemplate/search/cust_bill_pkg_discount.html
@@ -7,6 +7,7 @@
'header' => [
#'#',
'Discount',
+ 'Class',
'Amount',
'Months',
'Package',
@@ -17,6 +18,7 @@
'fields' => [
#'billpkgdiscountnum',
sub { $_[0]->cust_pkg_discount->discount->description },
+ sub { $_[0]->cust_pkg_discount->discount->classname },
sub { sprintf($money_char.'%.2f', shift->amount ) },
sub { my $m = shift->months;
$m =~ /\./ ? sprintf('%.2f', $m) : $m;
@@ -28,6 +30,7 @@
],
'sort_fields' => [
'',
+ '',
'amount',
'months',
'pkg',
@@ -40,6 +43,7 @@
'',
'',
'',
+ '',
$ilink,
$ilink,
( map { $_ ne 'Cust. Status' ? $clink : '' }
@@ -47,7 +51,7 @@
),
],
#'align' => 'rlrrrc'.FS::UI::Web::cust_aligns(),
- 'align' => 'lrrlrr'.FS::UI::Web::cust_aligns(),
+ 'align' => 'lcrrlrr'.FS::UI::Web::cust_aligns(),
'color' => [
#'',
'',
@@ -56,6 +60,7 @@
'',
'',
'',
+ '',
FS::UI::Web::cust_colors(),
],
'style' => [
@@ -66,6 +71,7 @@
'',
'',
'',
+ '',
FS::UI::Web::cust_styles(),
],
@@ -98,7 +104,51 @@ if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
push @where, "cust_pkg_discount.usernum = $1";
}
-# #classnum
+# (discount) classnum
+my $join_discount = '';
+#false laziness w/cust_pkg_discount.html and cust_pkg.pm::search
+if ( grep { $_ eq 'discount_classnum' } $cgi->param ) {
+
+# my @classnum = ();
+# if ( ref($params->{'discount_classnum'}) ) {
+#
+# if ( ref($params->{'discount_classnum'}) eq 'HASH' ) {
+# @classnum = grep $params->{'discount_classnum'}{$_}, keys %{ $params->{'discount_classnum'} };
+# } elsif ( ref($params->{'discount_classnum'}) eq 'ARRAY' ) {
+# @classnum = @{ $params->{'discount_classnum'} };
+# } else {
+# die 'unhandled discount_classnum ref '. $params->{'discount_classnum'};
+# }
+#
+#
+# } elsif ( $params->{'discount_classnum'} =~ /^(\d*)$/ && $1 ne '0' ) {
+# @classnum = ( $1 );
+# }
+#
+# if ( @classnum ) {
+
+ if ( $cgi->param('discount_classnum') =~ /^(\d*)$/ && $1 ne '0' ) {
+ my @classnum = ( $1 );
+
+ $join_discount = 'LEFT JOIN discount USING (discountnum)';
+
+ my @c_where = ();
+ my @nums = grep $_, @classnum;
+ push @c_where, 'discount.classnum IN ('. join(',',@nums). ')' if @nums;
+ my $null = scalar( grep { $_ eq '' } @classnum );
+ push @c_where, 'discount.classnum IS NULL' if $null;
+
+ if ( scalar(@c_where) == 1 ) {
+ push @where, @c_where;
+ } elsif ( @c_where ) {
+ push @where, ' ( '. join(' OR ', @c_where). ' ) ';
+ }
+
+ }
+
+}
+
+# #(package) classnum
# # not specified: all classes
# # 0: empty class
# # N: classnum
@@ -121,7 +171,7 @@ if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
# }
# }
-my $count_query = "SELECT COUNT(*), SUM(amount)";
+my $count_query = "SELECT COUNT(*), SUM(cust_bill_pkg_discount.amount)";
my $join_cust_pkg_discount =
'LEFT JOIN cust_pkg_discount USING (pkgdiscountnum)';
@@ -137,11 +187,11 @@ my $join_pkg =
#LEFT JOIN part_pkg AS override
# ON pkgpart_override = override.pkgpart ';
+my $join = "$join_cust_pkg_discount $join_discount $join_pkg $join_cust";
+
my $where = ' WHERE '. join(' AND ', @where);
-$count_query .=
- " FROM cust_bill_pkg_discount $join_cust_pkg_discount $join_pkg $join_cust ".
- $where;
+$count_query .= " FROM cust_bill_pkg_discount $join $where";
my @select = (
'cust_bill_pkg_discount.*',
@@ -155,7 +205,7 @@ push @select, 'cust_main.custnum',
my $query = {
'table' => 'cust_bill_pkg_discount',
- 'addl_from' => "$join_cust_pkg_discount $join_pkg $join_cust",
+ 'addl_from' => $join,
'hashref' => {},
'select' => join(', ', @select ),
'extra_sql' => $where,
diff --git a/httemplate/search/cust_pkg_discount.html b/httemplate/search/cust_pkg_discount.html
index 23af180..f0c7447 100644
--- a/httemplate/search/cust_pkg_discount.html
+++ b/httemplate/search/cust_pkg_discount.html
@@ -6,6 +6,7 @@
#'redirect' => $link,
'header' => [ 'Status',
'Discount',
+ 'Class',
'Months used',
'Employee',
'Package',
@@ -16,6 +17,7 @@
'fields' => [
sub { ucfirst( shift->status ) },
sub { shift->discount->description },
+ sub { shift->discount->classname },
sub { my $m = shift->months_used;
$m =~ /\./ ? sprintf('%.2f',$m) : $m;
},
@@ -29,17 +31,19 @@
'',
'',
'',
+ '',
( map { $_ ne 'Cust. Status' ? $clink : ''}
FS::UI::Web::cust_header()
),
],
- 'align' => 'clrll'. FS::UI::Web::cust_aligns(),
+ 'align' => 'clcrll'. FS::UI::Web::cust_aligns(),
'color' => [
'',
'',
'',
'',
'',
+ '',
FS::UI::Web::cust_colors(),
],
'style' => [
@@ -48,6 +52,7 @@
'',
'',
'',
+ '',
FS::UI::Web::cust_styles(),
],
@@ -78,6 +83,47 @@ if ( $cgi->param('status') eq 'active' ) {
"; #XXX also end date
}
+#classnum
+#false laziness w/cust_pkg.pm::search
+if ( grep { $_ eq 'classnum' } $cgi->param ) {
+
+# my @classnum = ();
+# if ( ref($params->{'classnum'}) ) {
+#
+# if ( ref($params->{'classnum'}) eq 'HASH' ) {
+# @classnum = grep $params->{'classnum'}{$_}, keys %{ $params->{'classnum'} };
+# } elsif ( ref($params->{'classnum'}) eq 'ARRAY' ) {
+# @classnum = @{ $params->{'classnum'} };
+# } else {
+# die 'unhandled classnum ref '. $params->{'classnum'};
+# }
+#
+#
+# } elsif ( $params->{'classnum'} =~ /^(\d*)$/ && $1 ne '0' ) {
+# @classnum = ( $1 );
+# }
+#
+# if ( @classnum ) {
+
+ if ( $cgi->param('classnum') =~ /^(\d*)$/ && $1 ne '0' ) {
+ my @classnum = ( $1 );
+
+ my @c_where = ();
+ my @nums = grep $_, @classnum;
+ push @c_where, 'discount.classnum IN ('. join(',',@nums). ')' if @nums;
+ my $null = scalar( grep { $_ eq '' } @classnum );
+ push @c_where, 'discount.classnum IS NULL' if $null;
+
+ if ( scalar(@c_where) == 1 ) {
+ push @where, @c_where;
+ } elsif ( @c_where ) {
+ push @where, ' ( '. join(' OR ', @c_where). ' ) ';
+ }
+
+ }
+
+}
+
#usernum
if ( $cgi->param('usernum') =~ /^(\d+)$/ ) {
push @where, "cust_pkg_discount.usernum = $1";
diff --git a/httemplate/search/report_cust_bill_pkg_discount.html b/httemplate/search/report_cust_bill_pkg_discount.html
index f9ab901..77affd1 100644
--- a/httemplate/search/report_cust_bill_pkg_discount.html
+++ b/httemplate/search/report_cust_bill_pkg_discount.html
@@ -1,30 +1,35 @@
-<% include('/elements/header.html', 'Discount report' ) %>
+<& /elements/header.html, 'Discount report' &>
<FORM ACTION="cust_bill_pkg_discount.html" METHOD="GET">
<TABLE>
- <% include( '/elements/tr-select-user.html',
- 'label' => 'Discounts by employee: ',
- 'access_user' => \%access_user,
- )
- %>
+ <& /elements/tr-select-discount_class.html,
+ 'field' => 'discount_classnum',
+ 'pre_options' => [ '0' => 'all' ],
+ 'empty_label' => '(none)'
+ &>
- <% include( '/elements/tr-select-agent.html',
- 'curr_value' => scalar( $cgi->param('agentnum') ),
- 'label' => 'for agent: ',
- 'disable_empty' => 0,
- )
- %>
+ <& /elements/tr-select-user.html,
+ 'label' => 'Discounts by employee: ',
+ 'access_user' => \%access_user,
+ &>
- <% include( '/elements/tr-input-beginning_ending.html' ) %>
+ <& /elements/tr-select-agent.html,
+ 'curr_value' => scalar( $cgi->param('agentnum') ),
+ 'label' => 'for agent: ',
+ 'disable_empty' => 0,
+ &>
- <% include( '/elements/tr-input-lessthan_greaterthan.html',
- 'label' => 'Amount',
- 'field' => 'amount',
- )
- %>
+ <& /elements/tr-input-beginning_ending.html &>
+
+<!-- doesn't actually work yet, needs support in cust_bill_pkg_discount.html
+ <& /elements/tr-input-lessthan_greaterthan.html,
+ 'label' => 'Amount',
+ 'field' => 'amount',
+ &>
+-->
</TABLE>
@@ -33,7 +38,7 @@
</FORM>
-<% include('/elements/footer.html') %>
+<& /elements/footer.html &>
<%init>
die "access denied"
diff --git a/httemplate/search/report_cust_pkg_discount.html b/httemplate/search/report_cust_pkg_discount.html
index 31774c3..7f0e55f 100644
--- a/httemplate/search/report_cust_pkg_discount.html
+++ b/httemplate/search/report_cust_pkg_discount.html
@@ -1,4 +1,4 @@
-<% include('/elements/header.html', 'Package discount report' ) %>
+<& /elements/header.html, 'Package discount report' &>
<FORM ACTION="cust_pkg_discount.html" METHOD="GET">
@@ -6,7 +6,7 @@
<TABLE>
<TR>
- <TD>Discount status</TD>
+ <TD ALIGN="right">Discount status</TD>
<TD>
<SELECT NAME="status">
<OPTION VALUE="active">Active
@@ -16,18 +16,21 @@
</TD>
</TR>
- <% include( '/elements/tr-select-user.html',
- 'label' => 'Discounts by employee: ',
- 'access_user' => \%access_user,
- )
- %>
+ <& /elements/tr-select-discount_class.html,
+ 'pre_options' => [ '0' => 'all' ],
+ 'empty_label' => '(none)'
+ &>
- <% include( '/elements/tr-select-agent.html',
- 'curr_value' => scalar( $cgi->param('agentnum') ),
- 'label' => 'for agent: ',
- 'disable_empty' => 0,
- )
- %>
+ <& /elements/tr-select-user.html,
+ 'label' => 'Discounts by employee: ',
+ 'access_user' => \%access_user,
+ &>
+
+ <& /elements/tr-select-agent.html,
+ 'curr_value' => scalar( $cgi->param('agentnum') ),
+ 'label' => 'for agent: ',
+ 'disable_empty' => 0,
+ &>
</TABLE>
@@ -36,7 +39,7 @@
</FORM>
-<% include('/elements/footer.html') %>
+<& /elements/footer.html &>
<%init>
die "access denied"