X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_location.pm;h=4f0bd9bbed8fba00385de7e4f007bb2df6f96c4e;hb=622c72770c971ae44d37dfb59a0f25972051a25a;hp=51fcba35b34a5c1bb3d3c283532c68b547b5d98b;hpb=7d26901e658bd61078f10c0713676f94375f3283;p=freeside.git diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index 51fcba35b..4f0bd9bbe 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -12,6 +12,7 @@ use FS::Conf; use FS::prospect_main; use FS::cust_main; use FS::cust_main_county; +use FS::part_export; use FS::GeocodeCache; $import = 0; @@ -67,7 +68,7 @@ Address line two (optional) =item city -City +City (optional only if cust_main-no_city_in_address config is set) =item county @@ -143,9 +144,20 @@ sub find_or_insert { warn "find_or_insert:\n".Dumper($self) if $DEBUG; - my @essential = (qw(custnum address1 address2 city county state zip country + my @essential = (qw(custnum address1 address2 county state zip country location_number location_type location_kind disabled)); + # Just in case this conf was accidentally/temporarily set, + # we'll never overwrite existing city; see city method + if ($conf->exists('cust_main-no_city_in_address')) { + warn "Warning: find_or_insert specified city when cust_main-no_city_in_address was configured" + if $self->get('city'); + $self->set('city',''); # won't end up in %nonempty, hence old value is preserved + } else { + # otherwise, of course, city is essential + push(@essential,'city') + } + # I don't think this is necessary #if ( !$self->coord_auto and $self->latitude and $self->longitude ) { # push @essential, qw(latitude longitude); @@ -201,23 +213,58 @@ otherwise returns false. sub insert { my $self = shift; + # Ideally, this should never happen, + # but throw a warning and save the value anyway, to avoid data loss + warn "Warning: inserting city when cust_main-no_city_in_address is configured" + if $conf->exists('cust_main-no_city_in_address') && $self->get('city'); + if ( $self->censustract ) { $self->set('censusyear' => $conf->config('census_year') || 2012); } + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + my $error = $self->SUPER::insert(@_); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } #false laziness with cust_main, will go away eventually - if ( !$import and !$error and $conf->config('tax_district_method') ) { + if ( !$import and $conf->config('tax_district_method') ) { my $queue = new FS::queue { 'job' => 'FS::geocode_Mixin::process_district_update' }; $error = $queue->insert( ref($self), $self->locationnum ); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + } + + # cust_location exports + #my $export_args = $options{'export_args'} || []; + + my @part_export = + map qsearch( 'part_export', {exportnum=>$_} ), + $conf->config('cust_location-exports'); #, $agentnum + foreach my $part_export ( @part_export ) { + my $error = $part_export->export_insert($self); #, @$export_args); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "exporting to ". $part_export->exporttype. + " (transaction rolled back): $error"; + } } - $error || ''; + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; } =item delete @@ -235,6 +282,15 @@ sub replace { my $self = shift; my $old = shift; $old ||= $self->replace_old; + + # Just in case this conf was accidentally/temporarily set, + # we'll never overwrite existing city; see city method + if ($conf->exists('cust_main-no_city_in_address')) { + warn "Warning: replace attempted to change city when cust_main-no_city_in_address was configured" + if $self->get('city') && ($old->get('city') != $self->get('city')); + $self->set('city',$old->get('city')); + } + # the following fields are immutable foreach (qw(address1 address2 city state zip country)) { if ( $self->$_ ne $old->$_ ) { @@ -242,7 +298,35 @@ sub replace { } } - $self->SUPER::replace($old); + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = $self->SUPER::replace($old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + # cust_location exports + #my $export_args = $options{'export_args'} || []; + + my @part_export = + map qsearch( 'part_export', {exportnum=>$_} ), + $conf->config('cust_location-exports'); #, $agentnum + + foreach my $part_export ( @part_export ) { + my $error = $part_export->export_replace($self, $old); #, @$export_args); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "exporting to ". $part_export->exporttype. + " (transaction rolled back): $error"; + } + } + + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; } @@ -263,9 +347,12 @@ sub check { $self->ut_numbern('locationnum') || $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum') || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum') + || $self->ut_textn('locationname') || $self->ut_text('address1') || $self->ut_textn('address2') - || $self->ut_text('city') + || ($conf->exists('cust_main-no_city_in_address') + ? $self->ut_textn('city') + : $self->ut_text('city')) || $self->ut_textn('county') || $self->ut_textn('state') || $self->ut_country('country') @@ -326,6 +413,30 @@ sub check { $self->SUPER::check; } +=item city + +When the I config is set, the +city method will return a blank string no matter the previously +set value of the field. You can still use the get method to +access the contents of the field directly. + +Just in case this config was accidentally/temporarily set, +we'll never overwrite existing city while the config is active. +L will throw a warning if passed any true value for city, +ignore the city field when finding, and preserve the existing value. +L will only throw a warning if passed a true value that is +different than the existing value of city, and will preserve the existing value. +L will throw a warning but still insert a true city value, +to avoid unnecessary data loss. + +=cut + +sub city { + my $self = shift; + return '' if $conf->exists('cust_main-no_city_in_address'); + return $self->get('city'); +} + =item country_full Returns this locations's full country name @@ -379,8 +490,8 @@ sub disable_if_unused { my $self = shift; my $locationnum = $self->locationnum; - return '' if FS::cust_main->count('bill_locationnum = '.$locationnum) - or FS::cust_main->count('ship_locationnum = '.$locationnum) + return '' if FS::cust_main->count('bill_locationnum = '.$locationnum.' OR + ship_locationnum = '.$locationnum) or FS::contact->count( 'locationnum = '.$locationnum) or FS::cust_pkg->count('cancel IS NULL AND locationnum = '.$locationnum) @@ -545,14 +656,61 @@ sub dealternize { =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) + +=item prospect_main + +Prospect object (see L) + +=item join_string + +String used to join location elements + +=back =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) + +=item prospect_main + +Prospect object (see L) + +=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 ) { @@ -574,14 +732,16 @@ sub location_label { ($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'; } - $prefix .= ($opt{join_string} || ': ') if $prefix; - $prefix . $self->SUPER::location_label(%opt); + $prefix; } =item county_state_county @@ -598,6 +758,16 @@ sub county_state_country { $label; } +=item cust_main + +=cut + +sub cust_main { + my $self = shift; + return '' unless $self->custnum; + qsearchs('cust_main', { 'custnum' => $self->custnum } ); +} + =back =head1 CLASS METHODS @@ -616,25 +786,29 @@ names in order. =cut +### Is this actually used for anything anymore? Grep doesn't show anything... sub in_county_sql { # replaces FS::cust_pkg::location_sql my ($class, %opt) = @_; my $ornull = $opt{ornull} ? ' OR ? IS NULL' : ''; my $x = $ornull ? 3 : 2; my @fields = (('district') x 3, - ('city') x 3, ('county') x $x, ('state') x $x, 'country'); + unless ($conf->exists('cust_main-no_city_in_address')) { + push( @fields, (('city') x 3) ); + } + my $text = (driver_name =~ /^mysql/i) ? 'char' : 'text'; my @where = ( "cust_location.district = ? OR ? = '' OR CAST(? AS $text) IS NULL", - "cust_location.city = ? OR ? = '' OR CAST(? AS $text) IS NULL", "cust_location.county = ? OR (? = '' AND cust_location.county IS NULL) $ornull", "cust_location.state = ? OR (? = '' AND cust_location.state IS NULL ) $ornull", - "cust_location.country = ?" + "cust_location.country = ?", + "cust_location.city = ? OR ? = '' OR CAST(? AS $text) IS NULL" ); my $sql = join(' AND ', map "($_)\n", @where); if ( $opt{param} ) {