user-defined site ID / location codes per location, RT#30856, RT#27545
authorIvan Kohler <ivan@freeside.biz>
Sat, 25 Oct 2014 19:08:06 +0000 (12:08 -0700)
committerIvan Kohler <ivan@freeside.biz>
Sat, 25 Oct 2014 19:08:06 +0000 (12:08 -0700)
FS/FS/Conf.pm
FS/FS/Schema.pm
FS/FS/Template_Mixin.pm
FS/FS/cust_location.pm
FS/FS/cust_main.pm
FS/FS/cust_main/Location.pm
conf/invoice_html
conf/invoice_latex
httemplate/edit/cust_main/top_misc.html
httemplate/elements/location.html
httemplate/view/cust_main/contacts.html

index b4cd7d8..6b59574 100644 (file)
@@ -3477,7 +3477,8 @@ and customer address. Include units.',
     'description' => 'Optional "site ID" to show in the location label',
     'type'        => 'select',
     'select_hash' => [ '' => '',
     'description' => 'Optional "site ID" to show in the location label',
     'type'        => 'select',
     'select_hash' => [ '' => '',
-                       'CoStAg' => 'CoStAgXXXXX (country, state, agent name, locationnum)',
+                       'CoStAg'    => 'CoStAgXXXXX (country, state, agent name, locationnum)',
+                       '_location' => 'Manually defined per location',
                       ],
   },
 
                       ],
   },
 
index 9b1fa94..cb5fb85 100644 (file)
@@ -1358,6 +1358,7 @@ sub tables_hashref {
         'locationnum',      'serial',     '',      '', '', '',
         'prospectnum',         'int', 'NULL',      '', '', '',
         'custnum',             'int', 'NULL',      '', '', '',
         'locationnum',      'serial',     '',      '', '', '',
         'prospectnum',         'int', 'NULL',      '', '', '',
         'custnum',             'int', 'NULL',      '', '', '',
+        'locationname',    'varchar', 'NULL', $char_d, '', '',
         'address1',        'varchar',     '', $char_d, '', '', 
         'address2',        'varchar', 'NULL', $char_d, '', '', 
         'city',            'varchar',     '', $char_d, '', '', 
         'address1',        'varchar',     '', $char_d, '', '', 
         'address2',        'varchar', 'NULL', $char_d, '', '', 
         'city',            'varchar',     '', $char_d, '', '', 
index d652d53..ce7efca 100644 (file)
@@ -2090,8 +2090,9 @@ sub _items_sections {
           $section->{'sort_weight'} = sprintf('%012s',$location->zip) .
                                       $locationnum;
           $section->{'location'} = {
           $section->{'sort_weight'} = sprintf('%012s',$location->zip) .
                                       $locationnum;
           $section->{'location'} = {
+            label_prefix => &{ $escape }($location->label_prefix),
             map { $_ => &{ $escape }($location->get($_)) }
             map { $_ => &{ $escape }($location->get($_)) }
-            $location->fields
+              $location->fields
           };
         } else {
           $section->{'category'} = $sectionname;
           };
         } else {
           $section->{'category'} = $sectionname;
index 2e0871d..23dbce9 100644 (file)
@@ -322,6 +322,7 @@ sub check {
     $self->ut_numbern('locationnum')
     || $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
     || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')
     $self->ut_numbern('locationnum')
     || $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
     || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')
+    || $self->ut_alphan('locationname')
     || $self->ut_text('address1')
     || $self->ut_textn('address2')
     || $self->ut_text('city')
     || $self->ut_text('address1')
     || $self->ut_textn('address2')
     || $self->ut_text('city')
@@ -604,14 +605,61 @@ sub dealternize {
 
 =item location_label
 
 
 =item location_label
 
-Returns the label of the location object, with an optional site ID
-string (based on the cust_location-label_prefix config option).
+Returns the label of the location object.
+
+Options:
+
+=over 4
+
+=item cust_main
+
+Customer object (see L<FS::cust_main>)
+
+=item prospect_main
+
+Prospect object (see L<FS::prospect_main>)
+
+=item join_string
+
+String used to join location elements
+
+=back
 
 =cut
 
 sub location_label {
   my( $self, %opt ) = @_;
 
 
 =cut
 
 sub location_label {
   my( $self, %opt ) = @_;
 
+  my $prefix = $self->label_prefix;
+  $prefix .= ($opt{join_string} ||  ': ') if $prefix;
+
+  $prefix . $self->SUPER::location_label(%opt);
+}
+
+=item label_prefix
+
+Returns the optional site ID string (based on the cust_location-label_prefix
+config option), "Default service location", or the empty string.
+
+Options:
+
+=over 4
+
+=item cust_main
+
+Customer object (see L<FS::cust_main>)
+
+=item prospect_main
+
+Prospect object (see L<FS::prospect_main>)
+
+=back
+
+=cut
+
+sub label_prefix {
+  my( $self, %opt ) = @_;
+
   my $cust_or_prospect = $opt{cust_main} || $opt{prospect_main};
   unless ( $cust_or_prospect ) {
     if ( $self->custnum ) {
   my $cust_or_prospect = $opt{cust_main} || $opt{prospect_main};
   unless ( $cust_or_prospect ) {
     if ( $self->custnum ) {
@@ -633,14 +681,16 @@ sub location_label {
         ($agent =~ /^(..)/),
         sprintf('%05d', $self->locationnum)
     ) );
         ($agent =~ /^(..)/),
         sprintf('%05d', $self->locationnum)
     ) );
-  }
-  elsif (    ( $opt{'cust_main'} || $self->custnum )
+
+  } elsif ( $label_prefix eq '_location' && $self->locationname ) {
+    $prefix = $self->locationname;
+
+  } elsif (    ( $opt{'cust_main'} || $self->custnum )
           && $self->locationnum == $cust_or_prospect->ship_locationnum ) {
     $prefix = 'Default service location';
   }
 
           && $self->locationnum == $cust_or_prospect->ship_locationnum ) {
     $prefix = 'Default service location';
   }
 
-  $prefix .= ($opt{join_string} ||  ': ') if $prefix;
-  $prefix . $self->SUPER::location_label(%opt);
+  $prefix;
 }
 
 =item county_state_county
 }
 
 =item county_state_county
index c0d8dbe..57abc18 100644 (file)
@@ -2092,6 +2092,7 @@ Returns a list of fields which have ship_ duplicates.
 
 sub addr_fields {
   qw( last first company
 
 sub addr_fields {
   qw( last first company
+      locationname
       address1 address2 city county state zip country
       latitude longitude
       daytime night fax mobile
       address1 address2 city county state zip country
       latitude longitude
       daytime night fax mobile
index 095bbe7..9f38297 100644 (file)
@@ -17,10 +17,12 @@ BEGIN {
   # set up accessors for location fields
   if (!$init) {
     no strict 'refs';
   # set up accessors for location fields
   if (!$init) {
     no strict 'refs';
-    @location_fields = 
-      qw( address1 address2 city county state zip country district
-        latitude longitude coord_auto censustract censusyear geocode
-        addr_clean );
+    @location_fields = qw(
+      locationname
+      address1 address2 city county state zip country
+      district latitude longitude coord_auto censustract censusyear geocode
+      addr_clean
+    );
 
     foreach my $f (@location_fields) {
       *{"FS::cust_main::Location::$f"} = sub {
 
     foreach my $f (@location_fields) {
       *{"FS::cust_main::Location::$f"} = sub {
index 35de6cf..795242d 100644 (file)
           $OUT .= '<p class="allcaps"><b>';
           my $sectionhead;
           if ( $section->{'location'} ) {
           $OUT .= '<p class="allcaps"><b>';
           my $sectionhead;
           if ( $section->{'location'} ) {
+            $sectionhead .= $section->{'location'}{'label_prefix'}. ': '.
+              if length($section->{'location'}{'label_prefix'});
             $sectionhead = $section->{'location'}{'address1'};
             $sectionhead .= ', '.$section->{'location'}{'address2'}
               if length($section->{'location'}{'address2'});
             $sectionhead = $section->{'location'}{'address1'};
             $sectionhead .= ', '.$section->{'location'}{'address2'}
               if length($section->{'location'}{'address2'});
index 70b36b1..6a5b53d 100644 (file)
       $OUT .= '\begin{longtable}{cllllllr}';\r
       $OUT .= '\caption*{ ';\r
       if ($section->{'location'}) {\r
       $OUT .= '\begin{longtable}{cllllllr}';\r
       $OUT .= '\caption*{ ';\r
       if ($section->{'location'}) {\r
+        $OUT .= $section->{'location'}{'label_prefix'}. ': '\r
+          if length($section->{'location'}{'label_prefix'});\r
         $OUT .= $section->{'location'}{'address1'};\r
         $OUT .= ', ' . $section->{'location'}{'address2'}\r
           if length($section->{'location'}{'address2'});\r
         $OUT .= $section->{'location'}{'address1'};\r
         $OUT .= ', ' . $section->{'location'}{'address2'}\r
           if length($section->{'location'}{'address2'});\r
index f3fde53..41dd563 100644 (file)
 
 
   var ship_locked_agents = <% encode_json(\%ship_locked_agents) %>;
 
 
   var ship_locked_agents = <% encode_json(\%ship_locked_agents) %>;
-  var ship_fields = ['address1', 'city', 'state', 'zip', 'country', 
-    'latitude', 'longitude', 'district'];
+  var ship_fields = [
+    'locationname', 'address1', 'city', 'state', 'zip', 'country', 
+    'latitude', 'longitude', 'district'
+  ];
 
   function agent_changed(what) {
     var agentnum = what.value;
 
   function agent_changed(what) {
     var agentnum = what.value;
@@ -270,7 +272,7 @@ foreach (qsearch('agent',{})) {
   my $agent_ship_location = $cust_main->ship_location;
   $ship_locked_agents{$agentnum} = +{
     map { $_ => $agent_ship_location->$_ }
   my $agent_ship_location = $cust_main->ship_location;
   $ship_locked_agents{$agentnum} = +{
     map { $_ => $agent_ship_location->$_ }
-    qw(address1 city state zip country latitude longitude district)
+    qw(locationname address1 city state zip country latitude longitude district)
   };
 }
 
   };
 }
 
index 799531e..5cdc424 100644 (file)
@@ -41,6 +41,33 @@ Example:
 
 % } 
 
 
 % } 
 
+% if ( $label_prefix eq '_location' ) {
+
+    <TR>
+      <TD ALIGN="right" ><% $opt{'locationname_label'} || emt('Location ID') %></TD>
+      <TD COLSPAN=7>
+        <INPUT TYPE     = "text"
+               NAME     = "<%$pre%>locationname"
+               ID       = "<%$pre%>locationname"
+               VALUE    = "<% $object->get('locationname') |h %>"
+               SIZE     = 24
+               onChange = "<% $onchange %>"
+               <% $disabled %>
+               <% $style %>
+        >
+      </TD>
+    </TR>
+
+% } else {
+
+    <INPUT TYPE     = "hidden"
+           NAME     = "<%$pre%>locationname"
+           ID       = "<%$pre%>locationname"
+           VALUE    = "<% $object->get('locationname') |h %>"
+    >
+
+% }
+
 <TR>
   <<%$th%> STYLE="width:16ex" ALIGN="right"><%$r%><% $opt{'address1_label'} || emt('Address') %></<%$th%>>
   <TD COLSPAN=7>
 <TR>
   <<%$th%> STYLE="width:16ex" ALIGN="right"><%$r%><% $opt{'address1_label'} || emt('Address') %></<%$th%>>
   <TD COLSPAN=7>
@@ -291,13 +318,14 @@ my $object   = $opt{'object'};
 my $onchange = $opt{'onchange'};
 my $disabled = $opt{'disabled'};
 
 my $onchange = $opt{'onchange'};
 my $disabled = $opt{'disabled'};
 
-my $conf = new FS::Conf;
-
 my $r = $opt{'no_asterisks'} ? '' : qq!<font color="#ff0000">*</font>&nbsp;!;
 
 my $r = $opt{'no_asterisks'} ? '' : qq!<font color="#ff0000">*</font>&nbsp;!;
 
+my $conf = new FS::Conf;
 my $countrydefault = $conf->config('countrydefault') || 'US';
 my $countrydefault = $conf->config('countrydefault') || 'US';
-my $statedefault = $conf->config('statedefault') 
-                   || ($countrydefault eq 'US' ? 'CA' : '');
+my $statedefault   = $conf->config('statedefault') 
+                       || ($countrydefault eq 'US' ? 'CA' : '');
+my $label_prefix   = $conf->config('cust_location-label_prefix');
+
 $object ||= FS::cust_location->new({
   'country' => $countrydefault,
   'state'   => $statedefault,
 $object ||= FS::cust_location->new({
   'country' => $countrydefault,
   'state'   => $statedefault,
index dbc491a..5b61e74 100644 (file)
 %   }
 % }
 % # now the actual address
 %   }
 % }
 % # now the actual address
+
+% if ( $location->locationname ) {
+    <TR>
+      <TD ALIGN="right"><% mt('Location ID') |h %></TD>
+      <TD COLSPAN=7 BGCOLOR="#ffffff"><% $location->locationname |h %></TD>
+    </TR>
+% }
+
 <TR>
   <TD ALIGN="right"><% mt('Address') |h %></TD>
   <TD COLSPAN=7 BGCOLOR="#ffffff"><% $location->address1 |h %></TD>
 <TR>
   <TD ALIGN="right"><% mt('Address') |h %></TD>
   <TD COLSPAN=7 BGCOLOR="#ffffff"><% $location->address1 |h %></TD>