summaryrefslogtreecommitdiff
path: root/httemplate
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate')
-rwxr-xr-xhttemplate/edit/cust_main.cgi194
-rw-r--r--httemplate/edit/cust_main/after_bill_location.html12
-rw-r--r--httemplate/edit/cust_main/before_bill_location.html10
-rw-r--r--httemplate/edit/cust_main/birthdate.html1
-rw-r--r--httemplate/edit/cust_main/bottomfixup.js28
-rw-r--r--httemplate/edit/cust_main/company.html7
-rw-r--r--httemplate/edit/cust_main/fax.html5
-rw-r--r--httemplate/edit/cust_main/name.html53
-rw-r--r--httemplate/edit/cust_main/phones.html29
-rw-r--r--httemplate/edit/cust_main/stateid.html39
-rw-r--r--httemplate/edit/cust_main/top_misc.html27
-rw-r--r--httemplate/edit/msg_template.html16
-rw-r--r--httemplate/edit/process/cust_location.cgi6
-rwxr-xr-xhttemplate/edit/process/cust_main.cgi43
-rw-r--r--httemplate/elements/location.html99
-rw-r--r--httemplate/elements/standardize_locations.js5
-rw-r--r--httemplate/elements/tr-select-cust_location.html50
-rwxr-xr-xhttemplate/search/report_tax.cgi98
-rw-r--r--httemplate/view/cust_main/contacts.html146
-rwxr-xr-xhttemplate/view/cust_main/locations.html22
-rw-r--r--httemplate/view/cust_main/misc.html6
21 files changed, 524 insertions, 372 deletions
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
index 0289246..a30c7c1 100755
--- a/httemplate/edit/cust_main.cgi
+++ b/httemplate/edit/cust_main.cgi
@@ -23,6 +23,8 @@
% }
%# agent, agent_custid, refnum (advertising source), referral_custnum
+%# better section title for this?
+<FONT CLASS="fsinnerbox-title"><% mt('Basics') |h %></FONT>
<& cust_main/top_misc.html, $cust_main, 'custnum' => $custnum &>
%# birthdate
@@ -33,113 +35,77 @@
<BR>
<& cust_main/birthdate.html, $cust_main &>
% }
-
-%# contact info
-
-% my $same_checked = '';
-% my $ship_disabled = '';
-% my @ship_style = ();
-% unless ( $cust_main->ship_last && $same ne 'Y' ) {
-% $same_checked = 'CHECKED';
-% $ship_disabled = 'DISABLED';
-% push @ship_style, 'background-color:#dddddd';
-% foreach (
-% qw( last first company address1 address2 city county state zip country
-% latitude longitude coord_auto
-% daytime night fax mobile )
-% ) {
-% $cust_main->set("ship_$_", $cust_main->get($_) );
-% }
-% }
-
+% my $has_ship_address = '';
+% if ( $cgi->param('error') ) {
+% $has_ship_address = !$cgi->param('same');
+% } elsif ( $cust_main->custnum ) {
+% $has_ship_address = $cust_main->has_ship_address;
+% }
<BR>
-<FONT CLASS="fsinnerbox-title"><% mt('Billing address') |h %></FONT>
-
-<& cust_main/contact.html,
- 'cust_main' => $cust_main,
- 'pre' => '',
- 'onchange' => 'bill_changed(this)',
- 'disabled' => '',
- 'ss' => $ss,
- 'stateid' => $stateid,
- 'same_checked' => $same_checked, #for address2 "Unit #" labeling
-&>
+<TABLE> <TR>
+ <TD STYLE="width:650px">
+%#; padding-right:2px; vertical-align:top">
+ <FONT CLASS="fsinnerbox-title"><% mt('Billing address') |h %></FONT>
+ <TABLE CLASS="fsinnerbox">
+ <& cust_main/before_bill_location.html, $cust_main &>
+ <& /elements/location.html,
+ object => $cust_main->bill_location,
+ prefix => 'bill_',
+ &>
+ <& cust_main/after_bill_location.html, $cust_main &>
+ </TABLE>
+ </TD>
+</TR>
+<TR><TD STYLE="height:40px"></TD></TR>
+<TR>
+ <TD STYLE="width:650px">
+%#; padding-left:2px; vertical-align:top">
+ <FONT CLASS="fsinnerbox-title"><% mt('Service address') |h %></FONT>
+ <INPUT TYPE="checkbox"
+ NAME="same"
+ ID="same"
+ onclick="samechanged(this)"
+ onkeyup="samechanged(this)"
+ VALUE="Y"
+ <% $has_ship_address ? '' : 'CHECKED' %>
+ ><% mt('same as billing address') |h %>
+ <TABLE CLASS="fsinnerbox" ID="table_ship_location">
+ <& /elements/location.html,
+ object => $cust_main->ship_location,
+ prefix => 'ship_',
+ enable_censustract => 1,
+ enable_district => 1,
+ &>
+ </TABLE>
+ <TABLE CLASS="fsinnerbox" ID="table_ship_location_blank"
+ STYLE="display:none">
+ <TR><TD></TD></TR>
+ </TABLE>
+ </TD>
+</TR></TABLE>
<SCRIPT>
-function bill_changed(what) {
- if ( what.form.same.checked ) {
-% for (qw( last first company address1 address2 city zip latitude longitude coord_auto daytime night fax mobile )) {
- what.form.ship_<%$_%>.value = what.form.<%$_%>.value;
-% }
-
- what.form.ship_country.selectedIndex = what.form.country.selectedIndex;
-
- function fix_ship_city() {
- what.form.ship_city_select.selectedIndex = what.form.city_select.selectedIndex;
- what.form.ship_city.style.display = what.form.city.style.display;
- what.form.ship_city_select.style.display = what.form.city_select.style.display;
- }
-
- function fix_ship_county() {
- what.form.ship_county.selectedIndex = what.form.county.selectedIndex;
- ship_county_changed(what.form.ship_county, fix_ship_city );
- }
-
- function fix_ship_state() {
- what.form.ship_state.selectedIndex = what.form.state.selectedIndex;
- ship_state_changed(what.form.ship_state, fix_ship_county );
- }
-
- ship_country_changed(what.form.ship_country, fix_ship_state );
-
- }
-}
function samechanged(what) {
+%# not display = 'none', because we still want it to take up space
+%# document.getElementById('table_ship_location').style.visibility =
+%# what.checked ? 'hidden' : 'visible';
+ var t1 = document.getElementById('table_ship_location');
+ var t2 = document.getElementById('table_ship_location_blank');
if ( what.checked ) {
- bill_changed(what);
-
-% my @fields = qw( last first company address1 address2 city city_select county state zip country latitude longitude daytime night fax mobile );
-% for (@fields) {
- what.form.ship_<%$_%>.disabled = true;
- what.form.ship_<%$_%>.style.backgroundColor = '#dddddd';
-% }
-
-% if ( $conf->exists('cust_main-require_address2') ) {
- document.getElementById('address2_required').style.visibility = '';
- document.getElementById('address2_label').style.visibility = '';
- document.getElementById('ship_address2_required').style.visibility = 'hidden';
- document.getElementById('ship_address2_label').style.visibility = 'hidden';
-% }
-
- } else {
-
-% for (@fields) {
- what.form.ship_<%$_%>.disabled = false;
- what.form.ship_<%$_%>.style.backgroundColor = '#ffffff';
-% }
-
-% if ( $conf->exists('cust_main-require_address2') ) {
- document.getElementById('address2_required').style.visibility = 'hidden';
- document.getElementById('address2_label').style.visibility = 'hidden';
- document.getElementById('ship_address2_required').style.visibility = '';
- document.getElementById('ship_address2_label').style.visibility = '';
-% }
-
+ t2.style.width = t1.clientWidth + 'px';
+ t2.style.height = t1.clientHeight + 'px';
+ t1.style.display = 'none';
+ t2.style.display = '';
+ }
+ else {
+ t2.style.display = 'none';
+ t1.style.display = '';
}
}
+samechanged(document.getElementById('same'));
</SCRIPT>
<BR>
-<FONT CLASS="fsinnerbox-title"><% mt('Service address') |h %></FONT>
-
-<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)" <%$same_checked%>><% mt('same as billing address') |h %>
-<& cust_main/contact.html,
- 'cust_main' => $cust_main,
- 'pre' => 'ship_',
- 'onchange' => '',
- 'disabled' => $ship_disabled,
- 'style' => \@ship_style
-&>
<& cust_main/contacts_new.html,
'cust_main' => $cust_main,
@@ -242,10 +208,28 @@ my $locationnum = '';
if ( $cgi->param('error') ) {
+ # false laziness w/ edit/process/cust_main.cgi
+ my %locations;
+ for my $pre (qw(bill ship)) {
+ my %hash;
+ foreach ( FS::cust_main->location_fields ) {
+ $hash{$_} = scalar($cgi->param($pre.'_'.$_));
+ }
+ $hash{'custnum'} = $cgi->param('custnum');
+ $locations{$pre} = qsearchs('cust_location', \%hash)
+ || FS::cust_location->new( \%hash );
+ }
+
$cust_main = new FS::cust_main ( {
- map { $_, scalar($cgi->param($_)) } fields('cust_main')
+ map { ( $_, scalar($cgi->param($_)) ) } (fields('cust_main')),
+ map { ( "ship_$_", '' ) } (FS::cust_main->location_fields)
} );
+ for my $pre (qw(bill ship)) {
+ $cust_main->set($pre.'_location', $locations{$pre});
+ $cust_main->set($pre.'_locationnum', $locations{$pre}->locationnum);
+ }
+
$custnum = $cust_main->custnum;
die "access denied"
@@ -355,6 +339,20 @@ if ( $cgi->param('error') ) {
$svc_dsl{$_} = $qual->$_
foreach qw( phonenum vendor_qual_id );
}
+ else {
+ my $countrydefault = $conf->config('countrydefault') || 'US';
+ my $statedefault = $conf->config('statedefault') || 'CA';
+ $cust_main->set('bill_location',
+ FS::cust_location->new(
+ { country => $countrydefault, state => $statedefault }
+ )
+ );
+ $cust_main->set('ship_location',
+ FS::cust_location->new(
+ { country => $countrydefault, state => $statedefault }
+ )
+ );
+ }
if ( $cgi->param('lock_pkgpart') =~ /^(\d+)$/ ) {
my $pkgpart = $1;
diff --git a/httemplate/edit/cust_main/after_bill_location.html b/httemplate/edit/cust_main/after_bill_location.html
new file mode 100644
index 0000000..2f4c3b5
--- /dev/null
+++ b/httemplate/edit/cust_main/after_bill_location.html
@@ -0,0 +1,12 @@
+% if ( ! $conf->exists('cust-edit-alt-field-order') ) {
+ <& phones.html, $cust_main &>
+ <& fax.html, $cust_main &>
+% } else {
+ <& fax.html, $cust_main &>
+ <& company.html, $cust_main &>
+% }
+<& stateid.html, $cust_main &>
+<%init>
+my $cust_main = shift;
+my $conf = FS::Conf->new;
+</%init>
diff --git a/httemplate/edit/cust_main/before_bill_location.html b/httemplate/edit/cust_main/before_bill_location.html
new file mode 100644
index 0000000..973201e
--- /dev/null
+++ b/httemplate/edit/cust_main/before_bill_location.html
@@ -0,0 +1,10 @@
+<& name.html, $cust_main &>
+% if ( ! $conf->exists('cust-edit-alt-field-order') ) {
+ <& company.html, $cust_main &>
+% } else {
+ <& phones.html, $cust_main &>
+% }
+<%init>
+my $cust_main = shift;
+my $conf = FS::Conf->new;
+</%init>
diff --git a/httemplate/edit/cust_main/birthdate.html b/httemplate/edit/cust_main/birthdate.html
index 6d1c221..5d6a123 100644
--- a/httemplate/edit/cust_main/birthdate.html
+++ b/httemplate/edit/cust_main/birthdate.html
@@ -1,4 +1,5 @@
<% ntable("#cccccc", 2) %>
+% # maybe put after the contact names?
% if ( $conf->exists('cust_main-enable_birthdate') ) {
<% include( '/elements/tr-input-date-field.html', {
'name' => 'birthdate',
diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js
index 800864b..77d4294 100644
--- a/httemplate/edit/cust_main/bottomfixup.js
+++ b/httemplate/edit/cust_main/bottomfixup.js
@@ -66,21 +66,25 @@ function copy_payby_fields() {
%# call submit_continue() on completion...
%# otherwise not touching standardize_locations for now
<% include( '/elements/standardize_locations.js',
- 'callback' => 'submit_continue();'
+ 'callback' => 'submit_continue();',
+ 'main_prefix' => 'bill_',
+ 'no_company' => 1,
)
%>
+var prefix;
function fetch_censustract() {
//alert('fetch census tract data');
+ prefix = document.getElementById('same').checked ? 'bill_' : 'ship_';
var cf = document.CustomerForm;
- var state_el = cf.elements['ship_state'];
+ var state_el = cf.elements[prefix + 'state'];
var census_data = new Array(
'year', <% $conf->config('census_year') || '2012' %>,
- 'address1', cf.elements['ship_address1'].value,
- 'city', cf.elements['ship_city'].value,
+ 'address1', cf.elements[prefix + 'address1'].value,
+ 'city', cf.elements[prefix + 'city'].value,
'state', state_el.options[ state_el.selectedIndex ].value,
- 'zip', cf.elements['ship_zip'].value
+ 'zip', cf.elements[prefix + 'zip'].value
);
censustract( census_data, update_censustract );
@@ -109,19 +113,21 @@ function update_censustract(arg) {
set_censustract = function () {
- cf.elements['censustract'].value = newcensus;
+ cf.elements[prefix + 'censustract'].value = newcensus;
submit_continue();
}
- if (error || cf.elements['censustract'].value != newcensus) {
+ if (error || cf.elements[prefix + 'censustract'].value != newcensus) {
// popup an entry dialog
if (error) { newcensus = error; }
newcensus.replace(/.*ndefined.*/, 'Not found');
- var latitude = cf.elements['latitude' ].value || '<% $company_latitude %>';
- var longitude= cf.elements['longitude'].value || '<% $company_longitude %>';
+ var latitude = cf.elements[prefix + 'latitude'].value
+ || '<% $company_latitude %>';
+ var longitude= cf.elements[prefix + 'longitude'].value
+ || '<% $company_longitude %>';
var choose_censustract =
'<CENTER><BR><B>Confirm censustract</B><BR>' +
@@ -132,14 +138,14 @@ function update_censustract(arg) {
'" target="_blank">Map service module location</A><BR>' +
'<A href="http://maps.ffiec.gov/FFIECMapper/TGMapSrv.aspx?' +
'census_year=<% $conf->config('census_year') || '2012' %>' +
- '&zip_code=' + cf.elements['ship_zip'].value +
+ '&zip_code=' + cf.elements[prefix + 'zip'].value +
'" target="_blank">Map zip code center</A><BR><BR>' +
'<TABLE>';
choose_censustract = choose_censustract +
'<TR><TH style="width:50%">Entered census tract</TH>' +
'<TH style="width:50%">Calculated census tract</TH></TR>' +
- '<TR><TD>' + cf.elements['censustract'].value +
+ '<TR><TD>' + cf.elements[prefix + 'censustract'].value +
'</TD><TD>' + newcensus + '</TD></TR>' +
'<TR><TD>&nbsp;</TD><TD>&nbsp;</TD></TR>';
diff --git a/httemplate/edit/cust_main/company.html b/httemplate/edit/cust_main/company.html
new file mode 100644
index 0000000..8a6ed0b
--- /dev/null
+++ b/httemplate/edit/cust_main/company.html
@@ -0,0 +1,7 @@
+% my $cust_main = shift;
+<TR ID="company_row" <% $cust_main->company ? '' : 'STYLE="display:none"' %>>
+ <TD ALIGN="right"><% mt('Company') |h %></TD>
+ <TD COLSPAN=6><INPUT TYPE="text" NAME="company" ID="company" SIZE=60
+ VALUE="<% $cust_main->company |h %>">
+ </TD>
+</TR>
diff --git a/httemplate/edit/cust_main/fax.html b/httemplate/edit/cust_main/fax.html
new file mode 100644
index 0000000..237d4be
--- /dev/null
+++ b/httemplate/edit/cust_main/fax.html
@@ -0,0 +1,5 @@
+% my $cust_main = shift;
+<TR>
+ <TD ALIGN="right"><% mt('Fax') |h %></TD>
+ <TD><INPUT TYPE="text" NAME="fax" VALUE="<% $cust_main->fax %>" SIZE=18></TD>
+</TR>
diff --git a/httemplate/edit/cust_main/name.html b/httemplate/edit/cust_main/name.html
new file mode 100644
index 0000000..2641ec9
--- /dev/null
+++ b/httemplate/edit/cust_main/name.html
@@ -0,0 +1,53 @@
+<%def .namepart>
+% my ($field, $value, $label, $extra) = @_;
+<TD>
+ <INPUT TYPE="text" NAME="<% $field %>" VALUE="<% $value |h %>" <%$extra%>>
+ <BR><FONT SIZE=-1><% mt($label) %></FONT>
+</TD>
+</%def>
+
+<TR>
+ <TH VALIGN="top" ALIGN="right"><%$r%><% mt('Contact name') |h %></TH>
+ <TD COLSPAN=6>
+ <TABLE CELLSPACING=0 CELLPADDING=0>
+ <TR>
+ <& .namepart, 'last', $cust_main->last, 'Last' &>
+ <TD VALIGN="top"> , </TD>
+ <& .namepart, 'first', $cust_main->first, 'First' &>
+% if ( $conf->exists('show_ss') ) {
+ <TD>&nbsp;</TD>
+ <& .namepart, 'ss', $ss, 'SS#', "SIZE=11" &>
+% } else {
+ <INPUT TYPE="hidden" NAME="ss" VALUE="<% $ss %>">
+% }
+ </TR>
+ </TABLE>
+ </TD>
+</TR>
+
+% if ( $conf->exists('cust-email-high-visibility') ) {
+<TR>
+ <TD ALIGN="right">
+ <% $conf->exists('cust_main-require_invoicing_list_email', $agentnum)
+ ? $r
+ : '' %>Email address(es)
+ </TD>
+ <TD BGCOLOR="#FFFF00">
+ <INPUT TYPE="text" NAME="invoicing_list"
+ VALUE=<% $cust_main->invoicing_list_emailonly_scalar %>>
+ </TD>
+</TR>
+% }
+<%init>
+my $cust_main = shift;
+my $agentnum = $cust_main->agentnum if $cust_main->custnum;
+my $conf = FS::Conf->new;
+my $r = '<font color="#ff0000">*</font>&nbsp;';
+my $ss;
+
+if ( $cgi->param('error') or $conf->exists('unmask_ss') ) {
+ $ss = $cust_main->ss;
+} else {
+ $ss = $cust_main->masked('ss');
+}
+</%init>
diff --git a/httemplate/edit/cust_main/phones.html b/httemplate/edit/cust_main/phones.html
new file mode 100644
index 0000000..9b23e07
--- /dev/null
+++ b/httemplate/edit/cust_main/phones.html
@@ -0,0 +1,29 @@
+<TR>
+ <TD VALIGN="top" ALIGN="right"><% mt('Phones') |h %></TD>
+ <TD COLSPAN=6>
+ <TABLE CELLSPACING=0 CELLPADDING=0>
+ <TR>
+% foreach my $phone (qw(daytime night mobile)) {
+ <TD>
+ <INPUT TYPE="text"
+ NAME="<% $phone %>"
+ VALUE="<% $cust_main->get($phone) %>"
+ SIZE=18
+ >
+ <BR><FONT SIZE=-1><% mt($phone_label{$phone}) |h %></FONT>
+ </TD>
+ <TD>&nbsp;</TD>
+% }
+ </TR>
+ </TABLE>
+ </TD>
+</TR>
+<%init>
+my $cust_main = shift;
+my $conf = FS::Conf->new;
+my %phone_label = (
+ daytime => 'Day Phone',
+ night => 'Night Phone',
+ mobile => 'Mobile',
+);
+</%init>
diff --git a/httemplate/edit/cust_main/stateid.html b/httemplate/edit/cust_main/stateid.html
new file mode 100644
index 0000000..2655f51
--- /dev/null
+++ b/httemplate/edit/cust_main/stateid.html
@@ -0,0 +1,39 @@
+% if ( $conf->exists('show_stateid') ) {
+<TR>
+ <TD ALIGN="right"><% $stateid_label %></TD>
+ <TD><INPUT TYPE="text" NAME="stateid" VALUE="<% $stateid %>" SIZE=12></TD>
+ <TD><& /elements/select-state.html,
+ state => $cust_main->stateid_state,
+ country => $cust_main->country, # how does this work on new customer?
+ prefix => 'stateid_',
+ disable_countyupdate => 1,
+ &></TD>
+</TR>
+% } else {
+<INPUT TYPE="hidden" NAME="stateid" VALUE="<% $stateid %>">
+<INPUT TYPE="hidden" NAME="stateid_state" VALUE="<% $cust_main->stateid_state %>">
+% }
+
+<%init>
+my $cust_main = shift;
+my $conf = FS::Conf->new;
+my $stateid;
+if ( $cgi->param('error') ) {
+ $stateid = $cust_main->stateid;
+} elsif ( $cust_main->custnum ) {
+ $stateid = $cust_main->masked('stateid');
+} else {
+ $stateid = '';
+}
+$cust_main->set('stateid_state' => $cust_main->state)
+ unless $cust_main->stateid_state;
+
+my $stateid_label = FS::Msgcat::_gettext('stateid') =~ /^(stateid)?$/
+ ? 'Driver&rsquo;s License'
+ : FS::Msgcat::_gettext('stateid') || 'Driver&rsquo;s License';
+
+my $stateid_state_label =
+ FS::Msgcat::_gettext('stateid_state') =~ /^(stateid_state)?$/
+ ? 'Driver&rsquo;s License State'
+ : FS::Msgcat::_gettext('stateid') || 'Driver&rsquo;s License State';
+</%init>
diff --git a/httemplate/edit/cust_main/top_misc.html b/httemplate/edit/cust_main/top_misc.html
index 7ba167b..7ce283c 100644
--- a/httemplate/edit/cust_main/top_misc.html
+++ b/httemplate/edit/cust_main/top_misc.html
@@ -20,27 +20,16 @@
<% $cust_main->residential_commercial eq 'Commercial' ? 'CHECKED' : '' %>
></TD>
</TR>
-
<SCRIPT TYPE="text/javascript">
- function rescom_changed() {
- var f = document.CustomerForm;
-
- if ( f.residential_commercial_Residential.checked ) {
- document.getElementById('contacts_div').style.display = 'none';
- } else { // if ( f.residential_commercial_Commercial.checked ) {
- document.getElementById('contacts_div').style.display = '';
- }
-
- if ( f.residential_commercial_Residential.checked && ! f.company.value.length ) {
- document.getElementById('company_row').style.display = 'none'
- } else { // if ( f.residential_commercial_Commercial.checked ) {
+ function rescom_changed(what) {
+ if ( what.checked == (what.value == 'Commercial' ) ) {
document.getElementById('company_row').style.display = '';
- }
-
- if ( f.residential_commercial_Residential.checked && ! f.ship_company.value.length ) {
- document.getElementById('ship_company_row').style.display = 'none'
- } else { // if ( f.residential_commercial_Commercial.checked ) {
- document.getElementById('ship_company_row').style.display = '';
+ document.getElementById('contacts_div').style.display = '';
+ } else {
+ if ( document.getElementById('company').value.length == 0 ) {
+ document.getElementById('company_row').style.display = 'none';
+ }
+ document.getElementById('contacts_div').style.display = 'none';
}
}
</SCRIPT>
diff --git a/httemplate/edit/msg_template.html b/httemplate/edit/msg_template.html
index f50d66d..115032a 100644
--- a/httemplate/edit/msg_template.html
+++ b/httemplate/edit/msg_template.html
@@ -227,6 +227,15 @@ my %substitutions = (
'$mobile' => 'Mobile phone',
'$fax' => 'Fax',
],
+ 'service' => [
+ '$ship_address1' => 'Address line 1',
+ '$ship_address2' => 'Address line 2',
+ '$ship_city' => 'City',
+ '$ship_county' => 'County',
+ '$ship_state' => 'State',
+ '$ship_zip' => 'Zip',
+ '$ship_country' => 'Country',
+ ],
'cust_bill' => [
'$invnum' => 'Invoice#',
],
@@ -281,15 +290,10 @@ my %substitutions = (
'$error' => 'Decline reason',
],
);
-my @c = @{ $substitutions{'contact'} };
-for (my $i=0; $i<scalar(@c); $i += 2) {
- $c[$i] =~ s/\$(.*)/\$ship_$1/;
-}
-$substitutions{'shipping'} = \@c;
tie my %sections, 'Tie::IxHash', (
'contact' => 'Name and contact info (billing)',
-'shipping' => 'Name and contact info (shipping)',
+'service' => 'Service address',
'cust_main' => 'Customer status and payment info',
'cust_pkg' => 'Package fields',
'cust_bill' => 'Invoice fields',
diff --git a/httemplate/edit/process/cust_location.cgi b/httemplate/edit/process/cust_location.cgi
index 790fc8e..b9f93db 100644
--- a/httemplate/edit/process/cust_location.cgi
+++ b/httemplate/edit/process/cust_location.cgi
@@ -28,10 +28,12 @@ my $cust_location = qsearchs({
});
die "unknown locationnum $locationnum" unless $cust_location;
-my $new = {
+my $new = FS::cust_location->new({
+ custnum => $cust_location->custnum,
+ prospectnum => $cust_location->prospectnum,
map { $_ => scalar($cgi->param($_)) }
qw( address1 address2 city county state zip country )
-};
+});
my $error = $cust_location->move_to($new);
diff --git a/httemplate/edit/process/cust_main.cgi b/httemplate/edit/process/cust_main.cgi
index 3f5e19e..5ee553b 100755
--- a/httemplate/edit/process/cust_main.cgi
+++ b/httemplate/edit/process/cust_main.cgi
@@ -57,19 +57,40 @@ push @invoicing_list, 'POST' if $cgi->param('invoicing_list_POST');
push @invoicing_list, 'FAX' if $cgi->param('invoicing_list_FAX');
$cgi->param('invoicing_list', join(',', @invoicing_list) );
+# is this actually used? if so, we need to clone locations...
+# but I can't find anything that sets this parameter to a non-empty value
+$cgi->param('duplicate_of_custnum') =~ /^(\d+)$/;
+my $duplicate_of = $1;
+
+my %locations;
+for my $pre (qw(bill ship)) {
+
+ my %hash;
+ foreach ( FS::cust_main->location_fields ) {
+ $hash{$_} = scalar($cgi->param($pre.'_'.$_));
+ }
+ $hash{'custnum'} = $cgi->param('custnum');
+ warn Dumper \%hash if $DEBUG;
+ # if we can qsearchs it, then it's unchanged, so use that
+ $locations{$pre} = qsearchs('cust_location', \%hash)
+ || FS::cust_location->new( \%hash );
+
+}
+
+if ( ($cgi->param('same') || '') eq 'Y' ) {
+ $locations{ship} = $locations{bill};
+}
#create new record object
+# but explicitly avoid setting ship_ fields
my $new = new FS::cust_main ( {
- map {
- $_, scalar($cgi->param($_))
- } fields('cust_main')
+ map { ( $_, scalar($cgi->param($_)) ) } (fields('cust_main')),
+ map { ( "ship_$_", '' ) } (FS::cust_main->location_fields)
} );
$new->invoice_noemail( ($cgi->param('invoice_email') eq 'Y') ? '' : 'Y' );
-$cgi->param('duplicate_of_custnum') =~ /^(\d+)$/;
-my $duplicate_of = $1;
if ( $duplicate_of ) {
# then negate all changes to the customer; the only change we should
# make is to order a package, if requested
@@ -78,11 +99,9 @@ if ( $duplicate_of ) {
or die "nonexistent existing customer (custnum $duplicate_of)";
}
-if ( defined($cgi->param('same')) && $cgi->param('same') eq "Y" ) {
- $new->setfield("ship_$_", '') foreach qw(
- last first company address1 address2 city county state zip
- country daytime night fax
- );
+for my $pre (qw(bill ship)) {
+ $new->set($pre.'_location', $locations{$pre});
+ $new->set($pre.'_locationnum', $locations{$pre}->locationnum);
}
if ( $cgi->param('no_credit_limit') ) {
@@ -261,6 +280,7 @@ if ( $new->custnum eq '' or $duplicate_of ) {
my $old = qsearchs( 'cust_main', { 'custnum' => $new->custnum } );
$error ||= "Old record not found!" unless $old;
+
if ( length($old->paycvv) && $new->paycvv =~ /^\s*\*+\s*$/ ) {
$new->paycvv($old->paycvv);
}
@@ -299,6 +319,9 @@ if ( $new->custnum eq '' or $duplicate_of ) {
local($FS::cust_main::DEBUG) = $DEBUG if $DEBUG;
local($FS::Record::DEBUG) = $DEBUG if $DEBUG;
+ local($Data::Dumper::Sortkeys) = 1;
+ warn Dumper({ new => $new, old => $old }) if $DEBUG;
+
$error ||= $new->replace( $old, \@invoicing_list,
'tax_exemption' => \%tax_exempt,
);
diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html
index c606523..7672318 100644
--- a/httemplate/elements/location.html
+++ b/httemplate/elements/location.html
@@ -3,16 +3,16 @@
Example:
include( '/elements/location.html',
- 'object' => $cust_main, # or $cust_location
- 'prefix' => $pre, #only for cust_main objects
+ 'object' => $cust_location
+ 'prefix' => $pre, # prefixed to form field names
'onchange' => $javascript,
- 'disabled' => $disabled,
- 'same_checked' => $same_checked,
'geocode' => $geocode, #passed through
'censustract' => $censustract, #passed through
'no_asterisks' => 0, #set true to disable the red asterisks next
#to required fields
'address1_label' => 'Address', #label for address
+ 'enable_district' => 1, #show tax district field
+ 'enable_censustract' => 1, #show censustract field
)
</%doc>
@@ -40,12 +40,12 @@ Example:
% }
<TR>
- <<%$th%> ALIGN="right"><%$r%><% $opt{'address1_label'} || emt('Address') %></<%$th%>>
+ <<%$th%> STYLE="width:16ex" ALIGN="right"><%$r%><% $opt{'address1_label'} || emt('Address') %></<%$th%>>
<TD COLSPAN=7>
<INPUT TYPE = "text"
NAME = "<%$pre%>address1"
ID = "<%$pre%>address1"
- VALUE = "<% $object->get($pre.'address1') |h %>"
+ VALUE = "<% $object->get('address1') |h %>"
SIZE = 54
onChange = "<% $onchange %>"
<% $disabled %>
@@ -62,7 +62,7 @@ Example:
<INPUT TYPE = "text"
NAME = "<%$pre%>address2"
ID = "<%$pre%>address2"
- VALUE = "<% $object->get($pre.'address2') |h %>"
+ VALUE = "<% $object->get('address2') |h %>"
SIZE = 54
onChange = "<% $onchange %>"
<% $disabled %>
@@ -75,7 +75,7 @@ Example:
<INPUT TYPE = "hidden"
NAME = "<%$pre%>address2"
- VALUE = "<% $object->get($pre.'address2') |h %>"
+ VALUE = "<% $object->get('address2') |h %>"
>
<TR>
@@ -83,7 +83,7 @@ Example:
<TD COLSPAN=7>
% my $location_type = scalar($cgi->param('location_type'))
-% || $object->get($pre.'location_type');
+% || $object->get('location_type');
% #my $location_number = scalar($cgi->param('location_number'))
% # || $object->get($pre.'location_number');
%
@@ -130,7 +130,7 @@ Example:
<INPUT TYPE="text"
NAME = "location_number"
ID = "location_number"
- VALUE = "<% scalar($cgi->param('location_number')) || $object->get($pre.'location_number') |h %>"
+ VALUE = "<% scalar($cgi->param('location_number')) || $object->get('location_number') |h %>"
SIZE = "5"
<% $disabled || ($location_type ? '' : 'DISABLED') %>
<% $style %>
@@ -161,7 +161,7 @@ Example:
<INPUT TYPE = "text"
NAME = "<%$pre%>zip"
ID = "<%$pre%>zip"
- VALUE = "<% $object->get($pre.'zip') |h %>"
+ VALUE = "<% $object->get('zip') |h %>"
SIZE = 10
onChange = "<% $onchange %>"
<% $disabled %>
@@ -181,7 +181,7 @@ Example:
<INPUT TYPE = "text"
NAME = "<%$pre%>latitude"
ID = "<%$pre%>latitude"
- VALUE = "<% $object->get($pre.'latitude') |h %>"
+ VALUE = "<% $object->get('latitude') |h %>"
<% $disabled %>
<% $style %>
>
@@ -189,36 +189,44 @@ Example:
<INPUT TYPE = "text"
NAME = "<%$pre%>longitude"
ID = "<%$pre%>longitude"
- VALUE = "<% $object->get($pre.'longitude') |h %>"
+ VALUE = "<% $object->get('longitude') |h %>"
<% $disabled %>
<% $style %>
>
</TD>
</TR>
-<INPUT TYPE="hidden" NAME="<%$pre%>coord_auto" VALUE="<% $object->get($pre.'coord_auto') %>">
+<INPUT TYPE="hidden" NAME="<%$pre%>coord_auto" VALUE="<% $object->coord_auto %>">
-% if ( !$pre ) {
- <INPUT TYPE="hidden" NAME="geocode" VALUE="<% $opt{geocode} %>">
+<INPUT TYPE="hidden" NAME="<%$pre%>geocode" VALUE="<% $object->geocode %>">
+<INPUT TYPE="hidden" NAME="<%$pre%>censusyear" VALUE="<% $object->censusyear %>">
+<TR>
+% if ( $opt{enable_censustract} ) {
+ <TD ALIGN="right">Census&nbsp;tract</TD>
+ <TD COLSPAN=8>
+ <INPUT TYPE="text" SIZE=15
+ NAME="<%$pre%>censustract"
+ VALUE="<% $object->censustract %>">
+ <% '(automatic)' %>
+ </TD>
% } else {
-% if ( $pre eq 'ship_' && $conf->exists('cust_main-require_censustract') ) {
- <TR><<%$th%> ALIGN="right">Census tract<BR>(automatic)</<%$th%>>
- <TD>
- <INPUT TYPE="text" NAME="censustract" VALUE="<% $opt{censustract} %>">
- <INPUT TYPE="hidden" NAME="censusyear" VALUE="<% $object->get('censusyear') %>">
- </TD>
- </TR>
+ <INPUT TYPE="hidden" NAME="<%$pre%>censustract" VALUE="<% $object->censustract %>">
+% }
+</TR>
+% if ( $conf->config('tax_district_method') ) {
+ <TR>
+% if ( $opt{enable_district} ) {
+ <TD ALIGN="right">Tax&nbsp;district</TD>
+ <TD COLSPAN=8>
+ <INPUT TYPE="text" SIZE=15
+ NAME="<%$pre%>district"
+ VALUE="<% $object->district %>">
+ <% '(automatic)' %>
+ </TD>
% } else {
- <INPUT TYPE="hidden" NAME="censustract" VALUE="<% $opt{censustract} %>">
-% }
-% if ( $conf->config('tax_district_method') or $object->get('district') ) {
- <TR>
- <<%$th%> ALIGN="right">Tax district<BR>(automatic)</<%$th%>>
- <TD>
- <INPUT TYPE="text" NAME="district" VALUE="<%$object->get('district')%>">
- </TD>
- </TR>
+ <INPUT TYPE="hidden" NAME="<%$pre%>district" VALUE="<% $object->district %>">
% }
-% }
+ </TR>
+% }
<%init>
@@ -233,16 +241,13 @@ my $conf = new FS::Conf;
my $r = $opt{'no_asterisks'} ? '' : qq!<font color="#ff0000">*</font>&nbsp;!;
-#false laziness with ship state
my $countrydefault = $conf->config('countrydefault') || 'US';
-$object->set($pre.'country', $countrydefault )
- unless $object->get($pre.'country');
-
-my $statedefault = $conf->config('statedefault')
+my $statedefault = $conf->config('statedefault')
|| ($countrydefault eq 'US' ? 'CA' : '');
-$object->set($pre.'state', $statedefault )
- unless $object->get($pre.'state')
- || $object->get($pre.'country') ne $countrydefault;
+$object ||= FS::cust_location->new({
+ 'country' => $countrydefault,
+ 'state' => $statedefault,
+});
my $alt_err = ($opt{'alt_format'} && !$disabled) ? $object->alternize : '';
@@ -255,8 +260,8 @@ push @address2_label_style, 'visibility:hidden'
|| ! $conf->exists('cust_main-require_address2')
|| ( !$pre && !$opt{'same_checked'} );
-my @counties = counties( $object->get($pre.'state'),
- $object->get($pre.'country'),
+my @counties = counties( $object->get('state'),
+ $object->get('country'),
);
my @county_style = ();
push @county_style, 'display:none' # 'visibility:hidden'
@@ -276,10 +281,10 @@ my $county_style =
: '';
my %select_hash = (
- 'city' => $object->get($pre.'city'),
- 'county' => $object->get($pre.'county'),
- 'state' => $object->get($pre.'state'),
- 'country' => $object->get($pre.'country'),
+ 'city' => $object->get('city'),
+ 'county' => $object->get('county'),
+ 'state' => $object->get('state'),
+ 'country' => $object->get('country'),
'prefix' => $pre,
'onchange' => $onchange,
'disabled' => $disabled,
diff --git a/httemplate/elements/standardize_locations.js b/httemplate/elements/standardize_locations.js
index e6a4aa6..86f8d2b 100644
--- a/httemplate/elements/standardize_locations.js
+++ b/httemplate/elements/standardize_locations.js
@@ -10,7 +10,7 @@ function standardize_locations() {
'onlyship', 1,
% } else {
% if ( $withfirm ) {
- 'company', cf.elements['<% $main_prefix %>company'].value,
+ 'company', cf.elements['company'].value,
% }
'address1', cf.elements['<% $main_prefix %>address1'].value,
'address2', cf.elements['<% $main_prefix %>address2'].value,
@@ -18,9 +18,6 @@ function standardize_locations() {
'state', state_el.options[ state_el.selectedIndex ].value,
'zip', cf.elements['<% $main_prefix %>zip'].value,
% }
-% if ( $withfirm ) {
- 'ship_company', cf.elements['<% $ship_prefix %>company'].value,
-% }
'ship_address1', cf.elements['<% $ship_prefix %>address1'].value,
'ship_address2', cf.elements['<% $ship_prefix %>address2'].value,
'ship_city', cf.elements['<% $ship_prefix %>city'].value,
diff --git a/httemplate/elements/tr-select-cust_location.html b/httemplate/elements/tr-select-cust_location.html
index 0ca255b..05712ee 100644
--- a/httemplate/elements/tr-select-cust_location.html
+++ b/httemplate/elements/tr-select-cust_location.html
@@ -11,7 +11,6 @@ Example:
#optional
'empty_label' => '(default service address)',
- 'disable_empty' => 0, #1 to disable
)
</%doc>
@@ -52,11 +51,12 @@ Example:
var ftype = what.form.<%$_%>.tagName;
if( ftype != 'SELECT') what.form.<%$_%>.style.backgroundColor = '#ffffff';
% }
-
+% if ( $opt{'alt_format'} ) {
if ( what.form.location_type.options[what.form.location_type.selectedIndex].value ) {
what.form.location_number.disabled = false;
what.form.location_number.style.backgroundColor = '#ffffff';
}
+% }
}
function locationnum_changed(what) {
@@ -101,25 +101,8 @@ Example:
return;
}
- if ( locationnum == 0 ) { //(default service address)
-% if ( $cust_main ) {
- what.form.address1.value = <% $cust_main->get($prefix.'address1') |js_string %>;
- what.form.address2.value = <% $cust_main->get($prefix.'address2') |js_string %>;
- what.form.city.value = <% $cust_main->get($prefix.'city') |js_string %>;
- what.form.zip.value = <% $cust_main->get($prefix.'zip') |js_string %>;
-
- changeSelect(what.form.country, <% $cust_main->get($prefix.'country') | js_string %> );
-
- country_changed( what.form.country,
- fix_state_factory( <% $cust_main->get($prefix.'state') | js_string %>,
- <% $cust_main->get($prefix.'county') | js_string %>
- )
- );
-% }
-
- } else {
- get_location( locationnum, update_location );
- }
+%# default service address is now just another location
+ get_location( locationnum, update_location );
% if ( $editable ) {
if ( locationnum == 0 ) {
@@ -203,14 +186,16 @@ Example:
ID = "locationnum"
onChange = "locationnum_changed(this);"
>
-% if ( !$prospect_main && !$opt{'disable_empty'} ) {
- <OPTION VALUE=""><% $opt{'empty_label'} || '(default service address)' |h %>
+% if ( $cust_main ) {
+ <OPTION VALUE="<% $cust_main->ship_locationnum %>"><% $opt{'empty_label'} || '(default service address)' |h %>
% }
% if ( $opt{'is_optional'} ) {
<OPTION VALUE="-2" <% $locationnum == -2 ? 'SELECTED' : ''%>><% $opt{'optional_label'} || '(not required)' |h %>
% }
%
% foreach my $loc ( @cust_location ) {
+% # don't show the ship_location redundantly
+% next if $cust_main && $cust_main->ship_locationnum == $loc->locationnum;
<OPTION VALUE="<% $loc->locationnum %>"
<% $locationnum == $loc->locationnum ? 'SELECTED' : '' %>
><% $loc->line |h %>
@@ -233,7 +218,9 @@ Example:
'alt_format' => $opt{'alt_format'},
)
%>
-
+<SCRIPT TYPE="text/javascript">
+ locationnum_changed(document.getElementById('locationnum'));
+</SCRIPT>
<%init>
my $conf = new FS::Conf;
@@ -246,8 +233,7 @@ my $cgi = $opt{'cgi'};
my $cust_pkg = $opt{'cust_pkg'};
my $cust_main = $opt{'cust_main'};
my $prospect_main = $opt{'prospect_main'};
-
-my $prefix = ($cust_main && length($cust_main->ship_last)) ? 'ship_' : '';
+die "cust_main or prospect_main required" unless $cust_main or $prospect_main;
my $locationnum = '';
if ( $cgi->param('error') ) {
@@ -259,9 +245,9 @@ if ( $cgi->param('error') ) {
} elsif ($prospect_main) {
my @cust_location = $prospect_main->cust_location;
$locationnum = $cust_location[0]->locationnum if scalar(@cust_location)==1;
- } else { #?
+ } else { #$cust_main
$cgi->param('locationnum') =~ /^(\-?\d*)$/ or die "illegal locationnum";
- $locationnum = $1;
+ $locationnum = $1 || $cust_main->ship_locationnum;
}
}
@@ -277,7 +263,7 @@ if ( $opt{'alt_format'} ) {
push @location_fields, qw( location_type location_number location_kind );
}
-my $cust_location;
+my $cust_location; #the one that shows by default in the location edit space
if ( $locationnum && $locationnum > 0 ) {
$cust_location = qsearchs('cust_location', { 'locationnum' => $locationnum } )
or die "unknown locationnum";
@@ -290,7 +276,7 @@ if ( $locationnum && $locationnum > 0 ) {
$cust_location->$_( $pkg_location->$_ ) foreach @location_fields;
$opt{'empty_label'} ||= 'package address: '.$pkg_location->line;
} elsif ( $cust_main ) {
- $cust_location->$_( $cust_main->get($prefix.$_) ) foreach @location_fields;
+ $cust_location = $cust_main->ship_location; #I think
}
}
@@ -311,14 +297,14 @@ push @cust_location, $cust_location
@cust_location = sort $location_sort grep !$_->disabled, @cust_location;
$cust_location = $cust_location[0]
- if ( $prospect_main || $opt{'disable_empty'} )
+ if ( $prospect_main )
&& !$opt{'is_optional'}
&& @cust_location;
my $disabled =
( $locationnum < 0
|| ( $editable && $locationnum )
- || ( ( $prospect_main || $opt{'disable_empty'} )
+ || ( $prospect_main
&& !$opt{'is_optional'} && !@cust_location && $addnew
)
)
diff --git a/httemplate/search/report_tax.cgi b/httemplate/search/report_tax.cgi
index 248f6c5..2786f57 100755
--- a/httemplate/search/report_tax.cgi
+++ b/httemplate/search/report_tax.cgi
@@ -239,6 +239,8 @@ as <A HREF="<% $p.'search/report_tax-xls.cgi?'.$cgi->query_string%>">Excel sprea
<%init>
+my $DEBUG = $cgi->param('debug') || 0;
+
die "access denied"
unless $FS::CurrentUser::CurrentUser->access_right('Financial reports');
@@ -252,15 +254,19 @@ my $join_cust = ' JOIN cust_bill USING ( invnum )
LEFT JOIN cust_main USING ( custnum ) ';
my $join_cust_pkg = $join_cust.
' LEFT JOIN cust_pkg USING ( pkgnum )
- LEFT JOIN part_pkg USING ( pkgpart ) ';
-$join_cust_pkg .= ' LEFT JOIN cust_location USING ( locationnum )'
- if $conf->exists('tax-pkg_address');
+ LEFT JOIN part_pkg USING ( pkgpart )
+ LEFT JOIN cust_location
+ ON ( cust_location.locationnum = ' .
+ FS::cust_pkg->tax_locationnum_sql . ' )';
my $from_join_cust_pkg = " FROM cust_bill_pkg $join_cust_pkg ";
my $where = "WHERE _date >= $beginning AND _date <= $ending ";
-my( $location_sql, @base_param ) = FS::cust_pkg->location_sql;
+# this query will be run once per cust_main_county,
+# or maybe once per country/state/city tuple,
+# or maybe once per country/state...it's hard to say.
+my ($location_sql, @base_param) = FS::cust_location->in_county_sql(param => 1);
$where .= " AND $location_sql ";
my $agentname = '';
@@ -291,59 +297,27 @@ sub gotcust {
";
}
-my $gotcust;
-if ( $conf->exists('tax-ship_address') ) {
-
- $gotcust = "
- ( cust_main_county.country = cust_main.country
- OR cust_main_county.country = cust_main.ship_country
- )
-
- AND
-
- (
- ( ( ship_last IS NULL OR ship_last = '' )
- AND ". gotcust('cust_main'). "
- )
- OR
- ( ship_last IS NOT NULL AND ship_last != ''
- AND ". gotcust('cust_main', 'ship_'). "
- )
- )
- ";
-
-} else {
-
- $gotcust = gotcust('cust_main');
-
-}
-if ( $conf->exists('tax-pkg_address') ) {
- $gotcust = "
- ( cust_pkg.locationnum IS NULL AND $gotcust)
- OR ( cust_pkg.locationnum IS NOT NULL AND ". gotcust('cust_location'). " )";
- $gotcust =
- "WHERE 0 < ( SELECT COUNT(*) FROM cust_pkg
- LEFT JOIN cust_main USING ( custnum )
- LEFT JOIN cust_location USING ( locationnum )
- WHERE $gotcust
- LIMIT 1
- )
- ";
-} else {
- $gotcust =
- "WHERE 0 < ( SELECT COUNT(*) FROM cust_main WHERE $gotcust LIMIT 1 )";
-}
+#non-parameterized form
+my $location_in_county = FS::cust_location->in_county_sql;
+my $gotcust = "WHERE EXISTS(
+ SELECT 1 FROM cust_location WHERE $location_in_county AND disabled IS NULL
+)";
my $out = 'Out of taxable region(s)';
# these are actually tax labels, not regions
my %regions = ();
+# Phase 1: Taxable and exempt sales
+# Collect for each cust_main_county, and assign to a bin based on label.
+# Note that "label" includes city if show_cities is on, and taxclass if
+# show_taxclasses is on.
foreach my $r ( qsearch({ 'table' => 'cust_main_county',
'extra_sql' => $gotcust,
+ 'debug' => $DEBUG,
})
)
{
- #warn $r->county. ' '. $r->state. ' '. $r->country. "\n";
+ warn $r->county. ' '. $r->state. ' '. $r->country. "\n" if $DEBUG > 1;
# set up a %regions entry for this region's tax label
my $label = getlabel($r);
@@ -475,7 +449,7 @@ foreach my $r ( qsearch({ 'table' => 'cust_main_county',
$regions{$label}->{'rate'} = $r->tax.'%';
}
}
-#warn Dumper(\%regions);
+warn Dumper(\%regions) if $DEBUG > 1;
# $regions{$label} now contains 'total', 'exempt_cust', 'exempt_pkg',
# 'exempt_monthly', summed over each set of regions with the same label.
@@ -491,29 +465,27 @@ my $taxclass_distinct =
)." AS taxclass";
+# Phase 2: invoiced/credited tax items
+# Collect this data for each country/state/city/district/taxname(/taxclass).
my %qsearch = (
'select' => "DISTINCT $distinct, $taxclass_distinct",
'table' => 'cust_main_county',
'hashref' => {},
'extra_sql' => $gotcust,
+ 'debug' => $DEBUG,
);
-my $taxfromwhere = " FROM cust_bill_pkg $join_cust ";
+# Join to cust_main the same as before (we need agentnum)
+# but not to cust_pkg (because tax line items don't have a package)
+# and then to cust_location via cust_bill_pkg_tax_location
+my $taxfromwhere = "FROM cust_bill_pkg $join_cust
+ LEFT JOIN cust_bill_pkg_tax_location USING ( billpkgnum )
+ LEFT JOIN cust_location USING ( locationnum )
+ ";
my $taxwhere = $where;
-if ( $conf->exists('tax-pkg_address') ) {
-
- $taxfromwhere .= 'LEFT JOIN cust_bill_pkg_tax_location USING ( billpkgnum )
- LEFT JOIN cust_location USING ( locationnum ) ';
- #quelle kludge
- $taxwhere =~ s/cust_pkg\.locationnum/cust_bill_pkg_tax_location.locationnum/g;
-
-}
my $creditfromwhere = $taxfromwhere.
- " JOIN cust_credit_bill_pkg USING (billpkgnum";
-$creditfromwhere .= " ,billpkgtaxlocationnum"
- if $conf->exists('tax-pkg_address');
-$creditfromwhere .= ")";
+ " JOIN cust_credit_bill_pkg USING (billpkgnum, billpkgtaxlocationnum)";
$taxfromwhere .= " $taxwhere "; #AND payby != 'COMP' ";
$creditfromwhere .= " $taxwhere AND billpkgtaxratelocationnum IS NULL"; #AND payby != 'COMP' ";
@@ -611,6 +583,10 @@ foreach my $r ( qsearch(\%qsearch) ) {
}
+# Phase 3: Non-taxclassed totals for invoiced/credited tax
+# (If show_taxclasses is not in use, this was phase 2, but it
+# displays somewhere different.)
+# Don't filter by report_groups.
my %base_regions = ();
if ( $cgi->param('show_taxclasses') ) {
diff --git a/httemplate/view/cust_main/contacts.html b/httemplate/view/cust_main/contacts.html
index fe7cc5c..6213f27 100644
--- a/httemplate/view/cust_main/contacts.html
+++ b/httemplate/view/cust_main/contacts.html
@@ -1,122 +1,128 @@
-% my %which = (
-% '' => emt('Billing'),
-% 'ship_' => emt('Service'),
-% );
-% foreach my $which ( '', 'ship_' ) {
-% my $pre = $cust_main->get("${which}last") ? $which : '';
-
-<FONT CLASS="fsinnerbox-title"><% $which{$which} %> <% mt('address') |h %></FONT>
+% my %addr_label = ('bill' => 'Billing address', 'ship' => 'Service address');
+
+%# Locations (possibly break this out)
+% my @which = ('bill');
+% push @which, 'ship' if $cust_main->has_ship_address;
+% while (@which) {
+% my $this = shift @which;
+% my $method = $this.'_location';
+% my $location = $cust_main->$method;
+<FONT CLASS="fsinnerbox-title"><% mt( $addr_label{$this} ) |h %></FONT>
<TABLE CLASS="fsinnerbox">
-<TR>
- <TD ALIGN="right"><% mt('Contact name') |h %></TD>
- <TD COLSPAN=5 BGCOLOR="#ffffff">
- <% $cust_main->get("${pre}last"). ', '. $cust_main->get("${pre}first") |h %>
- </TD>
-% if ( $which eq '' && $conf->exists('show_ss') ) {
- <TD ALIGN="right"><% mt('SS#') |h %></TD>
- <TD BGCOLOR="#ffffff"><% $conf->exists('unmask_ss') ? $cust_main->ss : $cust_main->masked('ss') || '&nbsp' %></TD>
-% }
-</TR>
-% if ( $conf->exists('cust-email-high-visibility') && $which eq '') {
+% if ( $this eq 'bill' ) {
+% #billing contact fields
+ <TR>
+ <TD ALIGN="right"><% mt('Contact name') |h %></TD>
+ <TD COLSPAN=5 BGCOLOR="#ffffff"><% $cust_main->contact |h %></TD>
+% if ( $conf->exists('show_ss') ) {
+ <TD ALIGN="right"><% mt('SS#') |h %></TD>
+ <TD BGCOLOR="#ffffff"><% $conf->exists('unmask_ss')
+ ? $cust_main->ss
+ : $cust_main->masked('ss') || '&nbsp;' %></TD>
+% }
+ </TR>
+% if ( $conf->exists('cust-email-high-visibility') ) {
<TR>
<TD ALIGN="right"><% mt('Email address(es)') |h %></TD>
<TD BGCOLOR="#ffff00">
- <% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || $no %>
+ <% $cust_main->invoicing_list_emailonly_scalar || $no %>
</TD>
</TR>
-% }
-
-% if ( $cust_main->get("${pre}company") ) {
+% }
+% if ( $cust_main->company ) {
<TR>
<TD ALIGN="right"><% mt('Company') |h %></TD>
- <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}company") |h %></TD>
+ <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->company %></TD>
</TR>
-% }
-
+% }
+% } # if $this eq 'bill'
+% # now the actual address
<TR>
<TD ALIGN="right"><% mt('Address') |h %></TD>
- <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}address1") |h %></TD>
+ <TD COLSPAN=7 BGCOLOR="#ffffff"><% $location->address1 |h %></TD>
</TR>
-% if ( $cust_main->get("${pre}address2") ) {
-% my $address2_label =
-% ( $conf->exists('cust_main-require_address2')
-% && ! ( $pre xor $cust_main->has_ship_address )
-% )
-% ? emt('Unit #')
-% : ' ';
+% if ( $location->get('address2') ) {
+% my $address2_label = $conf->exists('cust_main-require_address2')
+% ? emt('Unit #')
+% : ' ';
- <TR>
- <TD ALIGN="right"><% $address2_label %></TD>
- <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}address2") |h %></TD>
- </TR>
+<TR>
+ <TD ALIGN="right"><% $address2_label %></TD>
+ <TD COLSPAN=7 BGCOLOR="#ffffff"><% $location->address2 |h %></TD>
+</TR>
% }
<TR>
<TD ALIGN="right"><% mt('City') |h %></TD>
- <TD BGCOLOR="#ffffff"><% $cust_main->get("${pre}city") |h %></TD>
-% if ( $cust_main->get("${pre}county") ) {
+ <TD BGCOLOR="#ffffff"><% $location->city |h %></TD>
+% if ( $location->county ) {
<TD ALIGN="right"><% mt('County') |h %></TD>
- <TD BGCOLOR="#ffffff"><% $cust_main->get("${pre}county") |h %></TD>
+ <TD BGCOLOR="#ffffff"><% $location->county |h %></TD>
% }
<TD ALIGN="right"><% mt('State') |h %></TD>
- <TD BGCOLOR="#ffffff"><% state_label( $cust_main->get("${pre}state"), $cust_main->get("${pre}country") ) |h %></TD>
+ <TD BGCOLOR="#ffffff"><% state_label( $location->state, $location->country ) |h %></TD>
<TD ALIGN="right"><% mt('Zip') |h %></TD>
- <TD BGCOLOR="#ffffff"><% $cust_main->get("${pre}zip") %></TD>
+ <TD BGCOLOR="#ffffff"><% $location->zip %></TD>
</TR>
<TR>
<TD ALIGN="right"><% mt('Country') |h %></TD>
- <TD BGCOLOR="#ffffff"><% code2country( $cust_main->get("${pre}country") ) %></TD>
+ <TD BGCOLOR="#ffffff"><% code2country( $location->country ) %></TD>
</TR>
-% if ( $cust_main->get($pre.'latitude') && $cust_main->get($pre.'longitude') ) {
- <& /elements/tr-coords.html, $cust_main->get($pre.'latitude'),
- $cust_main->get($pre.'longitude'),
+% if ( $location->latitude && $location->longitude ) {
+ <& /elements/tr-coords.html, $location->latitude,
+ $location->longitude,
$cust_main->name_short,
$cust_main->agentnum,
&>
% }
+
+% if ( $this eq 'bill' ) {
+% # billing contact phone numbers
+% foreach my $phone (qw(daytime night mobile)) {
+% next if !$cust_main->get($phone);
+<TR>
+ <TD ALIGN="right"><% $phone_label{$phone} %></TD>
+ <TD COLSPAN=3 BGCOLOR="#ffffff">
+ <& /elements/phonenumber.html,
+ $cust_main->get($phone),
+ callable => 1,
+ calling_list_exempt => $cust_main->calling_list_exempt,
+ &>
+ </TD>
+</TR>
-% foreach my $phone (grep $cust_main->get($pre.$_), qw( daytime night mobile )){
-
- <TR>
- <TD ALIGN="right"><% $phone_label{$phone} %></TD>
- <TD COLSPAN=3 BGCOLOR="#ffffff">
- <& /elements/phonenumber.html,
- $cust_main->get($pre.$phone),
- 'callable'=>1,
- 'calling_list_exempt'=>$cust_main->calling_list_exempt,
- &>
- </TD>
- </TR>
-
-% }
+% } #foreach $phone
+% if ( $cust_main->get('fax') ) {
-% if ( $cust_main->get("${pre}fax") ) {
<TR>
<TD ALIGN="right"><% mt('Fax') |h %></TD>
<TD COLSPAN=3 BGCOLOR="#ffffff">
- <% $cust_main->get("${pre}fax") || '&nbsp' %>
+ <% $cust_main->get('fax') || '&nbsp;' %>
</TD>
</TR>
-% }
-% if ( $which eq '' && $conf->exists('show_stateid') ) {
- <TR>
+% }
+%
+% if ( $conf->exists('show_stateid') ) {
+
+<TR>
<TD ALIGN="right"><% $stateid_label %></TD>
<TD BGCOLOR="#ffffff"><% $cust_main->masked('stateid') || '&nbsp' %></TD>
<TD ALIGN="right"><% $stateid_state_label %></TD>
<TD BGCOLOR="#ffffff"><% $cust_main->stateid_state || '&nbsp' %></TD>
</TR>
-% }
+% }
+% } #if $this eq 'bill'
</TABLE>
-% if ( $which ne 'ship_' ) {
+% if ( @which ) {
<BR>
% }
-% }
+% } #while @which
<%once>
my %phone_label = (
@@ -147,7 +153,7 @@ my $stateid_state_label = FS::Msgcat::_gettext('stateid_state') =~ /^(stateid_st
</%once>
<%init>
-my( $cust_main ) = @_;
+my $cust_main = shift;
my $conf = new FS::Conf;
my @invoicing_list = $cust_main->invoicing_list;
my $no = emt('no');
diff --git a/httemplate/view/cust_main/locations.html b/httemplate/view/cust_main/locations.html
index 98c9336..b29d0ce 100755
--- a/httemplate/view/cust_main/locations.html
+++ b/httemplate/view/cust_main/locations.html
@@ -5,12 +5,17 @@ span.loclabel {
background-color: #cccccc;
border: 1px solid black
}
+table.location {
+ width: 100%;
+ padding: 1px;
+ border-spacing: 0px;
+}
</STYLE>
% foreach my $locationnum (@sorted) {
% my $packages = $packages_in{$locationnum};
% my $loc = $locations{$locationnum};
% next if $loc->disabled and scalar(@$packages) == 0;
-<& /elements/table-grid.html &>
+<TABLE CLASS="grid location">
<TR><TH COLSPAN=3 ALIGN="left" VALIGN="bottom"
STYLE="padding-bottom: 0px;
padding-left: 0px;
@@ -18,10 +23,7 @@ STYLE="padding-bottom: 0px;
border-bottom-color: black;
border-bottom-width: 1px;">
<SPAN CLASS="loclabel">
-% if (! $locationnum) {
-<% mt('Default service location:') |h %>
-% }
-% elsif ( $loc->disabled ) {
+% if ( $loc->disabled ) {
<FONT COLOR="#808080"><I>
% }
<% $loc->location_label %></SPAN>
@@ -49,8 +51,7 @@ my %locations = map { $_->locationnum => $_ } qsearch({
'order_by' => 'ORDER BY country, state, city, address1, locationnum',
});
my @sections = keys %locations;
-$locations{''} = $cust_main;
-my %packages_in = map { $_ => [] } ('', @sections);
+my %packages_in = map { $_ => [] } (@sections);
my %active = (); # groups with non-canceled packages
foreach my $cust_pkg ( @$all_packages ) {
@@ -58,10 +59,13 @@ foreach my $cust_pkg ( @$all_packages ) {
push @{ $packages_in{$key} }, $cust_pkg;
$active{$key} = 1 if !$cust_pkg->getfield('cancel');
}
+# prevent disabling these
+$active{$cust_main->ship_locationnum} = 1;
+$active{$cust_main->bill_locationnum} = 1;
my @sorted = (
- '',
- grep ( { $active{$_} } @sections),
+ $cust_main->ship_locationnum,
+ grep ( { $active{$_} && $_ != $cust_main->ship_locationnum } @sections),
grep ( { !$active{$_} } @sections),
);
diff --git a/httemplate/view/cust_main/misc.html b/httemplate/view/cust_main/misc.html
index 12faa57..a0ab403 100644
--- a/httemplate/view/cust_main/misc.html
+++ b/httemplate/view/cust_main/misc.html
@@ -134,9 +134,9 @@
<TR>
<TD ALIGN="right">
- <% mt('Census tract ([_1])', $cust_main->censusyear) |h %>
+ <% mt('Census tract ([_1])', $cust_main->ship_location->censusyear) |h %>
</TD>
- <TD BGCOLOR="#ffffff"><% $cust_main->censustract %></TD>
+ <TD BGCOLOR="#ffffff"><% $cust_main->ship_location->censustract %></TD>
</TR>
% }
@@ -145,7 +145,7 @@
<TR>
<TD ALIGN="right"><% mt('Tax district') |h %></TD>
- <TD BGCOLOR="#ffffff"><% $cust_main->district %></TD>
+ <TD BGCOLOR="#ffffff"><% $cust_main->ship_location->district %></TD>
</TR>
% }