e2830db748ff968ca83b75174b242cf736e55bf8
[freeside.git] / FS / FS / part_export / cust_location_http.pm
1 package FS::part_export::cust_location_http;
2
3 use strict;
4 use base qw( FS::part_export::http );
5 use vars qw( %options %info );
6
7 use FS::cust_main::Location;
8
9 my @location_fields = ( qw( custnum prospectnum ), FS::cust_main::Location->location_fields );
10
11 tie %options, 'Tie::IxHash',
12   'method' => { label   =>'Method',
13                 type    =>'select',
14                 #options =>[qw(POST GET)],
15                 options =>[qw(POST)],
16                 default =>'POST' },
17   'location_url'   => { label   => 'Location URL' },
18   'package_url'    => { label   => 'Package URL' },
19   'ssl_no_verify'  => { label => 'Skip SSL certificate validation',
20                         type  => 'checkbox',
21                       },
22   'include_fields' => { 'label' => 'Include fields',
23                         'type'  => 'select',
24                         'multiple' => 1,
25                         'options' => [ @location_fields ] },
26   'success_regexp' => {
27     label  => 'Success Regexp',
28     default => '',
29   },
30 ;
31
32 %info = (
33   'svc'     => [qw( cust_location )],
34   'desc'    => 'Send an HTTP or HTTPS GET or POST request, for customer locations',
35   'options' => \%options,
36   'no_machine' => 1,
37   'notes'   => <<'END',
38 Send an HTTP or HTTPS GET or POST to the specified URLs on customer location
39 creation/update (action 'location') and package location assignment/change (action 'package').
40 Always sends locationnum, action and any fields specified in the 'Include fields' 
41 export option.  Action 'package' also sends pkgnum and old_pkgnum (because location
42 changes usually instigate a pkgnum change.)  Action 'location' only sends on replace 
43 if one of the specified fields changed.  Leave a URL blank to skip that action.
44 For HTTPS support, <a href="http://search.cpan.org/dist/Crypt-SSLeay">Crypt::SSLeay</a>
45 or <a href="http://search.cpan.org/dist/IO-Socket-SSL">IO::Socket::SSL</a> is required.
46 END
47 );
48
49 # we don't do anything on deletion because we generally don't delete locations
50 #
51 # we don't send blank custnum/prospectnum because we do a lot of inserting/replacing 
52 #   with blank values and then immediately overwriting, but that unfortunately
53 #   makes it difficult to indicate if this is the first time we've sent the location
54 #   to the customer--hence we don't distinguish creation from update in the cgi vars
55
56 # gets invoked by FS::part_export::http _export_insert
57 sub _export_command {
58   my( $self, $action, $cust_location ) = ( shift, shift, shift );
59
60   # redundant--cust_location exports don't get invoked by cust_location->delete,
61   # or by any status trigger, but just to be clear, since http export has other actions...
62   return '' unless $action eq 'insert';
63
64   $self->_http_queue_standard(
65     'action' => 'location',
66     map { $_ => $cust_location->get($_) } ('locationnum', $self->_include_fields)
67   );
68
69 }
70
71 sub _export_replace {
72   my( $self, $new, $old ) = ( shift, shift, shift );
73
74   my $changed = 0;
75   foreach my $field ($self->_include_fields) {
76     next if $new->get($field) eq $old->get($field);
77     next if ($field =~ /latitude|longitude/) and $new->get($field) == $old->get($field);
78     $changed = 1;
79     last;
80   }
81   return '' unless $changed;
82
83   $self->_http_queue_standard(
84     'action' => 'location',
85     map { $_ => $new->get($_) } ('locationnum', $self->_include_fields)
86   );
87 }
88
89 # not to be confused with export_pkg_change, which is for svcs
90 sub export_pkg_location {
91   my( $self, $cust_pkg ) = ( shift, shift, shift );
92
93   return '' unless $cust_pkg->locationnum;
94
95   my $cust_location = $cust_pkg->cust_location;
96
97   $self->_http_queue_standard(
98     'action' => 'package',
99     (map { $_ => $cust_pkg->get($_) } ('pkgnum', 'change_pkgnum', 'locationnum')),
100     (map { $_ => $cust_location->get($_) } $self->_include_fields),
101   );
102 }
103
104 sub _http_queue_standard {
105   my $self = shift;
106   my %opts = @_;
107   my $url;
108   if ($opts{'action'} eq 'location') {
109     $url = $self->option('location_url');
110     return '' unless $url;
111   } elsif ($opts{'action'} eq 'package') {
112     $url = $self->option('package_url');
113     return '' unless $url;
114   } else {
115     return "Bad action ".$opts{'action'};
116   }
117   $self->http_queue( '',
118     ( $self->option('ssl_no_verify') ? 'ssl_no_verify' : '' ),
119     $self->option('method'),
120     $url,
121     $self->option('success_regexp'),
122     %opts
123   );
124 }
125
126 sub _include_fields {
127   my $self = shift;
128   split( /\s+/, $self->option('include_fields') );
129 }
130
131 1;