summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rw-r--r--httemplate/edit/bulk-part_pkg.html16
-rw-r--r--httemplate/edit/process/bulk-part_pkg.html25
-rw-r--r--httemplate/elements/checkbox-tristate.html57
-rwxr-xr-xhttemplate/search/cust_pay_batch.cgi4
-rwxr-xr-xhttemplate/search/cust_pay_pending.html3
-rw-r--r--httemplate/view/cust_main/payment_history/attempted_batch_payment.html11
-rw-r--r--httemplate/view/cust_main/payment_history/attempted_payment.html12
7 files changed, 89 insertions, 39 deletions
diff --git a/httemplate/edit/bulk-part_pkg.html b/httemplate/edit/bulk-part_pkg.html
index a1c6f0c9b..4665c9f95 100644
--- a/httemplate/edit/bulk-part_pkg.html
+++ b/httemplate/edit/bulk-part_pkg.html
@@ -6,6 +6,7 @@
.row0 { background-color: #eeeeee; }
.row1 { background-color: #ffffff; }
</STYLE>
+<& /elements/error.html &>
<FORM ACTION="process/bulk-part_pkg.html" METHOD="POST">
<DIV>
@@ -22,15 +23,12 @@ The following packages will be changed:<BR>
% foreach my $num (sort keys %report_class) {
<TR CLASS="row<%$row % 2%>">
<TD>
-% if ( defined $initial_state{$num} ) {
- <& /elements/checkbox.html,
- field => 'report_option_'.$num,
- value => 1,
- curr_value => $initial_state{$num}
- &>
-% } else {
+% if ( $initial_state{$num} == -1 ) {
% # needs to be a tristate so that you can say "don't change it"
<& /elements/checkbox-tristate.html, field => 'report_option_'.$num &>
+% } else {
+%# for visual consistency
+ <INPUT TYPE="checkbox" CLASS="partial" NAME="report_option_<%$num%>" VALUE="1" <% $initial_state{$num} ? 'CHECKED':'' %>><LABEL />
% }
</TD>
<TD><% $report_class{$num}->name %></TD>
@@ -64,11 +62,11 @@ foreach my $num (keys %report_class) {
}
}
if ( $yes and $no ) {
- $initial_state{$num} = undef;
+ $initial_state{$num} = -1;
} elsif ( $yes ) {
$initial_state{$num} = 1;
} elsif ( $no ) {
- $initial_state{$num} = 0;
+ $initial_state{$num} = '';
} # else, uh, you didn't provide any pkgparts
}
</%init>
diff --git a/httemplate/edit/process/bulk-part_pkg.html b/httemplate/edit/process/bulk-part_pkg.html
index 4775a9334..59c914a5d 100644
--- a/httemplate/edit/process/bulk-part_pkg.html
+++ b/httemplate/edit/process/bulk-part_pkg.html
@@ -1,6 +1,6 @@
% if ( $error ) {
% $cgi->param('error', $error);
-<% $cgi->redirect(popurl(3).'/edit/bulk-part_pkg.cgi?', $cgi->query_string) %>
+<% $cgi->redirect(popurl(3).'/edit/bulk-part_pkg.html?'.$cgi->query_string) %>
% } else {
<% $cgi->redirect(popurl(3).'/browse/part_pkg.cgi') %>
% }
@@ -10,21 +10,26 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Bulk edi
my @pkgparts = $cgi->param('pkgpart')
or die "no package definitions selected";
-my %changes;
+my %delete = map { 'report_option_'.($_->num) => 1 }
+ qsearch('part_pkg_report_option', {});
+my %insert;
+
foreach my $param (grep { /^report_option_\d+$/ } $cgi->param) {
- if ( length($cgi->param($param)) ) {
- if ( $cgi->param($param) == 1 ) {
- $changes{$param} = 1;
- } else {
- $changes{$param} = '';
- }
- }
+ if ( $cgi->param($param) == 1 ) {
+ $insert{$param} = 1;
+ delete $delete{$param};
+ } elsif ( $cgi->param($param) == -1 ) {
+ # leave it alone
+ delete $delete{$param};
+ } # else it's empty, so leave it on the delete list
}
+
my $error;
foreach my $pkgpart (@pkgparts) {
my $part_pkg = FS::part_pkg->by_key($pkgpart);
- my %options = ( $part_pkg->options, %changes );
+ my %options = ( $part_pkg->options, %insert );
+ delete $options{$_} foreach keys(%delete);
$error ||= $part_pkg->replace( options => \%options );
}
</%init>
diff --git a/httemplate/elements/checkbox-tristate.html b/httemplate/elements/checkbox-tristate.html
index 4c26ed74e..90966a509 100644
--- a/httemplate/elements/checkbox-tristate.html
+++ b/httemplate/elements/checkbox-tristate.html
@@ -2,29 +2,54 @@
A tristate checkbox (with three values: true, false, and null).
Internally, this creates a checkbox, coupled via javascript to a hidden
field that actually contains the value. For now, the only values these
-can have are 1, 0, and empty. Clicking the checkbox cycles between them.
+can have are 1, -1, and empty. Clicking the checkbox cycles between them.
+
+For compatibility with regular checkboxes, empty is the false state and
+-1 is the indeterminate state.
+
+Displaying these is a problem. "indeterminate" is a standard HTML5 attribute
+but some browsers display it in unhelpful ways (e.g. Firefox slightly grays
+the checkbox, approximately #dddddd), and checkboxes ignore nearly all CSS
+styling.
</%doc>
<%shared>
my $init = 0;
</%shared>
% if ( !$init ) {
% $init = 1;
+<STYLE>
+input.partial {
+ position: absolute;
+ opacity: 0;
+ z-index: 1;
+}
+input.partial + label::before {
+ position: relative;
+ content: "\2610";
+}
+input.partial:checked + label::before {
+ content: "\2611";
+}
+input.partial:indeterminate + label::before {
+ content: "\2612";
+}
+</STYLE>
<SCRIPT TYPE="text/javascript">
function tristate_onclick() {
var checkbox = this;
var input = checkbox.input;
- if ( input.value == "" ) {
- input.value = "0";
- checkbox.checked = false;
- checkbox.indeterminate = false;
- } else if ( input.value == "0" ) {
+ if ( input.value == "" ) { // false -> true
input.value = "1";
checkbox.checked = true;
checkbox.indeterminate = false;
- } else if ( input.value == "1" ) {
+ } else if ( input.value == "1" ) { // true -> indeterminate
+ input.value = "-1";
+ checkbox.checked = false;
+ checkbox.indeterminate = true;
+ } else if ( input.value == "-1" ) { // indeterminate -> false
input.value = "";
- checkbox.checked = true;
- checkbox.indeterminate = true
+ checkbox.checked = false;
+ checkbox.indeterminate = false;
}
}
@@ -47,10 +72,10 @@ window.onload = function() { // don't do this until all of the checkboxes exist
// set event handler
tristate_boxes[i].onclick = tristate_onclick;
// set initial value
- if ( tristates[i].value == "" ) {
+ if ( tristates[i].value == "-1" ) {
tristate_boxes[i].indeterminate = true
}
- if ( tristates[i].value != "0" ) {
+ if ( tristates[i].value == "1" ) {
tristate_boxes[i].checked = true;
}
}
@@ -62,6 +87,7 @@ window.onload = function() { // don't do this until all of the checkboxes exist
VALUE="<% $curr_value %>"
CLASS="tristate">
<INPUT TYPE="checkbox" ID="checkbox_<%$opt{field}%>" CLASS="partial">
+<LABEL />
<%init>
my %opt = @_;
@@ -72,7 +98,10 @@ my %opt = @_;
# : '';
$opt{'id'} ||= 'hidden_'.$opt{'field'};
-my $curr_value = $opt{curr_value};
-$curr_value = undef
- unless $curr_value eq '0' or $curr_value eq '1';
+my $curr_value = '-1';
+if (exists $opt{curr_value}) {
+ $curr_value = $opt{curr_value};
+ $curr_value = '' unless $curr_value eq '-1' or $curr_value eq '1';
+}
+
</%init>
diff --git a/httemplate/search/cust_pay_batch.cgi b/httemplate/search/cust_pay_batch.cgi
index 9f9eb30ce..d5fe52ba5 100755
--- a/httemplate/search/cust_pay_batch.cgi
+++ b/httemplate/search/cust_pay_batch.cgi
@@ -30,10 +30,10 @@
sub {
sprintf('%.02f', $_[0]->amount)
},
- 'status',
+ sub { $_[0]->display_status },
'error_message',
],
- 'align' => 'rrrlllcrll',
+ 'align' => 'rrrlllcrlll',
'links' => [ '',
["${p}view/cust_bill.cgi?", 'invnum'],
(["${p}view/cust_main.cgi?", 'custnum']) x 2,
diff --git a/httemplate/search/cust_pay_pending.html b/httemplate/search/cust_pay_pending.html
index 54c9935ef..fe82268f6 100755
--- a/httemplate/search/cust_pay_pending.html
+++ b/httemplate/search/cust_pay_pending.html
@@ -28,6 +28,9 @@ my $edit_pending =
my $status_sub = sub {
my $pending = shift;
my $return = $pending->status;
+ if ( $pending->failure_status ) {
+ $return = $pending->display_status;
+ }
my $action = $statusaction{$pending->status};
return $return unless $action && $edit_pending;
my $link = include('/elements/popup_link.html',
diff --git a/httemplate/view/cust_main/payment_history/attempted_batch_payment.html b/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
index 95947f512..765e54281 100644
--- a/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
+++ b/httemplate/view/cust_main/payment_history/attempted_batch_payment.html
@@ -7,7 +7,14 @@ my ($payby,$payinfo) = translate_payinfo($cust_pay_batch);
$payby = translate_payby($payby,$payinfo);
my $info = $payby ? "($payby$payinfo)" : '';
-$info .= ': '. $cust_pay_batch->error_message
- if length($cust_pay_batch->error_message);
+my $detail = '';
+if ( $cust_pay_batch->failure_status ) {
+ $detail = $cust_pay_batch->display_status;
+ $detail .= ' ('.$cust_pay_batch->error_message.')'
+ if $cust_pay_batch->error_message;
+} else {
+ $detail = $cust_pay_batch->error_message;
+}
+$info .= ': '.$detail if length($detail);
</%init>
diff --git a/httemplate/view/cust_main/payment_history/attempted_payment.html b/httemplate/view/cust_main/payment_history/attempted_payment.html
index f044fc0d4..63209c7c7 100644
--- a/httemplate/view/cust_main/payment_history/attempted_payment.html
+++ b/httemplate/view/cust_main/payment_history/attempted_payment.html
@@ -12,7 +12,15 @@ if ( $opt{'pkg-balances'} && $cust_pay_pending->pkgnum ) {
$info .= ' for '. $cust_pkg->pkg_label_long;
}
-$info .= ': '. $cust_pay_pending->statustext
- if length($cust_pay_pending->statustext);
+my $detail = '';
+if ( $cust_pay_pending->failure_status ) {
+ $detail = $cust_pay_pending->display_status;
+ $detail .= ' (' . $cust_pay_pending->statustext . ')'
+ if $cust_pay_pending->statustext;
+} else {
+ $detail = $cust_pay_pending->statustext;
+}
+
+$info .= ': '.$detail if length($detail);
</%init>