[freeside-commits] branch master updated. 376794a00e837317e35fefd61a29ab58c0303b35

Ivan ivan at 420.am
Mon Sep 21 02:02:15 PDT 2015


The branch, master has been updated
       via  376794a00e837317e35fefd61a29ab58c0303b35 (commit)
      from  94ab54acc7f6941d9ed02f2ad5d7b63f1d2f6b60 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 376794a00e837317e35fefd61a29ab58c0303b35
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Sep 21 02:02:13 2015 -0700

    billing event to call web services, RT#35167

diff --git a/FS/FS/Misc/DateTime.pm b/FS/FS/Misc/DateTime.pm
index 2fff906..56baec3 100644
--- a/FS/FS/Misc/DateTime.pm
+++ b/FS/FS/Misc/DateTime.pm
@@ -6,9 +6,10 @@ use Carp;
 use Time::Local;
 use Date::Parse;
 use DateTime::Format::Natural;
+use Date::Format;
 use FS::Conf;
 
- at EXPORT_OK = qw( parse_datetime day_end );
+ at EXPORT_OK = qw( parse_datetime day_end iso8601 );
 
 =head1 NAME
 
@@ -65,11 +66,22 @@ same date but 23:59:59 for the time.
 =cut
 
 sub day_end {
-    my $time = shift;
+  my $time = shift;
 
-    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
-        localtime($time);
-    timelocal(59,59,23,$mday,$mon,$year);
+  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
+      localtime($time);
+  timelocal(59,59,23,$mday,$mon,$year);
+}
+
+=item iso8601 TIME
+
+Parses time as an integer UNIX timestamp and returns the ISO 8601 formatted
+date and time.
+
+=cut
+
+sub iso8601 {
+  time2str('%Y-%m-%dT%T', @_);
 }
 
 =back
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 59d7774..cb39d43 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -409,6 +409,22 @@ sub insert {
     warn "can't send payment receipt/statement: $error" if $error;
   }
 
+  #run payment events immediately
+  my $due_cust_event = $self->cust_main->due_cust_event(
+    'eventtable'  => 'cust_pay',
+    'objects'     => [ $self ],
+  );
+  if ( !ref($due_cust_event) ) {
+    warn "Error searching for cust_pay billing events: $due_cust_event\n";
+  } else {
+    foreach my $cust_event (@$due_cust_event) {
+      next unless $cust_event->test_conditions;
+      if ( my $error = $cust_event->do_event() ) {
+        warn "Error running cust_pay billing event: $error\n";
+      }
+    }
+  }
+
   '';
 
 }
diff --git a/FS/FS/part_event.pm b/FS/FS/part_event.pm
index d15f35b..9a1144c 100644
--- a/FS/FS/part_event.pm
+++ b/FS/FS/part_event.pm
@@ -369,6 +369,7 @@ sub eventtable_labels {
     'cust_pkg'       => 'Package',
     'cust_bill'      => 'Invoice',
     'cust_main'      => 'Customer',
+    'cust_pay'       => 'Payment',
     'cust_pay_batch' => 'Batch payment',
     'cust_statement' => 'Statement',  #too general a name here? "Invoice group"?
     'svc_acct'       => 'Login service',
@@ -408,6 +409,7 @@ sub eventtable_pkey {
     'cust_main'      => 'custnum',
     'cust_bill'      => 'invnum',
     'cust_pkg'       => 'pkgnum',
+    'cust_pay'       => 'paynum',
     'cust_pay_batch' => 'paybatchnum',
     'cust_statement' => 'statementnum',
     'svc_acct'       => 'svcnum',
diff --git a/FS/FS/part_event/Action/http.pm b/FS/FS/part_event/Action/http.pm
new file mode 100644
index 0000000..b8715a7
--- /dev/null
+++ b/FS/FS/part_event/Action/http.pm
@@ -0,0 +1,85 @@
+package FS::part_event::Action::http;
+
+use strict;
+use base qw( FS::part_event::Action );
+use LWP::UserAgent;
+use HTTP::Request::Common;
+use JSON::XS;
+use FS::Misc::DateTime qw( iso8601 );
+
+#sub description { 'Send an HTTP or HTTPS GET or POST request'; }
+sub description { 'Send an HTTP or HTTPS POST request'; }
+
+sub eventtable_hashref {
+  { 'cust_bill' => 1,
+    'cust_pay'  => 1,
+  },
+}
+
+sub option_fields {
+  (
+    'method'        => { label => 'Method',
+                         type  => 'select',
+                         options => [qw( POST )], #GET )],
+                       },
+    'url'           => { label => 'URL',
+                         type  => 'text',
+                         size  => 120,
+                       },
+    'ssl_no_verify' => { label => 'Skip SSL certificate validation',
+                         type  => 'checkbox',
+                       },
+    'encoding'      => { label => 'Encoding',
+                         type  => 'select',
+                         options => [qw( JSON )], #XML, Form, etc.
+                       },
+    'content'       => { label => 'Content', #nneed better inline docs on format
+                         type  => 'textarea',
+                       },
+    #'response_error_param' => 'Response error parameter',
+  );
+}
+
+sub default_weight { 57; }
+
+our %content_type = (
+  'JSON' => 'application/json',
+);
+
+sub do_action {
+  my( $self, $object ) = @_;
+
+  my $cust_main = $self->cust_main($object);
+
+  my %content =
+    map {
+      /^\s*(\S+)\s+(.*)$/ or /()()/;
+      my( $field, $value_expression ) = ( $1, $2 );
+      my $value = eval $value_expression;
+      die $@ if $@;
+      ( $field, $value );
+    } split(/\n/, $self->option('content') );
+
+  my $content = encode_json( \%content );
+
+  my @lwp_opts = ();
+  push @lwp_opts, 'ssl_opts'=>{ 'verify_hostname'=>0 }
+    if $self->option('ssl_no_verify');
+  my $ua = LWP::UserAgent->new(@lwp_opts);
+
+  my $req = HTTP::Request::Common::POST(
+    $self->option('url'),
+    Content_Type => $content_type{ $self->option('encoding') },
+    Content      => $content,
+  );
+
+  my $response = $ua->request($req);
+
+  die $response->status_line if $response->is_error;
+
+  my $response_json = decode_json( $response->content );
+  die $response_json->{error} if $response_json->{error}; #XXX response_error_param
+
+}
+
+1;
diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm
index 60697c1..36fbe9a 100644
--- a/FS/FS/part_event/Condition.pm
+++ b/FS/FS/part_event/Condition.pm
@@ -52,6 +52,7 @@ sub eventtable_hashref {
     { 'cust_main'      => 1,
       'cust_bill'      => 1,
       'cust_pkg'       => 1,
+      'cust_pay'       => 1,
       'cust_pay_batch' => 1,
       'cust_statement' => 1,
       'svc_acct'       => 1,
diff --git a/FS/FS/part_event_option.pm b/FS/FS/part_event_option.pm
index 09b7756..6df9e84 100644
--- a/FS/FS/part_event_option.pm
+++ b/FS/FS/part_event_option.pm
@@ -183,7 +183,8 @@ sub check {
     $self->ut_numbern('optionnum')
     || $self->ut_foreign_key('eventpart', 'part_event', 'eventpart' )
     || $self->ut_text('optionname')
-    || $self->ut_textn('optionvalue')
+    #|| $self->ut_textn('optionvalue')
+    || $self->ut_anything('optionvalue') #http.pm content has \n
   ;
   return $error if $error;
 

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Misc/DateTime.pm          |   22 +++++++---
 FS/FS/cust_pay.pm               |   16 ++++++++
 FS/FS/part_event.pm             |    2 +
 FS/FS/part_event/Action/http.pm |   85 +++++++++++++++++++++++++++++++++++++++
 FS/FS/part_event/Condition.pm   |    1 +
 FS/FS/part_event_option.pm      |    3 +-
 6 files changed, 123 insertions(+), 6 deletions(-)
 create mode 100644 FS/FS/part_event/Action/http.pm




More information about the freeside-commits mailing list