summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
authorjeff <jeff>2010-09-22 19:16:20 +0000
committerjeff <jeff>2010-09-22 19:16:20 +0000
commit5250c44bd7f282c7d782bf0e8349af12376929df (patch)
treeb2afcd8e47270c6f5b78cff378849168d17ed765 /httemplate
parent60ee9af0e885def0dd61f4a5506ac0e55d779e89 (diff)
prepayment discounts rt#5318
Diffstat (limited to 'httemplate')
-rwxr-xr-xhttemplate/browse/part_pkg.cgi25
-rwxr-xr-xhttemplate/edit/cust_pay.cgi6
-rwxr-xr-xhttemplate/edit/part_pkg.cgi55
-rwxr-xr-xhttemplate/edit/process/cust_pay.cgi2
-rwxr-xr-xhttemplate/edit/process/part_pkg.cgi6
-rw-r--r--httemplate/elements/customer-table.html13
-rw-r--r--httemplate/elements/select-discount_term.html32
-rw-r--r--httemplate/elements/tr-select-discount_term.html25
-rw-r--r--httemplate/misc/batch-cust_pay.html98
-rw-r--r--httemplate/misc/payment.cgi5
-rw-r--r--httemplate/misc/process/batch-cust_pay.cgi13
-rw-r--r--httemplate/misc/process/payment.cgi26
-rw-r--r--httemplate/misc/xmlhttp-cust_main-discount_terms.cgi24
-rw-r--r--httemplate/view/cust_main/packages/package.html1
14 files changed, 305 insertions, 26 deletions
diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi
index 42eb5dfcb..3c3016ba2 100755
--- a/httemplate/browse/part_pkg.cgi
+++ b/httemplate/browse/part_pkg.cgi
@@ -195,6 +195,9 @@ push @fields, sub {
my $part_pkg = shift;
(my $plan = $plan_labels{$part_pkg->plan} ) =~ s/ /&nbsp;/g;
my $is_recur = ( $part_pkg->freq ne '0' );
+ my @discounts = sort { $a->months <=> $b->months }
+ map { $_->discount }
+ $part_pkg->part_pkg_discount;
[
[
@@ -238,6 +241,28 @@ push @fields, sub {
}
$part_pkg->bill_part_pkg_link
),
+ ( scalar(@discounts)
+ ? [
+ { data => '<b>Discounts</b>',
+ align=>'center', #?
+ colspan=>2,
+ }
+ ]
+ : ()
+ ),
+ ( scalar(@discounts)
+ ? map {
+ [
+ { data => $_->months. ':',
+ align => 'right',
+ },
+ { data => $_->amount ? '$'. $_->amount : $_->percent. '%'
+ }
+ ]
+ }
+ @discounts
+ : ()
+ ),
];
# $plan_labels{$part_pkg->plan}.'<BR>'.
diff --git a/httemplate/edit/cust_pay.cgi b/httemplate/edit/cust_pay.cgi
index cc4ec605d..7c4e6620e 100755
--- a/httemplate/edit/cust_pay.cgi
+++ b/httemplate/edit/cust_pay.cgi
@@ -46,6 +46,12 @@ Payment
<TD><INPUT TYPE="text" NAME="paid" VALUE="<% $paid %>" SIZE=8 MAXLENGTH=8> by <B><% FS::payby->payname($payby) %></B></TD>
</TR>
+ <% include('/elements/tr-select-discount_term.html',
+ 'custnum' => $custnum,
+ 'cgi' => $cgi
+ )
+ %>
+
% if ( $payby eq 'BILL' ) {
<TR>
<TD ALIGN="right">Check #</TD>
diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi
index deefa9cc1..9144c4995 100755
--- a/httemplate/edit/part_pkg.cgi
+++ b/httemplate/edit/part_pkg.cgi
@@ -45,6 +45,7 @@
'agentnum' => 'Agent',
'setup_fee' => 'Setup fee',
'recur_fee' => 'Recurring fee',
+ 'discountnum' => 'Offer discounts for longer terms',
'bill_dst_pkgpart' => 'Include line item(s) from package',
'svc_dst_pkgpart' => 'Include services of package',
'report_option' => 'Report classes',
@@ -94,6 +95,7 @@
type => 'selectlayers-select',
options => [ keys %plan_labels ],
labels => \%plan_labels,
+ onchange => 'aux_planchanged(what);',
},
{ field => 'setup_fee',
type => 'money',
@@ -195,6 +197,21 @@
'multiple' => 1,
},
+ { 'type' => 'tablebreak-tr-title',
+ 'value' => 'Term discounts',
+ },
+ { 'field' => 'discountnum',
+ 'type' => 'select-table',
+ 'table' => 'discount',
+ 'name_col' => 'name',
+ 'hashref' => { %$discountnum_hashref },
+ #'extra_sql' => 'AND (months IS NOT NULL OR months != 0)',
+ 'empty_label'=> 'Select discount',
+ 'm2_label' => 'Offer discounts for longer terms',
+ 'm2m_method' => 'part_pkg_discount',
+ 'm2m_dstcol' => 'discountnum',
+ 'm2_error_callback' => $discount_error_callback,
+ },
{ 'type' => 'tablebreak-tr-title',
'value' => 'Pricing add-ons',
@@ -426,6 +443,23 @@ my $clone_callback = sub {
$recur_disabled = $object->freq ? 0 : 1;
};
+my $discount_error_callback = sub {
+ my( $cgi, $object ) = @_;
+ map {
+ if ( /^discountnum(\d+)$/ &&
+ ( my $discountnum = $cgi->param("discountnum$1") ) )
+ {
+ new FS::part_pkg_discount {
+ 'pkgpart' => $object->pkgpart,
+ 'discountnum' => $discountnum,
+ };
+ } else {
+ ();
+ }
+ }
+ $cgi->param;
+};
+
my $m2_error_callback_maker = sub {
my $link_type = shift; #yay closures
return sub {
@@ -484,6 +518,22 @@ my $javascript = <<'END';
}
+ function aux_planchanged(what) {
+
+ alert('called!');
+ var plan = what.options[what.selectedIndex].value;
+ var table = document.getElementById('TableNumber7') // XXX NOT ROBUST
+
+ if ( plan == 'flat' || plan == 'prorate' || plan == 'subscription' ) {
+ //table.disabled = false;
+ table.style.visibility = '';
+ } else {
+ //table.disabled = true;
+ table.style.visibility = 'hidden';
+ }
+
+ }
+
</SCRIPT>
END
@@ -736,4 +786,9 @@ my $field_callback = sub {
}
};
+my $discountnum_hashref = {
+ 'disabled' => '',
+ 'months' => { 'op' => '>', 'value' => 1 },
+ };
+
</%init>
diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi
index df506c677..c8b0aa7df 100755
--- a/httemplate/edit/process/cust_pay.cgi
+++ b/httemplate/edit/process/cust_pay.cgi
@@ -47,7 +47,7 @@ my $new = new FS::cust_pay ( {
map {
$_, scalar($cgi->param($_));
} qw( paid payby payinfo paybatch
- pkgnum
+ pkgnum discount_term
)
#} fields('cust_pay')
} );
diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi
index c0febf828..08cc14086 100755
--- a/httemplate/edit/process/part_pkg.cgi
+++ b/httemplate/edit/process/part_pkg.cgi
@@ -160,6 +160,12 @@ my @process_m2m = (
'target_table' => 'tax_class',
'params' => \@tax_overrides,
},
+ { 'link_table' => 'part_pkg_discount',
+ 'target_table' => 'discount',
+ 'params' => [ map $cgi->param($_),
+ grep /^discountnum/, $cgi->param
+ ],
+ },
{ 'link_table' => 'part_pkg_link',
'target_table' => 'part_pkg',
'base_field' => 'src_pkgpart',
diff --git a/httemplate/elements/customer-table.html b/httemplate/elements/customer-table.html
index f00419f9c..3c3f8b2ee 100644
--- a/httemplate/elements/customer-table.html
+++ b/httemplate/elements/customer-table.html
@@ -22,6 +22,7 @@ Example:
###
'name_singular' => 'customer', #label
+ 'custnum_update_callback' => 'name_of_js_callback' #passed a rownum
#listrefs
'types' => ['immutable', ''], # immutable or ''/text
@@ -98,6 +99,9 @@ Example:
if ( name.length > 0 ) {
customer.value = name;
customer.setAttribute('magic', 'nosearch');
+% if ( $opt{custnum_update_callback} ) {
+ <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
+% }
} else {
customer.value = 'Not found';
customer.style.color = '#ff0000';
@@ -162,6 +166,9 @@ Example:
customer_obj.style.display = '';
customer_select.style.display = 'none';
+% if ( $opt{custnum_update_callback} ) {
+ <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
+% }
} else {
@@ -223,6 +230,10 @@ Example:
this.style.display = 'none';
customer_obj.style.display = '';
+% if ( $opt{custnum_update_callback} ) {
+ <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
+% }
+
}
}
@@ -314,7 +325,7 @@ Example:
>
% } elsif ($types->[$col] eq 'immutable') {
<% $font %><% $value %><% $font ? '</FONT>' : '' %>
- <INPUT TYPE="hidden" NAME="<% $name %>" VALUE="<% $value %>" >
+ <INPUT TYPE="hidden" ID="<% $name %>" NAME="<% $name %>" VALUE="<% $value %>" >
% } else {
Cannot represent unknown type: <% $types->[$col] %>
% }
diff --git a/httemplate/elements/select-discount_term.html b/httemplate/elements/select-discount_term.html
new file mode 100644
index 000000000..26d877a86
--- /dev/null
+++ b/httemplate/elements/select-discount_term.html
@@ -0,0 +1,32 @@
+% if ( scalar(@discount_term) ) {
+ <SELECT NAME="discount_term">
+ <OPTION VALUE="">1 month
+% foreach my $discount_term (@discount_term) {
+% my $sel = ( $cgi->param('discount_term') == $discount_term ) ? 'SELECTED' : '';
+ <OPTION <% $sel %> VALUE="<% $discount_term %>"><% $discount_term. " months" %>
+% }
+ </SELECT>
+% }
+<%init>
+
+my %opt = @_;
+
+my $cgi = $opt{'cgi'};
+
+my @discount_term;
+if ( $opt{discount_term} ) {
+
+ @discount_term = @{ $opt{discount_term} };
+
+} else {
+
+ my $custnum = $opt{'custnum'};
+
+ my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+ or die "unknown custnum $custnum\n";
+
+ @discount_term = $cust_main->discount_terms;
+
+}
+
+</%init>
diff --git a/httemplate/elements/tr-select-discount_term.html b/httemplate/elements/tr-select-discount_term.html
new file mode 100644
index 000000000..58582675d
--- /dev/null
+++ b/httemplate/elements/tr-select-discount_term.html
@@ -0,0 +1,25 @@
+% if ( scalar(@discount_term) ) {
+ <TR>
+ <TD ALIGN="right">Prepayment for</TD>
+ <TD COLSPAN=2>
+ <% include('select-discount_term.html',
+ 'discount_term' => \@discount_term,
+ 'cgi' => $opt{'cgi'},
+ )
+ %>
+ </TD>
+ </TR>
+
+% }
+
+<%init>
+my %opt = @_;
+
+my $custnum = $opt{'custnum'};
+
+my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+ or die "unknown custnum $custnum\n";
+
+my @discount_term = $cust_main->discount_terms;
+
+</%init>
diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html
index 505f2d0ff..610f6e1db 100644
--- a/httemplate/misc/batch-cust_pay.html
+++ b/httemplate/misc/batch-cust_pay.html
@@ -13,23 +13,63 @@ function warnUnload() {
}
}
window.onbeforeunload = warnUnload;
+
+function select_discount_term(row, prefix) {
+ var custnum_obj = document.getElementById('custnum'+prefix+row);
+ var select_obj = document.getElementById('discount_term'+prefix+row);
+
+ var value = '';
+ if (select_obj.type == 'hidden') {
+ value = select_obj.value;
+ }
+
+ var term_select = document.createElement('SELECT');
+ term_select.setAttribute('name', 'discount_term'+row);
+ term_select.setAttribute('id', 'discount_term'+row);
+ term_select.setAttribute('rownum', row);
+ term_select.style.display = '';
+ select_obj.parentNode.replaceChild(term_select, select_obj);
+ opt(term_select, '', '1 month');
+
+ function select_discount_term_update(discount_terms) {
+
+ var termArray = eval('(' + discount_terms + ')');
+ for ( var t = 0; t < termArray.length; t++ ) {
+ opt(term_select, termArray[t][0], termArray[t][1]);
+ if (termArray[t][0] == value) {
+ term_select.selectedIndex = t+1;
+ }
+ }
+
+ }
+
+ discount_terms(custnum_obj.value, select_discount_term_update);
+
+}
</SCRIPT>
+<% include('/elements/xmlhttp.html',
+ 'url' => $p. 'misc/xmlhttp-cust_main-discount_terms.cgi',
+ 'subs' => [qw( discount_terms )],
+ )
+%>
+
<FORM ACTION="process/batch-cust_pay.cgi" NAME="OneTrueForm" METHOD="POST" onsubmit="document.OneTrueForm.submit.disabled=true;window.onbeforeunload = null;">
<!-- <B>Batch</B> <INPUT TYPE="text" NAME="paybatch"><BR><BR> -->
<% include( "/elements/customer-table.html",
name_singular => 'payment',
- header => [ '', 'Amount', 'Check #', '' ],
- fields => [ sub {'$'}, 'paid', 'payinfo', 'error', ],
- types => [ 'immutable', '', '', 'immutable', ],
- align => [ 'c', 'r', 'r', 'l' ],
- sizes => [ 0, 8, 10, 0, ],
- colors => [ '', '', '', '#ff0000' ],
- param => { () },
- footer => [ '$', '_TOTAL', '', '' ],
- footer_align => [ 'c', 'r', 'r', '' ],
+ header => \@header,
+ fields => \@fields,
+ types => \@types,
+ align => \@align,
+ sizes => \@sizes,
+ colors => \@colors,
+ param => \%param,
+ footer => \@footer,
+ footer_align => \@footer_align,
+ custnum_update_callback => $custnum_update_callback,
)
%>
@@ -41,6 +81,14 @@ window.onbeforeunload = warnUnload;
</FORM>
+%if ( $cgi->param('error') ) {
+<SCRIPT TYPE="text/javascript">
+% for ( my $row = 0; defined($cgi->param("custnum$row")); $row++ ) {
+ select_discount_term(<% $row %>, '');
+% }
+</SCRIPT>
+%}
+
<% include('/elements/footer.html') %>
<%init>
@@ -48,4 +96,36 @@ window.onbeforeunload = warnUnload;
die "access denied"
unless $FS::CurrentUser::CurrentUser->access_right('Post payment batch');
+my @header = ( '', 'Amount', 'Check #' );
+my @fields = ( sub {'$'}, 'paid', 'payinfo' );
+my @types = ( 'immutable', '', '' );
+my @align = ( 'c', 'r', 'r' );
+my @sizes = ( 0, 8, 10 );
+my @colors = ( '', '', '' );
+my %param = ();
+my @footer = ( '$', '_TOTAL', '' );
+my @footer_align = ( 'c', 'r', 'r' );
+my $custnum_update_callback = '';
+
+if ( FS::Record->scalar_sql('SELECT count(*) FROM part_pkg_discount') ) {
+ push @header, '';
+ push @fields, 'discount_term';
+ push @types, 'immutable';
+ push @align, 'r';
+ push @sizes, '0';
+ push @colors, '';
+ push @footer, '';
+ push @footer_align, '';
+ $custnum_update_callback = 'select_discount_term';
+}
+
+push @header, '';
+push @fields, 'error';
+push @types, 'immutable';
+push @align, 'l';
+push @sizes, '0';
+push @colors, '#ff0000';
+push @footer, '';
+push @footer_align, '';
+
</%init>
diff --git a/httemplate/misc/payment.cgi b/httemplate/misc/payment.cgi
index 813b560bd..bcab68aae 100644
--- a/httemplate/misc/payment.cgi
+++ b/httemplate/misc/payment.cgi
@@ -67,6 +67,11 @@
% }
+<% include('/elements/tr-select-discount_term.html',
+ 'custnum' => $custnum,
+ 'cgi' => $cgi
+ )
+%>
% if ( $payby eq 'CARD' ) {
%
diff --git a/httemplate/misc/process/batch-cust_pay.cgi b/httemplate/misc/process/batch-cust_pay.cgi
index 4da00c63d..aefc00654 100644
--- a/httemplate/misc/process/batch-cust_pay.cgi
+++ b/httemplate/misc/process/batch-cust_pay.cgi
@@ -11,12 +11,13 @@
% #while ( exists($param->{"custnum$row"}) ) {
% for ( my $row = 0; exists($param->{"custnum$row"}); $row++ ) {
% push @cust_pay, new FS::cust_pay {
-% 'custnum' => $param->{"custnum$row"},
-% 'paid' => $param->{"paid$row"},
-% 'payby' => 'BILL',
-% 'payinfo' => $param->{"payinfo$row"},
-% 'paybatch' => $paybatch,
-% }
+% 'custnum' => $param->{"custnum$row"},
+% 'paid' => $param->{"paid$row"},
+% 'payby' => 'BILL',
+% 'payinfo' => $param->{"payinfo$row"},
+% 'discount_term' => $param->{"discount_term$row"},
+% 'paybatch' => $paybatch,
+% }
% if $param->{"custnum$row"}
% || $param->{"paid$row"}
% || $param->{"payinfo$row"};
diff --git a/httemplate/misc/process/payment.cgi b/httemplate/misc/process/payment.cgi
index 665001ea9..c1c9071f9 100644
--- a/httemplate/misc/process/payment.cgi
+++ b/httemplate/misc/process/payment.cgi
@@ -119,19 +119,26 @@ if ( $payby eq 'CHEK' ) {
die "unknown payby $payby";
}
+$cgi->param('discount_term') =~ /^\d*$/
+ or errorpage("illegal discount_term");
+my $discount_term = $1;
+
my $error = '';
my $paynum = '';
if ( $cgi->param('batch') ) {
- $error = $cust_main->batch_card(
- 'payby' => $payby,
- 'amount' => $amount,
- 'payinfo' => $payinfo,
- 'paydate' => "$year-$month-01",
- 'payname' => $payname,
- map { $_ => $cgi->param($_) }
- @{$payby2fields{$payby}}
- );
+ $error = 'Prepayment discounts not supported with batched payments'
+ if $discount_term;
+
+ $error ||= $cust_main->batch_card(
+ 'payby' => $payby,
+ 'amount' => $amount,
+ 'payinfo' => $payinfo,
+ 'paydate' => "$year-$month-01",
+ 'payname' => $payname,
+ map { $_ => $cgi->param($_) }
+ @{$payby2fields{$payby}}
+ );
errorpage($error) if $error;
} else {
@@ -146,6 +153,7 @@ if ( $cgi->param('batch') ) {
'payunique' => $payunique,
'paycvv' => $paycvv,
'paynum_ref' => \$paynum,
+ 'discount_term' => $discount_term,
map { $_ => $cgi->param($_) } @{$payby2fields{$payby}}
);
errorpage($error) if $error;
diff --git a/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi b/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi
new file mode 100644
index 000000000..71e2da597
--- /dev/null
+++ b/httemplate/misc/xmlhttp-cust_main-discount_terms.cgi
@@ -0,0 +1,24 @@
+% if ( $sub eq 'discount_terms' ) {
+%
+% my $return = [];
+% my $custnum = $cgi->param('arg');
+% my $cust_main = '';
+% $cust_main = qsearchs({
+% 'table' => 'cust_main',
+% 'hashref' => { 'custnum' => $custnum },
+% 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+% });
+%
+% if ($cust_main) {
+% $return = [ map [ $_, "$_ months" ], $cust_main->discount_terms ];
+% }
+%
+<% objToJson($return) %>
+% }
+<%init>
+
+my $conf = new FS::Conf;
+
+my $sub = $cgi->param('sub');
+
+</%init>
diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html
index 3c486dd25..3b58f9ec0 100644
--- a/httemplate/view/cust_main/packages/package.html
+++ b/httemplate/view/cust_main/packages/package.html
@@ -39,6 +39,7 @@
% if ( $curuser->access_right('Discount customer package')
% && $part_pkg->can_discount
% && ! scalar($cust_pkg->cust_pkg_discount_active)
+% && ! scalar($cust_pkg->part_pkg->part_pkg_discount)
% )
% {
% $br=1;