[freeside-commits] branch master updated. 8202103585cb218da090f18a8f0ce71af4bada8e

Ivan ivan at 420.am
Thu Sep 28 20:04:34 PDT 2017


The branch, master has been updated
       via  8202103585cb218da090f18a8f0ce71af4bada8e (commit)
      from  1bc76eeede2fcdea26a9e634409445626f53cdc9 (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 8202103585cb218da090f18a8f0ce71af4bada8e
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Thu Sep 28 20:04:33 2017 -0700

    new backoffice API to add a package, RT#77484

diff --git a/FS/FS/API.pm b/FS/FS/API.pm
index 6e09713..047bb4e 100644
--- a/FS/FS/API.pm
+++ b/FS/FS/API.pm
@@ -1,6 +1,7 @@
 package FS::API;
 
 use strict;
+use Date::Parse;
 use FS::Conf;
 use FS::Record qw( qsearch qsearchs );
 use FS::cust_main;
@@ -649,10 +650,128 @@ sub location_info {
   return \%return;
 }
 
+=item order_package OPTION => VALUE, ...
+
+Orders a new customer package.  Takes a list of keys and values as paramaters
+with the following keys:
+
+=over 4
+
+=item secret
+
+API Secret
+
+=item custnum
+
+=item pkgpart
+
+=item quantity
+
+=item start_date
+
+=item contract_end
+
+=item address1
+
+=item address2
+
+=item city
+
+=item county
+
+=item state
+
+=item zip
+
+=item country
+
+=item setup_fee
+
+Including this implements per-customer custom pricing for this package, overriding package definition pricing
+
+=item recur_fee
+
+Including this implements per-customer custom pricing for this package, overriding package definition pricing
+
+=item invoice_details
+
+A single string for just one detail line, or an array reference of one or more
+lines of detail
+
+=cut
+
+sub order_package {
+  my( $class, %opt ) = @_;
+
+  my $cust_main = qsearchs('cust_main', { 'custnum' => $opt{custnum} })
+    or return { 'error' => 'Unknown custnum' };
+
+  #some conceptual false laziness w/cust_pkg/Import.pm
+
+  my $cust_pkg = new FS::cust_pkg {
+    'pkgpart'    => $opt{'pkgpart'},
+    'quantity'   => $opt{'quantity'} || 1,
+  };
+
+  #start_date and contract_end
+  foreach my $date_field (qw( start_date contract_end )) {
+    if ( $opt{$date_field} =~ /^(\d+)$/ ) {
+      $cust_pkg->$date_field( $opt{$date_field} );
+    } elsif ( $opt{$date_field} ) {
+      $cust_pkg->$date_field( str2time( $opt{$date_field} ) );
+    }
+  }
+
+  #especially this part for custom pkg price
+  # (false laziness w/cust_pkg/Import.pm)
+  my $s = $opt{'setup_fee'};
+  my $r = $opt{'recur_fee'};
+  my $part_pkg = $cust_pkg->part_pkg;
+  if (    ( length($s) && $s != $part_pkg->option('setup_fee') )
+       or ( length($r) && $r != $part_pkg->option('recur_fee') )
+     )
+  {
+    my $custom_part_pkg = $part_pkg->clone;
+    $custom_part_pkg->disabled('Y');
+    my %options = $part_pkg->options;
+    $options{'setup_fee'} = $s if length($s);
+    $options{'recur_fee'} = $r if length($r);
+    my $error = $custom_part_pkg->insert( options=>\%options );
+    return ( 'error' => "error customizing package: $error" ) if $error;
+    $cust_pkg->pkgpart( $custom_part_pkg->pkgpart );
+  }
+
+  my %order_pkg = ( 'cust_pkg' => $cust_pkg );
+
+  my @loc_fields = qw( address1 address2 city county state zip country );
+  if ( grep length($opt{$_}), @loc_fields ) {
+     $order_pkg{'cust_location'} = new FS::cust_location {
+       map { $_ => $opt{$_} } @loc_fields, 'custnum'
+     };
+  }
+
+  $order_pkg{'invoice_details'} = $opt{'invoice_details'}
+    if $opt{'invoice_details'};
+
+  my $error = $cust_main->order_pkg( %order_pkg );
+
+  #if ( $error ) {
+    return { 'error'  => $error,
+             #'pkgnum' => '',
+           };
+  #} else {
+  #  return { 'error'  => '',
+  #           #cust_main->order_pkg doesn't actually have a way to return pkgnum
+  #           #'pkgnum' => $pkgnum,
+  #         };
+  #}
+
+}
+
 =item change_package_location
 
 Updates package location. Takes a list of keys and values 
-as paramters with the following keys: 
+as parameters with the following keys: 
 
 pkgnum
 
diff --git a/bin/xmlrpc-order_package.php b/bin/xmlrpc-order_package.php
new file mode 100755
index 0000000..fccf77a
--- /dev/null
+++ b/bin/xmlrpc-order_package.php
@@ -0,0 +1,81 @@
+#!/usr/bin/php5
+
+<?php
+
+$freeside = new FreesideAPI();
+
+$result = $freeside->order_package( array(
+  'secret'          => 'sharingiscaring', #config setting api_shared_secret
+  'custnum'         => 619797,
+  'pkgpart'         => 2,
+
+  #the rest is optional
+  'quantity'        => 5,
+  'start_date'      => '12/1/2017',
+  'invoice_details' => [ 'detail', 'even more detail' ],
+  'address1'        => '5432 API Lane',
+  'city'            => 'API Town',
+  'state'           => 'AZ',
+  'zip'             => '54321',
+  'country'         => 'US',
+  'setup_fee'       => '23',
+  'recur_fee'       => '19000',
+));
+
+var_dump($result);
+
+#pre-php 5.4 compatible version?
+function flatten($hash) {
+  if ( !is_array($hash) ) return $hash;
+  $flat = array();
+
+  array_walk($hash, function($value, $key, &$to) { 
+    array_push($to, $key, $value);
+  }, $flat);
+
+  if ( PHP_VERSION_ID >= 50400 ) {
+
+    #php 5.4+ (deb 7+)
+    foreach ($hash as $key => $value) {
+      $flat[] = $key;
+      $flat[] = $value;
+    }
+
+  }
+
+  return($flat);
+}
+
+class FreesideAPI  {
+
+    //Change this to match the location of your backoffice XML-RPC interface
+    #var $URL = 'https://localhost/selfservice/xmlrpc.cgi';
+    var $URL = 'http://localhost:8008/';
+
+    function FreesideAPI() {
+      $this;
+    }
+
+    public function __call($name, $arguments) {
+
+        error_log("[FreesideAPI] $name called, sending to ". $this->URL);
+
+        $request = xmlrpc_encode_request("FS.API.$name", flatten($arguments[0]));
+        $context = stream_context_create( array( 'http' => array(
+            'method' => "POST",
+            'header' => "Content-Type: text/xml",
+            'content' => $request
+        )));
+        $file = file_get_contents($this->URL, false, $context);
+        $response = xmlrpc_decode($file);
+        if (isset($response) && is_array($response) && xmlrpc_is_fault($response)) {
+            trigger_error("[FreesideAPI] XML-RPC communication error: $response[faultString] ($response[faultCode])");
+        } else {
+            //error_log("[FreesideAPI] $response");
+            return $response;
+        }
+    }
+
+}
+
+?>

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

Summary of changes:
 FS/FS/API.pm                 |  121 +++++++++++++++++++++++++++++++++++++++++-
 bin/xmlrpc-order_package.php |   81 ++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+), 1 deletion(-)
 create mode 100755 bin/xmlrpc-order_package.php




More information about the freeside-commits mailing list