summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Conf.pm11
-rw-r--r--FS/FS/cust_main.pm124
-rwxr-xr-xhttemplate/edit/cust_main.cgi85
-rw-r--r--httemplate/edit/cust_main/billing.html4
-rw-r--r--httemplate/edit/cust_main/contact.html18
-rw-r--r--httemplate/elements/header.html29
-rwxr-xr-xhttemplate/search/cust_main.cgi5
-rw-r--r--httemplate/view/cust_main/contacts.html19
8 files changed, 195 insertions, 100 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 0f1fcbbee..85a2b9b07 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -1716,7 +1716,14 @@ worry that config_items is freeside-specific and icky.
{
'key' => 'address2-search',
'section' => 'UI',
- 'description' => 'Enable a "Unit" search box which searches the second address field',
+ 'description' => 'Enable a "Unit" search box which searches the second address field. Useful for multi-tenant applications. See also: cust_main-require_address2',
+ 'type' => 'checkbox',
+ },
+
+ {
+ 'key' => 'cust_main-require_address2',
+ 'section' => 'UI',
+ 'description' => 'Second address field is required (on service address only, if billing and service addresses differ). Also enables "Unit" labeling of address2 on customer view and edit pages. Useful for multi-tenant applications. See also: address2-search',
'type' => 'checkbox',
},
@@ -2091,7 +2098,7 @@ worry that config_items is freeside-specific and icky.
{
'key' => 'cust_main-require_invoicing_list_email',
'section' => '',
- 'description' => 'Require at least one invoicing email address for all customer records.',
+ 'description' => 'Email address field is required: require at least one invoicing email address for all customer records.',
'type' => 'checkbox',
},
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 59ebfb58a..b5e689233 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -1291,58 +1291,60 @@ sub check {
}
- my @addfields = qw(
- last first company address1 address2 city county state zip
- country daytime night fax
- );
+ if ( $self->has_ship_address
+ && scalar ( grep { $self->getfield($_) ne $self->getfield("ship_$_") }
+ $self->addr_fields )
+ )
+ {
+ my $error =
+ $self->ut_name('ship_last')
+ || $self->ut_name('ship_first')
+ || $self->ut_textn('ship_company')
+ || $self->ut_text('ship_address1')
+ || $self->ut_textn('ship_address2')
+ || $self->ut_text('ship_city')
+ || $self->ut_textn('ship_county')
+ || $self->ut_textn('ship_state')
+ || $self->ut_country('ship_country')
+ ;
+ return $error if $error;
- if ( defined $self->dbdef_table->column('ship_last') ) {
- if ( scalar ( grep { $self->getfield($_) ne $self->getfield("ship_$_") }
- @addfields )
- && scalar ( grep { $self->getfield("ship_$_") ne '' } @addfields )
- )
- {
- my $error =
- $self->ut_name('ship_last')
- || $self->ut_name('ship_first')
- || $self->ut_textn('ship_company')
- || $self->ut_text('ship_address1')
- || $self->ut_textn('ship_address2')
- || $self->ut_text('ship_city')
- || $self->ut_textn('ship_county')
- || $self->ut_textn('ship_state')
- || $self->ut_country('ship_country')
- ;
- return $error if $error;
+ #false laziness with above
+ unless ( qsearchs('cust_main_county', {
+ 'country' => $self->ship_country,
+ 'state' => '',
+ } ) ) {
+ return "Unknown ship_state/ship_county/ship_country: ".
+ $self->ship_state. "/". $self->ship_county. "/". $self->ship_country
+ unless qsearch('cust_main_county',{
+ 'state' => $self->ship_state,
+ 'county' => $self->ship_county,
+ 'country' => $self->ship_country,
+ } );
+ }
+ #eofalse
- #false laziness with above
- unless ( qsearchs('cust_main_county', {
- 'country' => $self->ship_country,
- 'state' => '',
- } ) ) {
- return "Unknown ship_state/ship_county/ship_country: ".
- $self->ship_state. "/". $self->ship_county. "/". $self->ship_country
- unless qsearch('cust_main_county',{
- 'state' => $self->ship_state,
- 'county' => $self->ship_county,
- 'country' => $self->ship_country,
- } );
- }
- #eofalse
-
- $error =
- $self->ut_phonen('ship_daytime', $self->ship_country)
- || $self->ut_phonen('ship_night', $self->ship_country)
- || $self->ut_phonen('ship_fax', $self->ship_country)
- || $self->ut_zip('ship_zip', $self->ship_country)
- ;
- return $error if $error;
+ $error =
+ $self->ut_phonen('ship_daytime', $self->ship_country)
+ || $self->ut_phonen('ship_night', $self->ship_country)
+ || $self->ut_phonen('ship_fax', $self->ship_country)
+ || $self->ut_zip('ship_zip', $self->ship_country)
+ ;
+ return $error if $error;
+
+ return "Unit # is required."
+ if $self->ship_address2 =~ /^\s*$/
+ && $conf->exists('cust_main-require_address2');
+
+ } else { # ship_ info eq billing info, so don't store dup info in database
+
+ $self->setfield("ship_$_", '')
+ foreach $self->addr_fields;
+
+ return "Unit # is required."
+ if $self->address2 =~ /^\s*$/
+ && $conf->exists('cust_main-require_address2');
- } else { # ship_ info eq billing info, so don't store dup info in database
- $self->setfield("ship_$_", '')
- foreach qw( last first company address1 address2 city county state zip
- country daytime night fax );
- }
}
#$self->payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP|PREPAY|CASH|WEST|MCRD)$/
@@ -1543,6 +1545,30 @@ sub check {
$self->SUPER::check;
}
+=item addr_fields
+
+Returns a list of fields which have ship_ duplicates.
+
+=cut
+
+sub addr_fields {
+ qw( last first company
+ address1 address2 city county state zip country
+ daytime night fax
+ );
+}
+
+=item has_ship_address
+
+Returns true if this customer record has a separate shipping address.
+
+=cut
+
+sub has_ship_address {
+ my $self = shift;
+ scalar( grep { $self->getfield("ship_$_") ne '' } $self->addr_fields );
+}
+
=item all_pkgs
Returns all packages (see L<FS::cust_pkg>) for this customer.
diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi
index 579d6cfe3..be9dd1bfb 100755
--- a/httemplate/edit/cust_main.cgi
+++ b/httemplate/edit/cust_main.cgi
@@ -207,13 +207,31 @@
<!-- contact info -->
+% my $same_checked = '';
+% my $ship_disabled = '';
+% unless ( $cust_main->ship_last && $same ne 'Y' ) {
+% $same_checked = 'CHECKED';
+% $ship_disabled = 'DISABLED STYLE="background-color: #dddddd"';
+% foreach (
+% qw( last first company address1 address2 city county state zip country
+% daytime night fax )
+% ) {
+% $cust_main->set("ship_$_", $cust_main->get($_) );
+% }
+% }
+
<BR><BR>
Billing address
-<% include('cust_main/contact.html', $cust_main, '', 'bill_changed(this)', '', 'ss' => $ss, 'stateid' => $stateid ) %>
-
-<!-- service address -->
-% if ( defined $cust_main->dbdef_table->column('ship_last') ) {
-
+<% include('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
+ )
+%>
<SCRIPT>
function bill_changed(what) {
@@ -241,44 +259,47 @@ function bill_changed(what) {
function samechanged(what) {
if ( what.checked ) {
bill_changed(what);
-% for (qw( last first company address1 address2 city county state zip country daytime night fax )) {
- what.form.ship_<%$_%>.disabled = true;
- what.form.ship_<%$_%>.style.backgroundColor = '#dddddd';
-% }
+% for (qw( last first company address1 address2 city county state zip country daytime night fax )) {
+ 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 (qw( last first company address1 address2 city county state zip country daytime night fax )) {
- what.form.ship_<%$_%>.disabled = false;
- what.form.ship_<%$_%>.style.backgroundColor = '#ffffff';
-% }
+% for (qw( last first company address1 address2 city county state zip country daytime night fax )) {
+ 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 = '';
+% }
}
}
</SCRIPT>
-%
-% my $checked = '';
-% my $disabled = '';
-% my $disabledselect = '';
-% unless ( $cust_main->ship_last && $same ne 'Y' ) {
-% $checked = 'CHECKED';
-% $disabled = 'DISABLED STYLE="background-color: #dddddd"';
-% foreach (
-% qw( last first company address1 address2 city county state zip country
-% daytime night fax )
-% ) {
-% $cust_main->set("ship_$_", $cust_main->get($_) );
-% }
-% }
-%
-
<BR>
Service address
-(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)" <%$checked%>>same as billing address)
-<% include('cust_main/contact.html', $cust_main, 'ship_', '', $disabled ) %>
-% }
+(<INPUT TYPE="checkbox" NAME="same" VALUE="Y" onClick="samechanged(this)" <%$same_checked%>>same as billing address)
+<% include('cust_main/contact.html',
+ 'cust_main' => $cust_main,
+ 'pre' => 'ship_',
+ 'onchange' => '',
+ 'disabled' => $ship_disabled,
+ )
+%>
<!-- billing info -->
diff --git a/httemplate/edit/cust_main/billing.html b/httemplate/edit/cust_main/billing.html
index 394c5d8d5..6ed35c15a 100644
--- a/httemplate/edit/cust_main/billing.html
+++ b/httemplate/edit/cust_main/billing.html
@@ -426,7 +426,9 @@
% }
<TR>
- <TD ALIGN="right" WIDTH="200">Email invoice </TD>
+ <TD ALIGN="right" WIDTH="200">
+ <% $conf->exists('cust_main-require_invoicing_list_email') ? $r : '' %>Email address(es)
+ </TD>
<TD WIDTH="408"><INPUT TYPE="text" NAME="invoicing_list" VALUE="<% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) %>"></TD>
</TR>
diff --git a/httemplate/edit/cust_main/contact.html b/httemplate/edit/cust_main/contact.html
index 58fee3291..21c6b2990 100644
--- a/httemplate/edit/cust_main/contact.html
+++ b/httemplate/edit/cust_main/contact.html
@@ -32,8 +32,16 @@
</TD>
</TR>
+% my $address2_label_style =
+% ( $disabled
+% || ! $conf->exists('cust_main-require_address2')
+% || ( !$pre && !$opt{'same_checked'} )
+% )
+% ? 'visibility:hidden'
+% : '';
+
<TR>
- <TD ALIGN="right">&nbsp;</TD>
+ <TD ALIGN="right"><FONT ID="<% $pre %>address2_required" color="#ff0000" STYLE="<% $address2_label_style %>">*</FONT>&nbsp;<FONT ID="<% $pre %>address2_label" STYLE="<% $address2_label_style %>"><B>Unit&nbsp;#</B></FONT></TD>
<TD COLSPAN=7>
<INPUT TYPE="text" NAME="<%$pre%>address2" VALUE="<% $cust_main->get($pre.'address2') %>" SIZE=70 onChange="<% $onchange %>" <%$disabled%>>
</TD>
@@ -107,7 +115,13 @@
<%init>
-my( $cust_main, $pre, $onchange, $disabled, %opt ) = @_;
+#my( $cust_main, $pre, $onchange, $disabled, %opt ) = @_;
+my %opt = @_;
+my $cust_main = $opt{'cust_main'};
+my $pre = $opt{'pre'};
+my $onchange = $opt{'onchange'};
+my $disabled = $opt{'disabled'};
+
my $conf = new FS::Conf;
foreach (qw(ss stateid)) {
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
index 0ff8ecda6..dfe6b6829 100644
--- a/httemplate/elements/header.html
+++ b/httemplate/elements/header.html
@@ -19,6 +19,11 @@
what.value = '';
}
+ function clearhint_search_address2 (what) {
+ if ( what.value == '(Unit #)' )
+ what.value = '';
+ }
+
function clearhint_search_invoice (what) {
if ( what.value == '(inv #)' )
what.value = '';
@@ -113,14 +118,14 @@ input.fsblackbuttonselected {
<TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=0>
<TR>
- <TD COLSPAN=5 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
+ <TD COLSPAN=6 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<%$fsurl%>images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
</TR>
% if ( $menu_position eq 'top' ) {
<TR>
- <TD COLSPAN="5" WIDTH="100%" STYLE="padding:0">
+ <TD COLSPAN="6" WIDTH="100%" STYLE="padding:0">
<SCRIPT TYPE="text/javascript">
document.write(myBar);
</SCRIPT>
@@ -129,12 +134,12 @@ input.fsblackbuttonselected {
</TR>
<TR>
- <TD COLSPAN="5" WIDTH="100%" HEIGHT="2px" STYLE="padding:0" BGCOLOR="#000000">
+ <TD COLSPAN="6" WIDTH="100%" HEIGHT="2px" STYLE="padding:0" BGCOLOR="#000000">
</TD>
</TR>
<TR>
- <TD COLSPAN="5" WIDTH="100%" HEIGHT="4px" STYLE="padding:0" BGCOLOR="#000000">
+ <TD COLSPAN="6" WIDTH="100%" HEIGHT="4px" STYLE="padding:0" BGCOLOR="#000000">
</TD>
</TR>
@@ -156,21 +161,31 @@ input.fsblackbuttonselected {
</FORM>
</TD>
+ <TD COLSPAN=1 BGCOLOR="#000000" ALIGN="center">
+% if ( $conf->exists('address2-search') ) {
+ <FORM ACTION="<%$fsurl%>search/cust_main.cgi" METHOD="GET" STYLE="margin:0;display:inline">
+ <INPUT TYPE="hidden" NAME="address2_on" VALUE="1">
+ <INPUT NAME="address2_text" TYPE="text" VALUE="(Unit #)" SIZE="4" onFocus="clearhint_search_address2(this);" onClick="clearhint_search_address2(this);" STYLE="vertical-align:bottom;text-align:right;margin-bottom:1px">
+ <BR>
+ <INPUT TYPE="submit" VALUE="Search units" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%;padding-left:2px;padding-right:2px">
+ </FORM>
+% }
+ </TD>
+
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
% if ( $FS::CurrentUser::CurrentUser->access_right('View invoices') ) {
<FORM ACTION="<%$fsurl%>search/cust_bill.html" METHOD="GET" STYLE="margin:0;display:inline">
<INPUT NAME="invnum" TYPE="text" VALUE="(inv #)" SIZE="4" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" STYLE="vertical-align:bottom;text-align:right;margin-bottom:1px">
-% if ( $FS::CurrentUser::CurrentUser->access_right('List invoices') ) {
+% if ( $FS::CurrentUser::CurrentUser->access_right('List invoices') ) {
<A HREF="<%$fsurl%>search/report_cust_bill.html" STYLE="color: #ffffff; font-size: 70%">Advanced</A>
-% }
+% }
<BR>
<INPUT TYPE="submit" VALUE="Search invoices" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
</FORM>
% }
-
</TD>
<TD COLSPAN=1 BGCOLOR="#000000" ALIGN="right">
diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi
index b0f657fbb..1ddafae0b 100755
--- a/httemplate/search/cust_main.cgi
+++ b/httemplate/search/cust_main.cgi
@@ -688,9 +688,8 @@
% { 'address2' => { 'op' => 'ILIKE',
% 'value' => $address2 } } );
% push @cust_main, qsearch( 'cust_main',
-% { 'address2' => { 'op' => 'ILIKE',
-% 'value' => $address2 } } )
-% if defined dbdef->table('cust_main')->column('ship_last');
+% { 'ship_address2' => { 'op' => 'ILIKE',
+% 'value' => $address2 } } );
%
% \@cust_main;
%}
diff --git a/httemplate/view/cust_main/contacts.html b/httemplate/view/cust_main/contacts.html
index 22594c5e2..20770e45b 100644
--- a/httemplate/view/cust_main/contacts.html
+++ b/httemplate/view/cust_main/contacts.html
@@ -25,12 +25,23 @@
<TD ALIGN="right">Address</TD>
<TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}address1") %></TD>
</TR>
+
% if ( $cust_main->get("${pre}address2") ) {
+% my $address2_label =
+% ( $conf->exists('cust_main-require_address2')
+% # && ( ( !$which && !$cust_main->has_ship_address )
+% # || ( $which && $cust_main->has_ship_address )
+% # )
+% && ! ( $which xor $cust_main->has_ship_address )
+% )
+% ? 'Unit&nbsp;#'
+% : '&nbsp;';
+
+ <TR>
+ <TD ALIGN="right"><% $address2_label %></TD>
+ <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}address2") %></TD>
+ </TR>
-<TR>
- <TD ALIGN="right">&nbsp;</TD>
- <TD COLSPAN=7 BGCOLOR="#ffffff"><% $cust_main->get("${pre}address2") %></TD>
-</TR>
% }
<TR>