diff options
| -rw-r--r-- | FS/FS/Conf.pm | 6 | ||||
| -rw-r--r-- | FS/FS/cust_location.pm | 48 | ||||
| -rw-r--r-- | FS/FS/cust_pkg.pm | 33 | ||||
| -rw-r--r-- | FS/FS/part_export/cust_location_http.pm | 120 | 
4 files changed, 132 insertions, 75 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 691097784..6042cae04 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5584,7 +5584,7 @@ and customer address. Include units.',        my @part_export =          map { qsearch( 'part_export', {exporttype => $_ } ) }            keys %{FS::part_export::export_info('cust_main')}; -      map { $_->exportnum => $_->exporttype.' to '.$_->machine } @part_export; +      map { $_->exportnum => $_->exportname } @part_export;      },      'option_sub'  => sub {        require FS::Record; @@ -5593,7 +5593,7 @@ and customer address. Include units.',          'part_export', { 'exportnum' => shift }        );        $part_export -        ? $part_export->exporttype.' to '.$part_export->machine +        ? $part_export->exportname          : '';      },    }, @@ -5602,7 +5602,7 @@ and customer address. Include units.',    {      'key'         => 'cust_location-exports',      'section'     => '', -    'description' => 'Export(s) to call on cust_location insert, modification and deletion.', +    'description' => 'Export(s) to call on cust_location insert or modification',      'type'        => 'select-sub',      'multiple'    => 1,      'options_sub' => sub { diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm index aad25a4a7..2736b5067 100644 --- a/FS/FS/cust_location.pm +++ b/FS/FS/cust_location.pm @@ -244,20 +244,22 @@ sub insert {    # 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"; +  # don't export custnum_pending cases, let follow-up replace handle that +  if ($self->custnum || $self->prospectnum) { +    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"; +      }      }    } -    $dbh->commit or die $dbh->errstr if $oldAutoCommit;    '';  } @@ -306,20 +308,22 @@ sub replace {    # 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"; +  # don't export custnum_pending cases, let follow-up replace handle that +  if ($self->custnum || $self->prospectnum) { +    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;    '';  } diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index 140f961cc..876a6255c 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -397,6 +397,21 @@ sub insert {    my $conf = new FS::Conf; +  if ($self->locationnum) { +    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_pkg_location($self); #, @$export_args); +      if ( $error ) { +        $dbh->rollback if $oldAutoCommit; +        return "exporting to ". $part_export->exporttype. +               " (transaction rolled back): $error"; +      } +    } +  } +    if ( $conf->config('ticket_system') && $options{ticket_subject} ) {      #this init stuff is still inefficient, but at least its limited to  @@ -642,6 +657,24 @@ sub replace {      }    } +  # also run exports if removing locationnum? +  #   doesn't seem to happen, and we don't export blank locationnum on insert... +  if ($new->locationnum and ($new->locationnum != $old->locationnum)) { +    my $conf = new FS::Conf; +    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_pkg_location($new); #, @$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;    ''; diff --git a/FS/FS/part_export/cust_location_http.pm b/FS/FS/part_export/cust_location_http.pm index 460080c74..e2830db74 100644 --- a/FS/FS/part_export/cust_location_http.pm +++ b/FS/FS/part_export/cust_location_http.pm @@ -4,27 +4,9 @@ use strict;  use base qw( FS::part_export::http );  use vars qw( %options %info ); -my @location_fields = qw( -  custnum -  address1 -  address2 -  city -  state -  zip -  country -  locationname -  county -  latitude -  longitude -  prospectnum -  location_type -  location_number -  location_kind -  geocode -  district -  censusyear -  incorporated -); +use FS::cust_main::Location; + +my @location_fields = ( qw( custnum prospectnum ), FS::cust_main::Location->location_fields );  tie %options, 'Tie::IxHash',    'method' => { label   =>'Method', @@ -32,10 +14,11 @@ tie %options, 'Tie::IxHash',                  #options =>[qw(POST GET)],                  options =>[qw(POST)],                  default =>'POST' }, -  'url'    => { label   => 'URL', default => 'http://', }, -  'ssl_no_verify' => { label => 'Skip SSL certificate validation', -                       type  => 'checkbox', -                     }, +  'location_url'   => { label   => 'Location URL' }, +  'package_url'    => { label   => 'Package URL' }, +  'ssl_no_verify'  => { label => 'Skip SSL certificate validation', +                        type  => 'checkbox', +                      },    'include_fields' => { 'label' => 'Include fields',                          'type'  => 'select',                          'multiple' => 1, @@ -52,45 +35,39 @@ tie %options, 'Tie::IxHash',    'options' => \%options,    'no_machine' => 1,    'notes'   => <<'END', -Send an HTTP or HTTPS GET or POST to the specified URL on customer location insert -or replace.  Always sends cgi fields action ('insert' or 'replace') and locationnum, -as well as any fields specified below.  Only sends on replace if one of the -specified fields changed. +Send an HTTP or HTTPS GET or POST to the specified URLs on customer location +creation/update (action 'location') and package location assignment/change (action 'package'). +Always sends locationnum, action and any fields specified in the 'Include fields'  +export option.  Action 'package' also sends pkgnum and old_pkgnum (because location +changes usually instigate a pkgnum change.)  Action 'location' only sends on replace  +if one of the specified fields changed.  Leave a URL blank to skip that action.  For HTTPS support, <a href="http://search.cpan.org/dist/Crypt-SSLeay">Crypt::SSLeay</a>  or <a href="http://search.cpan.org/dist/IO-Socket-SSL">IO::Socket::SSL</a> is required.  END  ); -sub http_queue_standard { -  my $self = shift; -  $self->http_queue( '', -    ( $self->option('ssl_no_verify') ? 'ssl_no_verify' : '' ), -    $self->option('method'), -    $self->option('url'), -    $self->option('success_regexp'), -    @_ -  ); -} - -sub _include_fields { -  my $self = shift; -  split( /\s+/, $self->option('include_fields') ); -} +# we don't do anything on deletion because we generally don't delete locations +# +# we don't send blank custnum/prospectnum because we do a lot of inserting/replacing  +#   with blank values and then immediately overwriting, but that unfortunately +#   makes it difficult to indicate if this is the first time we've sent the location +#   to the customer--hence we don't distinguish creation from update in the cgi vars +# gets invoked by FS::part_export::http _export_insert  sub _export_command {    my( $self, $action, $cust_location ) = ( shift, shift, shift ); +  # redundant--cust_location exports don't get invoked by cust_location->delete, +  # or by any status trigger, but just to be clear, since http export has other actions...    return '' unless $action eq 'insert'; -  $self->http_queue_standard( -    'action' => $action, +  $self->_http_queue_standard( +    'action' => 'location',      map { $_ => $cust_location->get($_) } ('locationnum', $self->_include_fields)    );  } -# currently, only custnum can change (when converting prospect to customer) -# but using more generic logic for ease of adding other changeable fields  sub _export_replace {    my( $self, $new, $old ) = ( shift, shift, shift ); @@ -99,13 +76,56 @@ sub _export_replace {      next if $new->get($field) eq $old->get($field);      next if ($field =~ /latitude|longitude/) and $new->get($field) == $old->get($field);      $changed = 1; +    last;    }    return '' unless $changed; -  $self->http_queue_standard( -    'action' => 'replace', +  $self->_http_queue_standard( +    'action' => 'location',      map { $_ => $new->get($_) } ('locationnum', $self->_include_fields)    );  } +# not to be confused with export_pkg_change, which is for svcs +sub export_pkg_location { +  my( $self, $cust_pkg ) = ( shift, shift, shift ); + +  return '' unless $cust_pkg->locationnum; + +  my $cust_location = $cust_pkg->cust_location; + +  $self->_http_queue_standard( +    'action' => 'package', +    (map { $_ => $cust_pkg->get($_) } ('pkgnum', 'change_pkgnum', 'locationnum')), +    (map { $_ => $cust_location->get($_) } $self->_include_fields), +  ); +} + +sub _http_queue_standard { +  my $self = shift; +  my %opts = @_; +  my $url; +  if ($opts{'action'} eq 'location') { +    $url = $self->option('location_url'); +    return '' unless $url; +  } elsif ($opts{'action'} eq 'package') { +    $url = $self->option('package_url'); +    return '' unless $url; +  } else { +    return "Bad action ".$opts{'action'}; +  } +  $self->http_queue( '', +    ( $self->option('ssl_no_verify') ? 'ssl_no_verify' : '' ), +    $self->option('method'), +    $url, +    $self->option('success_regexp'), +    %opts +  ); +} + +sub _include_fields { +  my $self = shift; +  split( /\s+/, $self->option('include_fields') ); +} +  1;  | 
