From ec4ae54938488e037977066b28c6a325272b16fc Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Thu, 24 Oct 2013 00:40:05 -0700 Subject: [PATCH] discount classes, RT#24911 --- FS/FS.pm | 4 +- FS/FS/Mason.pm | 1 + FS/FS/Schema.pm | 13 +++++ FS/FS/discount.pm | 39 +++++++++---- FS/MANIFEST | 2 + httemplate/browse/discount.html | 3 +- httemplate/edit/discount.html | 2 + httemplate/elements/menu.html | 1 + .../graph/report_cust_bill_pkg_discount.html | 31 +++++++---- httemplate/search/cust_bill_pkg_discount.html | 64 +++++++++++++++++++--- httemplate/search/cust_pkg_discount.html | 48 +++++++++++++++- .../search/report_cust_bill_pkg_discount.html | 43 ++++++++------- httemplate/search/report_cust_pkg_discount.html | 31 ++++++----- 13 files changed, 216 insertions(+), 66 deletions(-) diff --git a/FS/FS.pm b/FS/FS.pm index b3ebf3050..abba99b19 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -312,7 +312,9 @@ L - Customer package discount class L - Customer package discount line item application class -L - Discount class +L - Discount class + +L - Discount class class L - Reason type class diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 398d78561..fc25a8638 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 cbb50e0bd..fcc2092a7 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 f6f994599..e66d78ced 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 e0969f09c..e63583118 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 f26c161ca..d3cf873d0 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 9bcd1e724..c2853bd47 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 ', + 'classnum' => 'Class', 'disabled' => 'Disabled ', '_type' => 'Type ', 'amount' => 'Amount ', diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 8cb967518..b8575238d 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 c599e71f1..6de84f80b 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' &>
-<% include('/elements/tr-select-from_to.html' ) %> + -<% 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!)

-<% 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 f598341a0..6da5787a0 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 23af1802e..f0c7447a5 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 f9ab901b5..77affd19d 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' &>
- <% 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 &> + +
@@ -33,7 +38,7 @@
-<% 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 31774c384..7f0e55fed 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' &>
@@ -6,7 +6,7 @@ - + - <% 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, + &>
Discount statusDiscount status
@@ -36,7 +39,7 @@
-<% include('/elements/footer.html') %> +<& /elements/footer.html &> <%init> die "access denied" -- 2.11.0