summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/process/quick-charge.cgi108
-rw-r--r--httemplate/edit/quick-charge.html114
-rw-r--r--httemplate/view/cust_main/packages/package.html29
-rw-r--r--httemplate/view/cust_main/payment_history.html14
-rw-r--r--httemplate/view/cust_main/payment_history/voided_credit.html25
5 files changed, 230 insertions, 60 deletions
diff --git a/httemplate/edit/process/quick-charge.cgi b/httemplate/edit/process/quick-charge.cgi
index 38f06e1e9..db41fb238 100644
--- a/httemplate/edit/process/quick-charge.cgi
+++ b/httemplate/edit/process/quick-charge.cgi
@@ -10,8 +10,9 @@
% }
<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
die "access denied"
- unless $FS::CurrentUser::CurrentUser->access_right('One-time charge');
+ unless $curuser->access_right('One-time charge');
my $error = '';
my $conf = new FS::conf;
@@ -27,49 +28,76 @@ $param->{"custnum"} =~ /^(\d+)$/
or $error .= "Illegal customer number " . $param->{"custnum"} . " ";
my $custnum = $1;
-$param->{"amount"} =~ /^\s*(\d*(?:\.?\d{1,2}))\s*$/
- or $error .= "Illegal amount " . $param->{"amount"} . " ";
-my $amount = $1;
+my $cust_main = FS::cust_main->by_key($custnum)
+ or die "custnum $custnum not found";
-my $quantity = 1;
-if ( $cgi->param('quantity') =~ /^\s*(\d+)\s*$/ ) {
- $quantity = $1;
-}
+exists($curuser->agentnums_href->{$cust_main->agentnum})
+ or die "access denied";
-$param->{'tax_override'} =~ /^\s*([,\d]*)\s*$/
- or $error .= "Illegal tax override " . $param->{"tax_override"} . " ";
-my $override = $1;
+if ( $param->{'pkgnum'} =~ /^(\d+)$/ ) {
+ my $pkgnum = $1;
+ die "access denied"
+ unless $curuser->access_right('Modify one-time charge');
-if ( $param->{'taxclass'} eq '(select)' ) {
- $error .= "Must select a tax class. "
- unless ($conf->exists('enable_taxproducts') &&
- ( $override || $param->{taxproductnum} )
- );
- $cgi->param('taxclass', '');
-}
+ my $cust_pkg = FS::cust_pkg->by_key($1)
+ or die "pkgnum $pkgnum not found";
+
+ my $part_pkg = $cust_pkg->part_pkg;
+ die "pkgnum $pkgnum is not a one-time charge" unless $part_pkg->freq eq '0';
+
+ $error = $cust_pkg->modify_charge(
+ 'pkg' => scalar($cgi->param('pkg')),
+ 'classnum' => scalar($cgi->param('classnum')),
+ 'additional' => \@description,
+ 'adjust_commission' => ($cgi->param('adjust_commission') ? 1 : 0),
+ );
+
+} else {
+ # the usual case: new one-time charge
+ $param->{"amount"} =~ /^\s*(\d*(?:\.?\d{1,2}))\s*$/
+ or $error .= "Illegal amount " . $param->{"amount"} . " ";
+ my $amount = $1;
+
+ my $quantity = 1;
+ if ( $cgi->param('quantity') =~ /^\s*(\d+)\s*$/ ) {
+ $quantity = $1;
+ }
+
+ $param->{'tax_override'} =~ /^\s*([,\d]*)\s*$/
+ or $error .= "Illegal tax override " . $param->{"tax_override"} . " ";
+ my $override = $1;
+
+ if ( $param->{'taxclass'} eq '(select)' ) {
+ $error .= "Must select a tax class. "
+ unless ($conf->exists('enable_taxproducts') &&
+ ( $override || $param->{taxproductnum} )
+ );
+ $cgi->param('taxclass', '');
+ }
+
+ unless ( $error ) {
+ my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+ or $error .= "Unknown customer number $custnum. ";
-unless ( $error ) {
- my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
- or $error .= "Unknown customer number $custnum. ";
-
- $error ||= $cust_main->charge( {
- 'amount' => $amount,
- 'quantity' => $quantity,
- 'bill_now' => scalar($cgi->param('bill_now')),
- 'invoice_terms' => scalar($cgi->param('invoice_terms')),
- 'start_date' => ( scalar($cgi->param('start_date'))
- ? parse_datetime($cgi->param('start_date'))
- : ''
- ),
- 'no_auto' => scalar($cgi->param('no_auto')),
- 'pkg' => scalar($cgi->param('pkg')),
- 'setuptax' => scalar($cgi->param('setuptax')),
- 'taxclass' => scalar($cgi->param('taxclass')),
- 'taxproductnum' => scalar($cgi->param('taxproductnum')),
- 'tax_override' => $override,
- 'classnum' => scalar($cgi->param('classnum')),
- 'additional' => \@description,
- } );
+ $error ||= $cust_main->charge( {
+ 'amount' => $amount,
+ 'quantity' => $quantity,
+ 'bill_now' => scalar($cgi->param('bill_now')),
+ 'invoice_terms' => scalar($cgi->param('invoice_terms')),
+ 'start_date' => ( scalar($cgi->param('start_date'))
+ ? parse_datetime($cgi->param('start_date'))
+ : ''
+ ),
+ 'no_auto' => scalar($cgi->param('no_auto')),
+ 'pkg' => scalar($cgi->param('pkg')),
+ 'setuptax' => scalar($cgi->param('setuptax')),
+ 'taxclass' => scalar($cgi->param('taxclass')),
+ 'taxproductnum' => scalar($cgi->param('taxproductnum')),
+ 'tax_override' => $override,
+ 'classnum' => scalar($cgi->param('classnum')),
+ 'additional' => \@description,
+ } );
+ }
}
</%init>
diff --git a/httemplate/edit/quick-charge.html b/httemplate/edit/quick-charge.html
index 466091dfa..666ba82de 100644
--- a/httemplate/edit/quick-charge.html
+++ b/httemplate/edit/quick-charge.html
@@ -104,6 +104,49 @@ function bill_now_changed (what) {
<TABLE ID="QuickChargeTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0 STYLE="background-color: #cccccc">
+% if ( $cust_pkg ) {
+
+<INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $cust_pkg->pkgnum %>">
+<& /elements/tr-fixed.html,
+ label => 'Amount',
+ field => 'amount',
+ value => $money_char . sprintf('%.2f',$part_pkg->option('setup_fee')),
+&>
+
+% if ( $conf->exists('invoice-unitprice') ) {
+<& /elements/tr-fixed.html,
+ label => 'Quantity',
+ field => 'quantity',
+ value => $cust_pkg->quantity
+&>
+% }
+
+<& /elements/tr-select-pkg_class.html, 'curr_value' => $classnum &>
+
+% # crudely estimate whether any agent commission credits might exist
+% my @events = grep { $_->part_event->action =~ /credit/ }
+% $cust_pkg->cust_event;
+% if ( scalar @events ) {
+<TR><TD></TD>
+ <TD><INPUT TYPE="checkbox" NAME="adjust_commission" VALUE="Y" CHECKED>
+<% emt('Adjust commission credits if necessary') %>
+</TD>
+</TR>
+% }
+
+% #display the future or past charge date, but don't allow changes
+% # XXX we probably _could_ let as-yet unbilled charges be rescheduled, but
+% # there's no compelling need yet
+% if ( $cust_pkg->setup or $cust_pkg->start_date ) {
+% my $label = $cust_pkg->setup ? emt('Billed on') : emt('Will be billed');
+% my $field = $cust_pkg->setup ? 'setup' : 'start_date';
+ <& /elements/tr-fixed-date.html,
+ label => $label,
+ value => $cust_pkg->get($field)
+ &>
+% } # else we don't show anything here
+% } else { # new one-time charge
+
<TR>
<TD ALIGN="right"><% mt('Amount') |h %> </TD>
<TD>
@@ -117,7 +160,7 @@ function bill_now_changed (what) {
</TD>
</TR>
-% if ( $conf->exists('invoice-unitprice') ) {
+% if ( $conf->exists('invoice-unitprice') ) {
<TR>
<TD ALIGN="right"><% mt('Quantity') |h %> </TD>
<TD>
@@ -128,9 +171,9 @@ function bill_now_changed (what) {
onKeyPress = "return enable_quick_charge(event)">
</TD>
</TR>
-% }
+% }
-<& /elements/tr-select-pkg_class.html, 'curr_value' => $cgi->param('classnum') &>
+<& /elements/tr-select-pkg_class.html, 'curr_value' => $classnum &>
<TR>
<TD ALIGN="right"><% mt('Invoice now') |h %></TD>
@@ -206,6 +249,8 @@ function bill_now_changed (what) {
<& /elements/tr-select-taxoverride.html, 'onclick' => 'parent.taxoverridemagic(this);', 'curr_value' => $cgi->param('tax_override') &>
+% } # if !$cust_pkg
+
<TR>
<TD ALIGN="right"><% mt('Description') |h %> </TD>
<TD>
@@ -226,11 +271,7 @@ function bill_now_changed (what) {
</TR>
% my $row = 0;
-% if ( $cgi->param('error') || $cgi->param('magic') ) {
-% my $param = $cgi->Vars;
-%
-% for ( $row = 0; exists($param->{"description$row"}); $row++ ) {
-
+% foreach (@description) {
<TR>
<TD></TD>
<TD>
@@ -238,21 +279,25 @@ function bill_now_changed (what) {
NAME = "description<% $row %>"
SIZE = "60"
MAXLENGTH = "65"
- VALUE = "<% $param->{"description$row"} |h %>"
+ VALUE = "<% $_ |h %>"
rownum = "<% $row %>"
onKeyPress = "return enable_quick_charge(event)"
onKeyUp = "return possiblyAddRow(event)"
>
</TD>
</TR>
-% }
+% $row++;
% }
</TABLE>
<BR>
-<INPUT TYPE="submit" ID="submit" NAME="submit" VALUE="<% mt('Add one-time charge') |h %>" <% $cgi->param('error') ? '' :' DISABLED' %>>
+% my $label = $cust_pkg
+% ? emt('Modify one-time charge')
+% : emt('Add one-time charge');
+<INPUT TYPE="submit" ID="submit" NAME="submit" VALUE="<% $label %>" \
+<% ($cgi->param('error') || $cust_pkg) ? '' :' DISABLED' %>>
</FORM>
@@ -329,9 +374,25 @@ my $conf = new FS::Conf;
my $date_format = $conf->config('date_format') || '%m/%d/%Y';
my $money_char = $conf->config('money_char') || '$';
-$cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum';
-my $custnum = $1;
-my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ); #XXX agent-virt
+my ($cust_main, $cust_pkg);
+if ( $cgi->param('change_pkgnum') ) {
+ # change an existing one-time charge
+ die "access denied"
+ unless $curuser->access_right('Modify one-time charge');
+
+ $cgi->param('change_pkgnum') =~ /^(\d+)$/ or die "illegal pkgnum";
+ $cust_pkg = FS::cust_pkg->by_key($1) or die "pkgnum $1 not found";
+ $cust_main = $cust_pkg->cust_main;
+} else {
+ $cgi->param('custnum') =~ /^(\d+)$/ or die 'illegal custnum';
+ $cust_main = FS::cust_main->by_key($1) or die "custnum $1 not found";
+}
+
+my $custnum = $cust_main->custnum;
+# agent-virt
+if (!exists($curuser->agentnums_href->{$cust_main->agentnum})) {
+ die "custnum $custnum not found";
+}
my $format = "%m/%d/%Y %T %z (%Z)"; #false laziness w/REAL_cust_pkg.cgi?
my $start_date = $cust_main->next_bill_date;
@@ -360,4 +421,29 @@ if ( $cust_main->invoice_terms ) {
);
}
+my @description;
+my %param = $cgi->Vars;
+for (my $i = 0; exists($param{"description$i"}); $i++) {
+ push @description, $param{"description$i"};
+}
+
+my $classnum;
+if ( $cgi->param('classnum') =~ /^(\d+)$/ ) {
+ $classnum = $1;
+}
+
+my $part_pkg;
+
+if ( $cust_pkg ) { # set defaults
+ $part_pkg = $cust_pkg->part_pkg;
+ $pkg ||= $part_pkg->pkg;
+ $classnum ||= $part_pkg->classnum;
+ if (!@description) {
+ for (my $i = 0; $i < ($part_pkg->option('additional_count',1) || 0); $i++)
+ {
+ push @description, $part_pkg->option("additional_info$i",1);
+ }
+ }
+}
+
</%init>
diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html
index df804b829..dec13cabc 100644
--- a/httemplate/view/cust_main/packages/package.html
+++ b/httemplate/view/cust_main/packages/package.html
@@ -21,17 +21,21 @@
<TD COLSPAN=2>
<FONT SIZE=-1>
-% unless ( $cust_pkg->get('cancel') || $opt{no_links} ) {
+% if ( $part_pkg->freq eq '0' and !$opt{no_links} ) {
+% # One-time charge. Nothing you can do with this, unless:
+% if ( $curuser->access_right('Modify one-time charge') ) {
+ (&nbsp;<%onetime_change_link($cust_pkg)%>&nbsp;)
+ <BR>
+% }
%
+% } elsif ( !$cust_pkg->get('cancel') and !$opt{no_links} ) {
+%
% if ( $change_from ) {
% # This is the target package for a future change.
% # Nothing you can do with it besides modify/cancel the
% # future change, and that's on the current package.
-% } elsif ( $supplemental or $part_pkg->freq eq '0' ) {
-% # Supplemental packages can't be changed independently.
-% # One-time charges don't need to be changed.
-% # For both of those, we only show "Edit dates", "Add comments",
-% # and "Add invoice details".
+% } elsif ( $supplemental ) {
+% # Show only "Add comments" and "Add invoice details".
% if ( $curuser->access_right('Edit customer package dates') ) {
(&nbsp;<%pkg_dates_link($cust_pkg)%>&nbsp;)
% }
@@ -328,6 +332,19 @@ sub pkg_change_link {
);
}
+sub onetime_change_link {
+ my $cust_pkg = shift;
+ my $pkgnum = $cust_pkg->pkgnum;
+ include( '/elements/popup_link-cust_pkg.html',
+ 'action' => $p. "edit/quick-charge.html?change_pkgnum=$pkgnum",
+ 'label' => emt('Modify one-time charge'),
+ 'actionlabel' => emt('Modify'),
+ 'cust_pkg' => $cust_pkg,
+ 'width' => 690,
+ 'height' => 380,
+ );
+}
+
sub pkg_change_location_link {
my $cust_pkg = shift;
my $pkgpart = $cust_pkg->pkgpart;
diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html
index c7bf3748c..73082ce96 100644
--- a/httemplate/view/cust_main/payment_history.html
+++ b/httemplate/view/cust_main/payment_history.html
@@ -270,6 +270,11 @@
% ? sprintf("-&nbsp;$money_char\%.2f", $item->{'credit'})
% : '';
%
+% $credit ||= sprintf( "<DEL>-&nbsp;$money_char\%.2f</DEL>",
+% $item->{'void_credit'}
+% )
+% if exists($item->{'void_credit'});
+%
% my $refund = exists($item->{'refund'})
% ? sprintf("$money_char\%.2f", $item->{'refund'})
% : '';
@@ -469,6 +474,15 @@ foreach my $cust_pay_void ($cust_main->cust_pay_void) {
}
+#voided credits
+foreach my $cust_credit_void ($cust_main->cust_credit_void) {
+ push @history, {
+ 'date' => $cust_credit_void->_date,
+ 'desc' => include('payment_history/voided_credit.html', $cust_credit_void, %opt ),
+ 'void_credit' => $cust_credit_void->amount,
+ };
+}
+
#declined payments
foreach my $cust_pay_pending ($cust_main->cust_pay_pending_attempt) {
push @history, {
diff --git a/httemplate/view/cust_main/payment_history/voided_credit.html b/httemplate/view/cust_main/payment_history/voided_credit.html
new file mode 100644
index 000000000..0723a7282
--- /dev/null
+++ b/httemplate/view/cust_main/payment_history/voided_credit.html
@@ -0,0 +1,25 @@
+<DEL><% emt("Credit by [_1]", $cust_credit_void->otaker, $reason ) %>\
+<% $reason |h %></DEL>
+<I>
+<% emt("voided [_1]", time2str($date_format, $cust_credit_void->void_date) )%>
+% my $void_user = $cust_credit_void->void_access_user;
+% if ($void_user) {
+<% emt('by [_1]', $void_user->username) %>
+% }
+<% $void_reason |h %>
+</I>
+<%init>
+
+my( $cust_credit_void, %opt ) = @_;
+
+my $date_format = $opt{'date_format'} || '%m/%d/%Y';
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+#my $unvoid = ''; # not yet available
+my $reason = $cust_credit_void->reason;
+$reason = " ($reason)" if $reason;
+
+my $void_reason = $cust_credit_void->void_reason;
+$void_reason = " ($void_reason)" if $void_reason;
+</%init>