From: Jonathan Prykop Date: Thu, 21 Apr 2016 00:48:53 +0000 (-0500) Subject: RT#29296: API stuff: Add new locations [v3 reconcile] X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=645a1c856120171b58bfb3eb5f326c06a9c49825 RT#29296: API stuff: Add new locations [v3 reconcile] --- diff --git a/FS/FS/API.pm b/FS/FS/API.pm index 5db29b2b5..4e6cb6cd7 100644 --- a/FS/FS/API.pm +++ b/FS/FS/API.pm @@ -755,6 +755,8 @@ secret locationnum - pass this, or the following keys (don't pass both) +locationname + address1 address2 @@ -767,8 +769,22 @@ state zip +addr_clean + country +censustract + +censusyear + +location_type + +location_number + +location_kind + +incorporated + On error, returns a hashref with an 'error' key. On success, returns a hashref with 'pkgnum' and 'locationnum' keys, containing the new values. @@ -785,7 +801,24 @@ sub change_package_location { my %changeopt; - foreach my $field ('locationnum',FS::cust_location::API::API_editable_fields()) { + foreach my $field ( qw( + locationnum + locationname + address1 + address2 + city + county + state + zip + addr_clean + country + censustract + censusyear + location_type + location_number + location_kind + incorporated + )) { $changeopt{$field} = $opt{$field} if $opt{$field}; } diff --git a/FS/FS/cust_location/API.pm b/FS/FS/cust_location/API.pm deleted file mode 100644 index 7d9140fbe..000000000 --- a/FS/FS/cust_location/API.pm +++ /dev/null @@ -1,34 +0,0 @@ -package FS::cust_location::API; - -use strict; - -# this gets used by FS::cust_main::API and FS::cust_pkg::API, -# so don't use FS::cust_main or FS::cust_pkg here - -# some of these could probably be included, but in general, -# probably a bad idea to expose everything in -# cust_main::Location::location_fields by default -# -#locationname -#district -#latitude -#longitude -#censustract -#censusyear -#geocode -#coord_auto -#addr_clean - -sub API_editable_fields { - return qw( - address1 - address2 - city - county - state - zip - country - ); -} - -1; diff --git a/FS/FS/cust_pkg/API.pm b/FS/FS/cust_pkg/API.pm index 7ef3f7246..837cf40cc 100644 --- a/FS/FS/cust_pkg/API.pm +++ b/FS/FS/cust_pkg/API.pm @@ -2,8 +2,6 @@ package FS::cust_pkg::API; use strict; -use FS::cust_location::API; - sub API_getinfo { my $self = shift; @@ -25,7 +23,23 @@ sub API_change { # update location--accepts raw fields OR location my %location_hash; - foreach my $field (FS::cust_location::API::API_editable_fields()) { + foreach my $field ( qw( + locationname + address1 + address2 + city + county + state + zip + addr_clean + country + censustract + censusyear + location_type + location_number + location_kind + incorporated + ) ) { $location_hash{$field} = $opt{$field} if $opt{$field}; } return { 'error' => 'Cannot pass both locationnum and location fields' } diff --git a/FS/FS/part_export/cust_http.pm b/FS/FS/part_export/cust_http.pm index f72d00698..c13e18db1 100644 --- a/FS/FS/part_export/cust_http.pm +++ b/FS/FS/part_export/cust_http.pm @@ -55,7 +55,7 @@ tie %options, 'Tie::IxHash', ; %info = ( - 'svc' => [qw( cust_main cust_location )], + 'svc' => [qw( cust_main )], 'desc' => 'Send an HTTP or HTTPS GET or POST request, for customers.', 'options' => \%options, 'no_machine' => 1, diff --git a/FS/FS/part_export/cust_location_http.pm b/FS/FS/part_export/cust_location_http.pm index e2830db74..fe7722340 100644 --- a/FS/FS/part_export/cust_location_http.pm +++ b/FS/FS/part_export/cust_location_http.pm @@ -4,9 +4,28 @@ use strict; use base qw( FS::part_export::http ); use vars qw( %options %info ); -use FS::cust_main::Location; - -my @location_fields = ( qw( custnum prospectnum ), FS::cust_main::Location->location_fields ); +my @location_fields = qw( + custnum + prospectnum + locationname + address1 + address2 + city + county + state + zip + country + latitude + longitude + censustract + censusyear + district + geocode + location_type + location_number + location_kind + incorporated +); tie %options, 'Tie::IxHash', 'method' => { label =>'Method', @@ -23,6 +42,10 @@ tie %options, 'Tie::IxHash', 'type' => 'select', 'multiple' => 1, 'options' => [ @location_fields ] }, + 'location_data' => { 'label' => 'Location data', + 'type' => 'textarea' }, + 'package_data' => { 'label' => 'Package data', + 'type' => 'textarea' }, 'success_regexp' => { label => 'Success Regexp', default => '', @@ -37,10 +60,16 @@ tie %options, 'Tie::IxHash', 'notes' => <<'END', 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. +Leave a URL blank to skip that action. +Always sends locationnum, action, and fields specified in the export options. +Action 'package' also sends pkgnum and change_pkgnum (the previous pkgnum, +because location changes usually instigate a pkgnum change.) +Simple field values can be selected in 'Include fields', and more complex +values can be specified in the data field options as perl code using vars +$cust_location, $cust_main and (where relevant) $cust_pkg. +Action 'location' only sends on update if a specified field changed. +Note that scheduled future package changes are currently sent when the change is scheduled +(this may not be the case in future versions of this export.) For HTTPS support, Crypt::SSLeay or IO::Socket::SSL is required. END @@ -51,11 +80,11 @@ END # 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 +# to the customer--hence we don't distinguish insert 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 ); + my( $self, $action, $cust_location ) = @_; # 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... @@ -63,32 +92,55 @@ sub _export_command { $self->_http_queue_standard( 'action' => 'location', - map { $_ => $cust_location->get($_) } ('locationnum', $self->_include_fields) + (map { $_ => $cust_location->get($_) } ('locationnum', $self->_include_fields)), + $self->_eval_replace('location_data',$cust_location,$cust_location->cust_main), ); } sub _export_replace { - my( $self, $new, $old ) = ( shift, shift, shift ); + my( $self, $new, $old ) = @_; my $changed = 0; + + # even if they don't want custnum/prospectnum exported, + # inserts that lack custnum/prospectnum don't trigger exports, + # so we might not have previously reported these + $changed = 1 if $new->custnum && !$old->custnum; + $changed = 1 if $new->prospectnum && !$old->prospectnum; + foreach my $field ($self->_include_fields) { + last if $changed; next if $new->get($field) eq $old->get($field); next if ($field =~ /latitude|longitude/) and $new->get($field) == $old->get($field); $changed = 1; - last; } + + my %old_eval; + unless ($changed) { + %old_eval = $self->_eval_replace('location_data', $old, $old->cust_main), + } + + my %eval = $self->_eval_replace('location_data', $new, $new->cust_main); + + foreach my $key (keys %eval) { + last if $changed; + next if $eval{$key} eq $old_eval{$key}; + $changed = 1; + } + return '' unless $changed; $self->_http_queue_standard( 'action' => 'location', - map { $_ => $new->get($_) } ('locationnum', $self->_include_fields) + (map { $_ => $new->get($_) } ('locationnum', $self->_include_fields)), + %eval, ); } # not to be confused with export_pkg_change, which is for svcs sub export_pkg_location { - my( $self, $cust_pkg ) = ( shift, shift, shift ); + my ($self, $cust_pkg) = @_; return '' unless $cust_pkg->locationnum; @@ -98,6 +150,7 @@ sub export_pkg_location { 'action' => 'package', (map { $_ => $cust_pkg->get($_) } ('pkgnum', 'change_pkgnum', 'locationnum')), (map { $_ => $cust_location->get($_) } $self->_include_fields), + $self->_eval_replace('package_data',$cust_location,$cust_pkg->cust_main,$cust_pkg), ); } @@ -128,4 +181,16 @@ sub _include_fields { split( /\s+/, $self->option('include_fields') ); } +sub _eval_replace { + my ($self,$option,$cust_location,$cust_main,$cust_pkg) = @_; + return + map { + /^\s*(\S+)\s+(.*)$/ or /()()/; + my( $field, $value_expression ) = ( $1, $2 ); + my $value = eval $value_expression; + die $@ if $@; + ( $field, $value ); + } split(/\n/, $self->option($option) ); +} + 1;