[freeside-commits] branch master updated. f4bb9273f1ba174858e221fd37f6dd1dca4119e9
Mark Wells
mark at 420.am
Tue Sep 6 13:32:02 PDT 2016
The branch, master has been updated
via f4bb9273f1ba174858e221fd37f6dd1dca4119e9 (commit)
from c33b039c24de7192a72b172b317937f749c2cea3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f4bb9273f1ba174858e221fd37f6dd1dca4119e9
Author: Mark Wells <mark at freeside.biz>
Date: Tue Sep 6 12:42:34 2016 -0700
UI improvements for selecting taxproducts, #71555 and #71556
diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi
index 1e8b510..acc3211 100755
--- a/httemplate/browse/part_pkg.cgi
+++ b/httemplate/browse/part_pkg.cgi
@@ -27,6 +27,19 @@
'html_foot' => $html_foot,
)
%>
+<%def .style>
+<STYLE TYPE="text/css">
+ .taxproduct_desc {
+ color: blue;
+ text-decoration: underline dotted;
+ }
+</STYLE>
+<SCRIPT TYPE="text/javascript">
+$().ready(function() {
+ $('.taxproduct_desc').tooltip({});
+});
+</SCRIPT>
+</%def>
<%init>
my $curuser = $FS::CurrentUser::CurrentUser;
@@ -45,6 +58,7 @@ die "access denied"
my $conf = new FS::Conf;
my $taxclasses = $conf->exists('enable_taxclasses');
+my $taxvendor = $conf->config('tax_data_vendor');
my $money_char = $conf->config('money_char') || '$';
my $select = '*';
@@ -180,6 +194,7 @@ my $html_init = qq!
</FORM>
<BR><BR>
!;
+$html_init .= include('.style');
$cgi->param('dummy', 1);
@@ -562,6 +577,43 @@ if ( $taxclasses ) {
push @header, 'Taxclass';
push @fields, sub { shift->taxclass() || ' '; };
$align .= 'l';
+} elsif ( $taxvendor ) {
+ push @header, 'Tax product';
+ my @classnums = ( 'setup', 'recur' );
+ my @classnames = ( 'Setup', 'Recur' );
+ foreach ( qsearch('usage_class', { disabled => '' }) ) {
+ push @classnums, $_->classnum;
+ push @classnames, $_->classname;
+ }
+ my $taxproduct_sub = sub {
+ my $ppt = shift;
+ '<SPAN CLASS="taxproduct_desc" TITLE="' .
+ encode_entities($ppt->description) .
+ '">' . encode_entities($ppt->taxproduct) . '</SPAN>'
+ };
+ my $taxproduct_list_sub = sub {
+ my $part_pkg = shift;
+ my $base_ppt = $part_pkg->taxproduct;
+ my $out = [];
+ if ( $base_ppt ) {
+ push @$out, [
+ { 'data' => '', 'align' => 'left' },
+ { 'data' => &$taxproduct_sub($base_ppt), 'align' => 'right' },
+ ];
+ }
+ for (my $i = 0; $i < scalar @classnums; $i++) {
+ my $num = $part_pkg->option('usage_taxproductnum_' . $classnums[$i]);
+ next if !$num;
+ my $ppt = FS::part_pkg_taxproduct->by_key($num);
+ push @$out, [
+ { 'data' => $classnames[$i] . ': ', 'align' => 'left', },
+ { 'data' => &$taxproduct_sub($ppt), 'align' => 'right' },
+ ];
+ }
+ $out;
+ };
+ push @fields, $taxproduct_list_sub;
+ $align .= 'l';
}
# make a table of report class optionnames => the actual
@@ -602,7 +654,9 @@ push @fields,
sort
grep { $options{$_} =~ /\S/ }
grep { $_ !~ /^(setup|recur)_fee$/
- and $_ !~ /^report_option_\d+$/ }
+ and $_ !~ /^report_option_\d+$/
+ and $_ !~ /^usage_taxproductnum_/
+ }
keys %options
);
if ( @report_options ) {
diff --git a/httemplate/browse/part_pkg_taxproduct/suretax.html b/httemplate/browse/part_pkg_taxproduct/suretax.html
index 9c00c5c..8f237f3 100755
--- a/httemplate/browse/part_pkg_taxproduct/suretax.html
+++ b/httemplate/browse/part_pkg_taxproduct/suretax.html
@@ -138,8 +138,7 @@ my $id = $cgi->param('id');
my $select_onclick = sub {
my $row = shift;
my $taxnum = $row->taxproductnum;
- my $code = $row->taxproduct;
- my $desc = $row->description;
+ my $desc = $row->taxproduct . ' ' . $row->description;
"select_taxproduct('$taxnum', '$desc')";
};
diff --git a/httemplate/elements/select-taxproduct.html b/httemplate/elements/select-taxproduct.html
index 5feb71d..d08ac22 100644
--- a/httemplate/elements/select-taxproduct.html
+++ b/httemplate/elements/select-taxproduct.html
@@ -1,14 +1,79 @@
-<% $opt{'prefix'} %><INPUT NAME = "<% $name %>"
- ID = "<% $name %>"
- TYPE = "hidden"
- VALUE = "<% $value |h %>"
- >
- <INPUT NAME = "<% $name %>_description"
- ID = "<% $name %>_description"
- TYPE = "text"
- VALUE = "<% $description %>"
- SIZE = "12"
- onClick = "<% $onclick %>"><% $opt{'postfix'} %>
+% if (!$init) {
+% $init = 1;
+<STYLE TYPE="text/css">
+.ui-autocomplete-loading {
+ background-color: silver;
+}
+ul.ui-autocomplete li.ui-menu-item {
+ font-size: 0.8em;
+ padding: 2px;
+}
+ul.ui-autocomplete li.ui-state-focus {
+ font-weight: normal;
+ color: #7e0079;
+ background-color: inherit;
+ border: 1px solid #7e0079;
+}
+</STYLE>
+<SCRIPT TYPE="text/javascript">
+$().ready(function() {
+ $('input.taxproduct_desc').autocomplete({
+ source: '<% $fsurl %>misc/taxproduct.cgi',
+ minLength: 3,
+ autoFocus: true,
+ response: function( event, ui ) {
+ // if there's only one choice (user entered an exact taxproduct) then
+ // select it
+ if ( ui.content.length == 1 ) {
+ var input_taxproductnum = $(this).siblings('.taxproductnum')
+ var item = ui.content[0];
+ $(this).val(item.label);
+ input_taxproductnum.val(item.value);
+ }
+ },
+ focus: function( event, ui ) {
+ return false;
+ },
+ select: function( event, ui ) {
+ // find the hidden input for the taxproductnum
+ var input_taxproductnum = $(this).siblings('.taxproductnum')
+ if ( ui.item ) {
+ $(this).val(ui.item.label);
+ input_taxproductnum.val(ui.item.value);
+ return false; // don't store item.value in this input
+ } else {
+ input_taxproductnum.val('');
+ }
+ },
+ change: function( event, ui ) {
+ var input_taxproductnum = $(this).siblings('.taxproductnum')
+ if ( $(this).val() == '' ) {
+ input_taxproductnum.val('');
+ }
+ }
+ });
+});
+</SCRIPT>
+% }
+<% $opt{'prefix'} %>
+<INPUT NAME = "<% $name %>"
+ ID = "<% $name %>"
+ TYPE = "hidden"
+ VALUE = "<% $value |h %>"
+ CLASS = "taxproductnum"
+>
+<INPUT NAME = "<% $name %>_description"
+ ID = "<% $name %>_description"
+ TYPE = "text"
+ VALUE = "<% $description %>"
+ SIZE = "50"
+ CLASS = "taxproduct_desc"
+>
+<BUTTON STYLE="padding: 0" onclick="<% $onclick %>">...</BUTTON>
+<% $opt{'postfix'} %>
+<%shared>
+my $init = 0;
+</%shared>
<%init>
my %opt = @_;
@@ -19,7 +84,8 @@ my $description = $opt{'taxproduct_description'};
unless ( $description || ! $value ) {
my $part_pkg_taxproduct =
qsearchs( 'part_pkg_taxproduct', { 'taxproductnum'=> $value } );
- $description = $part_pkg_taxproduct->description
+ $description = $part_pkg_taxproduct->taxproduct . ' ' .
+ $part_pkg_taxproduct->description
if $part_pkg_taxproduct;
}
diff --git a/httemplate/elements/tr-part_pkg-taxproducts.html b/httemplate/elements/tr-part_pkg-taxproducts.html
index c57232c..5dcea09 100644
--- a/httemplate/elements/tr-part_pkg-taxproducts.html
+++ b/httemplate/elements/tr-part_pkg-taxproducts.html
@@ -1,18 +1,39 @@
+%# by default, only show default
<TR>
- <TH COLSPAN=2>Tax products</TH>
+ <TH ALIGN="right"><% emt('Tax product') %></TH>
+ <TD><& select-taxproduct.html,
+ %opt,
+ 'field' => $field.'_', # expected in edit/process/part_pkg
+ 'curr_value' => $curr_values{''},
+ &>
+ </TD>
+</TR>
+% if ( !$separate ) {
+<TR STYLE="font-size: small">
+ <TD></TD>
+ <TD>
+ <BUTTON TYPE="button" ID="show_taxproduct_class">By usage class
+ <IMG SRC="<%$fsurl%>images/arrow.down.black.png">
+ </BUTTON>
+ </TD>
</TR>
+<SCRIPT TYPE="text/javascript">
+$().ready(function() {
+ $('#show_taxproduct_class').on('click', function() {
+ this.disabled = true;
+ $('tr.taxproduct_class').show();
+ });
+});
+</SCRIPT>
+% }
% foreach my $usage_class (@classes) {
% my $classnum = $usage_class->classnum;
-% my $curr_value =
-% $cgi->param("usage_taxproductnum_$classnum")
-% || $pkg_options{"usage_taxproductnum_$classnum"}
-% || '';
-<TR>
- <TD><% $usage_class->classname %></TD>
+<TR CLASS="taxproduct_class" STYLE="<% $separate ? '' : 'display:none' %>">
+ <TH ALIGN="right"><% $usage_class->classname %></TH>
<TD><& select-taxproduct.html,
%opt,
'field' => $field.'_'.$classnum,
- 'curr_value' => $curr_value
+ 'curr_value' => $curr_values{$classnum},
&>
</TD>
</TR>
@@ -20,18 +41,29 @@
<%init>
my %opt = @_;
my $field = delete($opt{field}) || 'taxproductnum';
+my @classes = qsearch('usage_class', { 'disabled' => '' });
+unshift @classes,
+ FS::usage_class->new({ 'classnum' => 'setup', 'classname' => 'Setup', }),
+ FS::usage_class->new({ 'classnum' => 'recur', 'classname' => 'Recur', }),
+;
+my $separate = 0; # will change to 1 if any non-default classes have values
+
my $pkgpart = delete($opt{pkgpart});
+my %curr_values;
my %pkg_options;
if ($pkgpart) {
my $part_pkg = FS::part_pkg->by_key($pkgpart);
%pkg_options = $part_pkg->options;
- $pkg_options{'usage_taxproductnum_'} = $part_pkg->taxproductnum;
+ $curr_values{''} = $part_pkg->taxproductnum;
}
-my @classes = qsearch('usage_class', { 'disabled' => '' });
-unshift @classes,
- FS::usage_class->new({ 'classnum' => '', 'classname' => '(default)', }),
- FS::usage_class->new({ 'classnum' => 'setup', 'classname' => 'Setup', }),
- FS::usage_class->new({ 'classnum' => 'recur', 'classname' => 'Recur', }),
-;
+foreach my $usage_class (@classes) {
+ my $classnum = $usage_class->classnum;
+ my $curr_value =
+ $cgi->param("usage_taxproductnum_$classnum")
+ || $pkg_options{"usage_taxproductnum_$classnum"}
+ || '';
+ $curr_values{$classnum} = $curr_value;
+ $separate = 1 if ( length($classnum) and length($curr_value) );
+}
</%init>
diff --git a/httemplate/misc/taxproduct.cgi b/httemplate/misc/taxproduct.cgi
new file mode 100644
index 0000000..b228493
--- /dev/null
+++ b/httemplate/misc/taxproduct.cgi
@@ -0,0 +1,24 @@
+<%once>
+my $conf = FS::Conf->new;
+my $vendor = $conf->config('tax_data_vendor');
+</%once>
+<%init>
+my $term = $cgi->param('term');
+warn "taxproduct.cgi?$term"; # XXX debug
+my $search = { table => 'part_pkg_taxproduct' };
+if ( $term =~ /^\d+$/ ) {
+ $search->{extra_sql} = " WHERE taxproduct LIKE '$term%'";
+ $search->{order_by} = " ORDER BY taxproduct ASC";
+} elsif ( length($term) ) {
+ $term = dbh->quote( lc($term) ); # protect against bad strings
+ $search->{extra_sql} = " WHERE POSITION($term IN LOWER(description)) > 0";
+ # and sort by how close to the beginning of the string it is
+ $search->{order_by} = " ORDER BY POSITION($term IN LOWER(description)) ASC, LOWER(description) ASC, taxproduct ASC";
+}
+my @taxproducts = qsearch($search);
+my @results = map {
+ { label => $_->taxproduct . ' ' . $_->description,
+ value => $_->taxproductnum }
+} @taxproducts;
+</%init>
+<% encode_json(\@results) %>\
-----------------------------------------------------------------------
Summary of changes:
httemplate/browse/part_pkg.cgi | 56 +++++++++++-
httemplate/browse/part_pkg_taxproduct/suretax.html | 3 +-
httemplate/elements/select-taxproduct.html | 90 +++++++++++++++++---
httemplate/elements/tr-part_pkg-taxproducts.html | 62 ++++++++++----
httemplate/misc/taxproduct.cgi | 24 ++++++
5 files changed, 205 insertions(+), 30 deletions(-)
create mode 100644 httemplate/misc/taxproduct.cgi
More information about the freeside-commits
mailing list