summaryrefslogtreecommitdiff
path: root/httemplate/browse/part_pkg_taxproduct
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2014-10-31 15:45:50 -0700
committerMark Wells <mark@freeside.biz>2014-10-31 15:45:50 -0700
commit7516e3da0f17eeecba27219ef96a8b5f46af2083 (patch)
tree772fe13627910a7d0774871633697f2a4d1c6faf /httemplate/browse/part_pkg_taxproduct
parentf31a9212ab3835b815aa87a86cca3b19babcaaff (diff)
tax engine refactoring for Avalara and Billsoft tax vendors, #25718
Diffstat (limited to 'httemplate/browse/part_pkg_taxproduct')
-rwxr-xr-xhttemplate/browse/part_pkg_taxproduct/avalara.html84
-rwxr-xr-xhttemplate/browse/part_pkg_taxproduct/billsoft.html146
-rwxr-xr-xhttemplate/browse/part_pkg_taxproduct/cch.html236
3 files changed, 466 insertions, 0 deletions
diff --git a/httemplate/browse/part_pkg_taxproduct/avalara.html b/httemplate/browse/part_pkg_taxproduct/avalara.html
new file mode 100755
index 000000000..e8da58962
--- /dev/null
+++ b/httemplate/browse/part_pkg_taxproduct/avalara.html
@@ -0,0 +1,84 @@
+<& /elements/header-popup.html, { title => 'Select tax product' } &>
+<form NAME="myform">
+<table class="inv" width="100%">
+<& /elements/tr-select-table.html,
+ 'label' => 'Tax product',
+ 'field' => 'taxproductnum',
+ 'table' => 'part_pkg_taxproduct',
+ 'hashref' => { data_vendor => 'avalara' },
+ 'name_col' => 'taxproduct', # for sorting
+ 'label_callback' => $label_callback,
+ 'curr_value' => $taxproductnum,
+ 'empty_label' => 'none',
+ 'onchange' => 'select_onchange',
+&>
+</table>
+<table class="inv" width="100%">
+<tr>
+ <td style="border-top: 1px solid #7e0079; text-align: center" colspan=2>
+ Add a new tax product</td>
+</tr>
+<tr>
+ <td style="text-align: right">Avalara tax code</td>
+ <td><input name="taxproduct" size=8></td>
+</tr>
+<tr>
+ <td style="text-align: right">Description</td>
+ <td><input name="description" size=20></td>
+</tr>
+<tr>
+ <td colspan="2" style="text-align: center">
+ <input type="button" onclick="add_new()" value="Add" />
+ </td>
+</tr>
+</table>
+</form>
+<SCRIPT TYPE="text/javascript">
+function select_onchange() {
+ var select = document.forms['myform']['taxproductnum'];
+ parent.document.getElementById('<% $id %>').value = select.value;
+ parent.document.getElementById('<% $id %>_description').value =
+ select.options[select.selectedIndex].text;
+ parent.nd(1);
+}
+function add_new() {
+ parent.document.getElementById('<% $id %>').value = -1;
+ parent.document.getElementById('<% $id %>_description').value =
+ document.forms['myform']['taxproduct'].value + ' ' +
+ document.forms['myform']['description'].value;
+ parent.nd(1);
+}
+</SCRIPT>
+</BODY>
+</HTML>
+<%once>
+
+my $conf = new FS::Conf;
+
+</%once>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Edit package definitions');
+
+warn Dumper({ $cgi->Vars });
+
+# id: where to put the taxproductnum (in the parent document) after the user
+# selects it
+$cgi->param('id') =~ /^([ \w]+)$/
+ or die "id parameter required";
+my $id = $1;
+
+# current value of taxproductnum
+my $taxproductnum = '';
+if ($cgi->param('taxproductnum') =~ /^(\d+)$/) {
+ $taxproductnum = $1;
+}
+
+my $label_callback = sub {
+ my $part_pkg_taxproduct = shift;
+ join(' ', $part_pkg_taxproduct->taxproduct,
+ $part_pkg_taxproduct->description);
+};
+
+</%init>
diff --git a/httemplate/browse/part_pkg_taxproduct/billsoft.html b/httemplate/browse/part_pkg_taxproduct/billsoft.html
new file mode 100755
index 000000000..c58ac30fa
--- /dev/null
+++ b/httemplate/browse/part_pkg_taxproduct/billsoft.html
@@ -0,0 +1,146 @@
+<& /elements/header-popup.html, $title &>
+<& /browse/elements/browse.html,
+ 'name_singular' => 'tax product',
+ 'html_form' => include('.form', $service_code, $trans_code),
+ 'query' => {
+ 'table' => 'part_pkg_taxproduct',
+ 'hashref' => $hashref,
+ 'order_by' => 'ORDER BY taxproduct',
+ },
+ 'count_query' => $count_query,
+ 'header' => \@header,
+ 'fields' => \@fields,
+ 'align' => $align,
+ 'links' => [],
+ 'link_onclicks' => \@link_onclicks,
+ 'nohtmlheader' => 1,
+&>
+<%shared>
+# populate dropdowns
+
+# taxproduct is 12 digits. First half is the service type code, second
+# half is the transaction code. Description is also two parts, corresponding
+# to those codes, separated with a :.
+
+my (@service_codes, @trans_codes, %service_labels, %trans_labels);
+foreach my $row ( qsearch({
+ table => 'part_pkg_taxproduct',
+ select => 'DISTINCT substr(taxproduct, 1, 6) AS code, '.
+ "substring(description from '(.*):') AS label",
+ }))
+{
+ $service_labels{$row->get('code')} =
+ sprintf('%02d %s', $row->get('code'), $row->get('label'));
+}
+foreach my $row ( qsearch({
+ table => 'part_pkg_taxproduct',
+ select => 'DISTINCT substr(taxproduct, 7, 6) AS code, '.
+ "substring(description from ':(.*)') AS label",
+ }))
+{
+ $trans_labels{$row->get('code')} =
+ sprintf('%02d %s', $row->get('code'), $row->get('label'));
+}
+$service_labels{''} = $trans_labels{''} = '';
+
+@service_codes = sort {$a <=> $b} keys %service_labels;
+@trans_codes = sort {$a <=> $b} keys %trans_labels;
+
+</%shared>
+<%def .form>
+% my ($service_code, $trans_code) = @_;
+<FORM ACTION="<% $cgi->url %>" METHOD="GET">
+<& /elements/select.html,
+ field => 'service_code',
+ options => \@service_codes,
+ labels => \%service_labels,
+ curr_value => $service_code,
+ onchange => 'this.form.submit()',
+&>
+&nbsp;
+<& /elements/select.html,
+ field => 'trans_code',
+ options => \@trans_codes,
+ labels => \%trans_labels,
+ curr_value => $trans_code,
+ onchange => 'this.form.submit()',
+&>
+<& /elements/hidden.html,
+ field => 'id',
+ curr_value => $cgi->param('id'),
+&>
+</%def>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+$cgi->param('id') =~ /^\w+$/ or die "missing id parameter";
+my $id = $cgi->param('id');
+
+my $select_onclick = sub {
+ my $row = shift;
+ my $taxnum = $row->taxproductnum;
+ my $desc = $row->description;
+ "parent.document.getElementById('$id').value = $taxnum;".
+ "parent.document.getElementById('${id}_description').value = '$desc';".
+ "parent.cClick();";
+}
+ if $id;
+
+my @menubar;
+my $title = 'Tax Products';
+
+my $hashref = { data_vendor => 'billsoft' };
+
+my ($service_code, $trans_code, $taxproduct);
+if ( $cgi->param('service_code') =~ /^(\d+)$/ ) {
+ $service_code = $1;
+ $taxproduct = sprintf('%06d', $service_code);
+} else {
+ $taxproduct = '%';
+}
+
+if ( $cgi->param('trans_code') =~ /^(\d+)$/ ) {
+ $trans_code = $1;
+ $taxproduct .= sprintf('%06d', $trans_code);
+} elsif ( $service_code ) {
+ $taxproduct .= '%';
+}
+
+$hashref->{taxproduct} = { op => 'LIKE', value => $taxproduct };
+
+my $count_query = "SELECT COUNT(*) FROM part_pkg_taxproduct ".
+ "WHERE data_vendor = 'billsoft' AND ".
+ "taxproduct LIKE '$taxproduct'";
+
+my $sub_service_desc = sub {
+ my $ppt = shift; #part_pkg_taxproduct
+ my @codes = ($ppt->taxproduct =~ /(\d{6})(\d{6})/);
+ my @descs = split(':', $ppt->description);
+ $ppt->set('service_desc' => sprintf('%02d %s', $codes[0], $descs[0]));
+ $ppt->set('trans_desc' => sprintf('%02d %s', $codes[1], $descs[1]));
+ $ppt->service_desc;
+};
+
+my $sub_trans_desc = sub {
+ my $ppt = shift;
+ $ppt->trans_desc;
+};
+
+my @fields = (
+ $sub_service_desc,
+ $sub_trans_desc,
+ 'note'
+);
+
+my @header = (
+ 'Service Type',
+ 'Transaction',
+ '',
+);
+
+my $align = 'lll';
+my @link_onclicks = ( $select_onclick, $select_onclick );
+
+</%init>
diff --git a/httemplate/browse/part_pkg_taxproduct/cch.html b/httemplate/browse/part_pkg_taxproduct/cch.html
new file mode 100755
index 000000000..b901bad9f
--- /dev/null
+++ b/httemplate/browse/part_pkg_taxproduct/cch.html
@@ -0,0 +1,236 @@
+<% include( '../elements/browse.html',
+ 'title' => "Tax Products $title",
+ 'name_singular' => 'tax product',
+ 'menubar' => \@menubar,
+ 'html_init' => $html_init,
+ 'query' => {
+ 'table' => 'part_pkg_taxproduct',
+ 'hashref' => $hashref,
+ 'order_by' => 'ORDER BY description',
+ 'extra_sql' => $extra_sql,
+ },
+ 'count_query' => $count_query,
+ 'header' => \@header,
+ 'fields' => \@fields,
+ 'align' => $align,
+ 'links' => \@links,
+ 'link_onclicks' => \@link_onclicks,
+ )
+%>
+<%once>
+
+my $conf = new FS::Conf;
+
+my $select_link = [ 'javascript:void(0);', sub { ''; } ];
+
+</%once>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my @menubar;
+my $title = '';
+my $onclick = 'cClick';
+
+my $data_vendor = 'cch';
+
+$title = " for $title" if $title;
+
+my $taxproductnum = $1
+ if ( $cgi->param('taxproductnum') =~ /^(\d+)$/ );
+my $tax_group = $1
+ if ( $cgi->param('tax_group') =~ /^([- \w\(\).\/]+)$/ );
+my $tax_item = $1
+ if ( $cgi->param('tax_item') =~ /^([- \w\(\).\/&%]+)$/ );
+my $tax_provider = $1
+ if ( $cgi->param('tax_provider') =~ /^([ \w]+)$/ );
+my $tax_customer = $1
+ if ( $cgi->param('tax_customer') =~ /^([ \w]+)$/ );
+my $id = $1
+ if ( $cgi->param('id') =~ /^([ \w]+)$/ );
+
+$onclick = $1
+ if ( $cgi->param('onclick') =~ /^(\w+)$/ );
+$cgi->delete('onclick');
+
+my $remove_onclick = <<EOS
+ parent.document.getElementById('$id').value = '';
+ parent.document.getElementById('${id}_description').value = '';
+ parent.$onclick();
+EOS
+ if $id;
+
+my $select_onclick = sub {
+ my $row = shift;
+ my $taxnum = $row->taxproductnum;
+ my $desc = $row->description;
+ "parent.document.getElementById('$id').value = $taxnum;".
+ "parent.document.getElementById('${id}_description').value = '$desc';".
+ "parent.$onclick();";
+}
+ if $id;
+
+my $selected_part_pkg_taxproduct;
+if ($taxproductnum) {
+ $selected_part_pkg_taxproduct =
+ qsearchs('part_pkg_taxproduct', { 'taxproductnum' => $taxproductnum });
+}
+
+my $hashref = {};
+my $extra_sql .= ' WHERE data_vendor = '. dbh->quote($data_vendor);
+
+if ($tax_group || $tax_item || $tax_customer || $tax_provider) {
+ my $compare = "LIKE '". ( $tax_group || "%" ). " : ". ( $tax_item || "%" ). " : ".
+ ( $tax_provider || "%" ). " : ". ( $tax_customer || "%" ). "'";
+ $compare = "= '$tax_group:$tax_item:$tax_provider:$tax_customer'"
+ if ($tax_group && $tax_item && $tax_provider && $tax_customer);
+
+ $extra_sql .= ($extra_sql =~ /WHERE/ ? ' AND ' : ' WHERE ').
+ "description $compare";
+
+}
+$cgi->delete('tax_group');
+$cgi->delete('tax_item');
+$cgi->delete('tax_provider');
+$cgi->delete('tax_customer');
+
+
+if ( $tax_group || $tax_item || $tax_provider || $tax_customer ) {
+ push @menubar, 'View all tax products' => $p.'browse/part_pkg_taxproduct.cgi';
+}
+
+$cgi->param('dummy', 1);
+
+#restore this so pagination works
+$cgi->param('tax_group', $tax_group) if $tax_group;
+$cgi->param('tax_item', $tax_item ) if $tax_item;
+$cgi->param('tax_provider', $tax_provider ) if $tax_provider;
+$cgi->param('tax_customer', $tax_customer ) if $tax_customer;
+$cgi->param('onclick', $onclick ) if $onclick;
+
+my $count_query = "SELECT COUNT(*) FROM part_pkg_taxproduct $extra_sql";
+
+my @header = ( 'Group', 'Item', 'Provider', 'Customer' );
+my @links = ( $select_link,
+ $select_link,
+ $select_link,
+ $select_link,
+ );
+my @link_onclicks = ( $select_onclick,
+ $select_onclick,
+ $select_onclick,
+ $select_onclick,
+ );
+my $align = 'llll';
+
+my @fields = (
+ sub { shift->description =~ /^(.*):.*:.*:.*$/; $1;},
+ sub { shift->description =~ /^.*:(.*):.*:.*$/; $1;},
+ sub { shift->description =~ /^.*:.*:(.*):.*$/; $1;},
+ sub { shift->description =~ /^.*:.*:.*:(.*)$/; $1;},
+);
+
+my $html_init = '';
+
+my $select_link = [ 'javascript:void(0);', sub { ''; } ];
+$html_init = '<TABLE><TR><TD><A HREF="javascript:void(0)" '.
+ qq!onClick="$remove_onclick">(remove)</A>&nbsp;!.
+ 'Current tax product: </TD><TD>'.
+ $selected_part_pkg_taxproduct->description.
+ '</TD></TR></TABLE><BR><BR>'
+ if $selected_part_pkg_taxproduct;
+
+my $type = $cgi->param('_type');
+$html_init .= qq(
+ <FORM>
+ <INPUT NAME="_type" TYPE="hidden" VALUE="$type">
+ <INPUT NAME="taxproductnum" TYPE="hidden" VALUE="$taxproductnum">
+ <INPUT NAME="onclick" TYPE="hidden" VALUE="$onclick">
+ <INPUT NAME="id" TYPE="hidden" VALUE="$id">
+ <TABLE>
+ <TR>
+ <TD><SELECT NAME="tax_group" onChange="this.form.submit()">
+);
+
+my $sql = "SELECT DISTINCT ".
+ qq!substring(description from '#"%#" : % : % : %' for '#'),!.
+ qq!substring(description from '#"%#" : % : % : %' for '#')!.
+ "FROM part_pkg_taxproduct ORDER BY 1";
+
+my $dbh = dbh;
+my $sth = $dbh->prepare($sql) or die $dbh->errstr;
+$sth->execute or die $sth->errstr;
+for (['', '(choose group)'], @{$sth->fetchall_arrayref}) {
+ $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
+ ($_->[0] eq $tax_group ? " SELECTED" : "").
+ '">'. $_->[1];
+}
+
+$html_init .= qq(
+ </SELECT>
+
+ <TD><SELECT NAME="tax_item" onChange="this.form.submit()">
+);
+
+$sql = "SELECT DISTINCT ".
+ qq!substring(description from '% : #"%#" : %: %' for '#'),!.
+ qq!substring(description from '% : #"%#" : %: %' for '#')!.
+ "FROM part_pkg_taxproduct ORDER BY 1";
+
+$sth = $dbh->prepare($sql) or die $dbh->errstr;
+$sth->execute or die $sth->errstr;
+for (@{$sth->fetchall_arrayref}) {
+ $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
+ ($_->[0] eq $tax_item ? " SELECTED" : "").
+ '">'. ($_->[0] ? $_->[1] : '(choose item)');
+}
+
+$html_init .= qq(
+ </SELECT>
+
+ <TD><SELECT NAME="tax_provider" onChange="this.form.submit()">
+);
+
+$sql = "SELECT DISTINCT ".
+ qq!substring(description from '% : % : #"%#" : %' for '#'),!.
+ qq!substring(description from '% : % : #"%#" : %' for '#')!.
+ "FROM part_pkg_taxproduct ORDER BY 1";
+
+$sth = $dbh->prepare($sql) or die $dbh->errstr;
+$sth->execute or die $sth->errstr;
+for (@{$sth->fetchall_arrayref}) {
+ $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
+ ($_->[0] eq $tax_provider ? " SELECTED" : "").
+ '">'. ($_->[0] ? $_->[1] : '(choose provider type)');
+}
+
+$html_init .= qq(
+ </SELECT>
+
+ <TD><SELECT NAME="tax_customer" onChange="this.form.submit()">
+);
+
+$sql = "SELECT DISTINCT ".
+ qq!substring(description from '% : % : % : #"%#"' for '#'),!.
+ qq!substring(description from '% : % : % : #"%#"' for '#')!.
+ "FROM part_pkg_taxproduct ORDER BY 1";
+
+$sth = $dbh->prepare($sql) or die $dbh->errstr;
+$sth->execute or die $sth->errstr;
+for (@{$sth->fetchall_arrayref}) {
+ $html_init .= '<OPTION VALUE="'. $_->[0]. '"'.
+ ($_->[0] eq $tax_customer ? " SELECTED" : "").
+ '">'. ($_->[0] ? $_->[1] : '(choose customer type)');
+}
+
+$html_init .= qq(
+ </SELECT>
+
+ </TR>
+ </TABLE>
+ </FORM>
+
+);
+
+</%init>