[freeside-commits] branch FREESIDE_3_BRANCH updated. 38472d1494a3c0e7c39ba7433a23de25159350d7

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


The branch, FREESIDE_3_BRANCH has been updated
       via  38472d1494a3c0e7c39ba7433a23de25159350d7 (commit)
      from  1f0d6d4ce0c0dd6fffb87d5ead4a6843e671c792 (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 38472d1494a3c0e7c39ba7433a23de25159350d7
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Mon Sep 21 02:02:25 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 424fab0..9e0e687 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -396,6 +396,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 69725b0..62d96f9 100644
--- a/FS/FS/part_event.pm
+++ b/FS/FS/part_event.pm
@@ -384,6 +384,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',
@@ -423,6 +424,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