self-service Drupal module, RT#9380
authormark <mark>
Thu, 12 Aug 2010 21:31:19 +0000 (21:31 +0000)
committermark <mark>
Thu, 12 Aug 2010 21:31:19 +0000 (21:31 +0000)
FS/FS/ClientAPI/Signup.pm
FS/FS/ClientAPI_XMLRPC.pm
fs_selfservice/drupal/admin.inc [new file with mode: 0644]
fs_selfservice/drupal/freeside.class.php [new file with mode: 0644]
fs_selfservice/drupal/freeside.info [new file with mode: 0644]
fs_selfservice/drupal/freeside.module [new file with mode: 0644]
fs_selfservice/drupal/signup.inc [new file with mode: 0644]

index 5d70325..a4032f3 100644 (file)
@@ -90,7 +90,7 @@ sub signup_info {
                             ],
 
       'agent' => [ map { my $agent = $_;
-                         map { $_ => $agent->get($_) } @agent_fields;
+                        +{ map { $_ => $agent->get($_) } @agent_fields }
                        }
                        qsearch('agent', { 'disabled' => '' } )
                  ],
@@ -111,6 +111,9 @@ sub signup_info {
 
       'payby' => [ $conf->config('signup_server-payby') ],
 
+      'payby_longname' => [ map { FS::payby->longname($_) } 
+                            $conf->config('signup_server-payby') ],
+
       'card_types' => card_types(),
 
       'paytypes' => [ @FS::cust_main::paytypes ],
index 138ad06..cfaf009 100644 (file)
@@ -49,7 +49,7 @@ sub AUTOLOAD {
     #no strict 'refs';
     #&{$call}(@_);
     #FS::ClientAPI->dispatch($autoload->{$call}, @_);
-    FS::ClientAPI->dispatch($autoload->{$call}, { @_ } );
+    FS::ClientAPI->dispatch($autoload->{$call}, @_ );
   }else{
     die "No such procedure: $call";
   }
diff --git a/fs_selfservice/drupal/admin.inc b/fs_selfservice/drupal/admin.inc
new file mode 100644 (file)
index 0000000..45d83d5
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+function freeside_admin() {
+  return drupal_get_form('freeside_admin_form');
+}
+
+function freeside_admin_form() {
+  $hostname = variable_get('freeside_hostname','');
+
+  $form = array(
+    'freeside_hostname'=> array(
+      '#type'   => 'textfield',
+      '#title'  => t('Freeside server address'),
+      '#default_value'=>variable_get('freeside_hostname',''),
+      '#required'=>1,
+    ),
+  );
+
+  if($hostname) {
+    $freeside = new FreesideSelfService();
+    $signup_info = $freeside->signup_info(); // no agent in this request
+
+    $agents = array();
+    foreach((array)$signup_info['agent'] as $a) {
+      $agents[$a['agentnum']] = $a['agent'];
+    }
+
+    $form['freeside_agentnum'] = array(
+      '#type'   => 'select',
+      '#title'  => t('Signup agent'),
+      '#default_value'=>variable_get('freeside_agentnum',''),
+      '#required'=>1,
+      '#options'=> $agents,
+    );
+
+    $form['freeside_debug'] = array(
+      '#type'   => 'checkbox',
+      '#title'  => t('Enable debugging'),
+      '#default_value'=>variable_get('freeside_debug',0),
+    );
+  }
+
+  return system_settings_form($form);
+}
+
+?>
diff --git a/fs_selfservice/drupal/freeside.class.php b/fs_selfservice/drupal/freeside.class.php
new file mode 100644 (file)
index 0000000..161156a
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+class FreesideSelfService  {
+
+  public $URL = '';
+    function FreesideSelfService() {
+      $this->URL = 'http://' . variable_get('freeside_hostname','') . ':8080';
+      $this;
+    }
+
+    public function __call($name, $arguments) {
+
+        error_log("[FreesideSelfService] $name called, sending to ". $this->URL);
+
+        $request = xmlrpc_encode_request("FS.ClientAPI_XMLRPC.$name", $arguments);
+        $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 (xmlrpc_is_fault($response)) {
+            trigger_error("[FreesideSelfService] XML-RPC communication error: $response[faultString] ($response[faultCode])");
+        } else {
+            //error_log("[FreesideSelfService] $response");
+            return $response;
+        }
+    }
+
+}
+
+?>
diff --git a/fs_selfservice/drupal/freeside.info b/fs_selfservice/drupal/freeside.info
new file mode 100644 (file)
index 0000000..957c7b9
--- /dev/null
@@ -0,0 +1,3 @@
+name = Freeside
+description = Freeside self-service
+core = 6.x
diff --git a/fs_selfservice/drupal/freeside.module b/fs_selfservice/drupal/freeside.module
new file mode 100644 (file)
index 0000000..a806e3b
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+// init freeside API
+require('freeside.class.php');
+
+// menu actions and node paths
+function freeside_menu() {
+  $items = array();
+  $items['freeside/signup'] = array(
+    'title' => t('New customer'),
+    'page callback' => 'freeside_signup',
+    'access arguments' => array('access content'),
+    'description' => t('New Customer Signup'),
+    'file' => 'signup.inc',
+  );
+  $items['admin/settings/freeside'] = array(
+    'title' => t('Configure Freeside'),
+    'page callback' => 'freeside_admin',
+    'access arguments' => array('administer freeside'),
+    'description' => t('Configure Freeside self-service'),
+    'file' => 'admin.inc',
+  );
+  return $items;
+}
+
+// access control
+function freeside_perm() {
+  return array(
+    'administer freeside'
+  );
+}
+
+?>
diff --git a/fs_selfservice/drupal/signup.inc b/fs_selfservice/drupal/signup.inc
new file mode 100644 (file)
index 0000000..13ed379
--- /dev/null
@@ -0,0 +1,318 @@
+<?php
+function freeside_signup() {
+  return drupal_get_form('freeside_signup_form');
+}
+
+function dkpr($var) {
+  /* "debug kpr": Krumo-print $var if debugging is on */
+  static $debug;
+  if(empty($debug)) $debug = variable_get('freeside_debug','');
+  if($debug) kpr($var);
+}
+
+function signup_info($packet) {
+  /* local cache, because transporting the entire signup_info
+    through XML-RPC is incredibly slow.  If you change the config,
+    you can flush the local cache with the "Clear cached data" 
+    button on the Drupal "Performance" menu. */
+  if(1) { // change to 0 to disable local cache
+    $cid = 'FS_signup'.serialize($packet);
+    $info = cache_get($cid);
+    if($info) {
+      return($info->data);
+    }
+    else {
+      $freeside = new FreesideSelfService(); 
+      $info = $freeside->signup_info($packet);
+      cache_set($cid, $info, 'cache', CACHE_TEMPORARY);
+      return($info);
+    }
+  }
+  else {
+    $freeside = new FreesideSelfService();
+    return $freeside->signup_info($packet);
+  }
+}
+
+function subextract($array, $key) {
+  // map { $_->{$key} } (...)
+  $out = array();
+  foreach ($array as $i) {
+    $out[] = $i[$key];
+  }
+  return $out;
+}
+
+function freeside_signup_form($form_state) {
+
+  $agentnum = variable_get('freeside_agentnum','');
+  if( !$agentnum || !(variable_get('freeside_hostname','')) ) {
+    drupal_set_message(t('Freeside self-service is not yet configured.'),'error');
+    return array();
+  }
+
+  $freeside = new FreesideSelfService();
+  $packet = array(
+    'agentnum'    => $agentnum,
+    'promo_code'  => '',
+    'reg_code'    => '',
+  );
+  $signup_info = signup_info($packet);
+  dkpr($signup_info);
+
+  $form = array();
+
+  $refs = $signup_info['part_referral'];
+  $form['refnum'] = count($refs) > 1 ?
+    array(
+      '#type'   => 'select',
+      '#title'  => t('How did you hear about us?'),
+      '#options'=> array_combine(
+        subextract($refs, 'refnum'), 
+        subextract($refs, 'referral')
+      ),
+      '#default_value'=>$signup_info['refnum'],
+    ) : array (
+      '#type'   => 'hidden',
+      '#value'  => $refs[0]['refnum'],
+    );
+
+  $form['contact'] = array(
+    '#type'   => 'fieldset',
+    '#title'  => t('Contact Information'),
+    'last'    => array( 
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => t('Contact name (last, first)'),
+      '#size'   => 20,
+      '#required' => 1,
+    ),
+    'first'   => array( 
+      '#type'   => 'textfield',
+      '#size'   => 20,
+      '#required' => 1,
+      '#suffix' => '</div>',
+    ),
+    'company' => array(
+      '#type'   => 'textfield',
+      '#title'  => t('Company'),
+      '#size'   => 20,
+    ),
+    'address1'=> array(
+      '#type'   => 'textfield',
+      '#title'  => t('Address'),
+      '#size'   => 30,
+      '#required'=>1,
+    ),
+    'address2'=> array(
+      '#type'   => 'textfield',
+      '#size'   => 30,
+    ),
+    'city'    => array(
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => t('City'),
+      '#size'   => 15,
+      '#required'=>1,
+    ),
+    'state'   => array(
+      '#type'   => 'textfield',
+      '#title'  => t('State'),
+      '#size'   => 2,
+      '#required'=>1,
+      '#default_value'=>$info['statedefault'],
+    ),
+    'zip'     => array(
+      '#type'   => 'textfield',
+      '#title'  => t('Zip'),
+      '#size'   => 10,
+      '#required'=>1,
+      '#suffix' => '</div>',
+    ),
+    'daytime' => array(
+      '#type'   => 'textfield',
+      '#title'  => t('Daytime Phone'),
+      '#size'   => 18,
+    ),
+    'night'   => array(
+      '#type'   => 'textfield',
+      '#title'  => t('Night Phone'),
+      '#size'   => 18,
+    ),
+  );
+
+  $emailinvoiceonly = $signup_info['emailinvoiceonly'];
+
+  $form['billing'] = array(
+    'invoicing_list'  => array(
+      '#type'   => 'textfield',
+      '#title'  => t('Email invoice to'),
+      '#size'   => '40',
+      '#required'=>$emailinvoiceonly,
+    ),
+    '#type'   => 'fieldset',
+    '#title'  => t('Billing Information'),
+    'invoicing_list_POST' => array(
+      '#type'   => $emailinvoiceonly ? 'hidden' : 'checkbox',
+      '#title'  => t('Send a paper invoice'),
+      '#default_value' => 0,
+    ),
+  );
+
+  if( count($signup_info['payby']) > 1 ) {
+    $form['billing']['payby'] = array(
+      '#type'   => 'select',
+      '#title'  => t('Payment method'),
+      '#options'=> array_combine(
+        $signup_info['payby'],
+        $signup_info['payby_longname']
+      ),
+    );
+  }
+  else {
+    $form['billing']['payby'] = array(
+      '#type'   => 'hidden',
+      '#value'  => $signup_info['payby'][0],
+    );
+  }
+  $form['billing']['payby_CARD'] = array(
+    '#type'   => 'fieldset',
+    'cardnum' => array(
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => t('Credit card number'),
+      '#size'   => 20,
+      '#maxlength'=>20,
+      '#required'=>1,
+      '#suffix' => '</div>',
+    ),
+    'expmonth' => array(
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => t('Expiration date'),
+      '#size'   => 2,
+      '#required'=>1,
+      '#maxlength' => 2,
+    ),
+    'expyear' => array(
+      '#field_prefix' => '/',
+      '#type'   => 'textfield',
+      '#size'   => 2,
+      '#maxlength' => 2,
+      '#required'=>1,
+      '#suffix' => '</div>',
+    ),
+    'paycvv'  => array(
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => 'CVV',
+      '#size'   => 3,
+      '#maxlength'  => 3,
+      '#required'=>1,
+      '#suffix' => '</div>',
+    ),
+    'cardname'=> array(
+      '#prefix' => '<div class="container-inline">',
+      '#type'   => 'textfield',
+      '#title'  => t('Exact name on card'),
+      '#size'   => 40,
+      '#maxlength'=>60,
+      '#suffix' => '</div>',
+    ),
+  );
+
+  $pkgs = $signup_info['part_pkg'];
+  $form['package'] = array(
+    '#type'   => 'fieldset',
+    '#title'  => t('First Package'),
+    'pkgpart' => (count($pkgs) > 1 ?
+      array(
+        '#type'   => 'select',
+        '#title'  => '',
+        '#options'=> array_combine(
+          subextract($pkgs, 'pkgpart'),
+          subextract($pkgs, 'pkg')
+        ),
+        '#default_value'=>$signup_info['default_pkgpart'],
+      ) : array (
+        '#type'   => 'hidden',
+        '#value'  => $pkgs[0]['pkgpart'],
+      )
+    ),
+    'username'=> array(
+      '#type'   => 'textfield',
+      '#title'  => t('Username'),
+      '#size'   => 20,
+      '#required'=>1,
+    ),
+    'password'=> array(
+      '#type'   => 'password_confirm',
+      '#size'   => 20,
+      '#required'=>1,
+    ),
+  );
+  $form['package']['pkgpart']['#default_value'] = $signup_info['default_pkgpart'];
+
+  $form['submit'] = array(
+    '#type'   => 'submit',
+    '#value'  => 'Sign me up!',
+  );
+  return $form;
+}
+
+function freeside_signup_form_submit($form, &$form_state) {
+  $freeside = new FreesideSelfService();
+  $values = $form_state['values'];
+  dkpr($values);
+
+  $customer = array();
+  $customer['agentnum'] = variable_get('freeside_agentnum','');
+  foreach( array( 'first',
+                 'last',
+                 'address1',
+                 'address2',
+                 'city',
+                 'state',
+                 'zip',
+                 'daytime',
+                 'night',
+                 'fax',
+                 'payby',
+                 'invoicing_list',
+                 'pkgpart',
+                 'username'
+               ) 
+    as $field ) {
+    $customer[$field] = $values[$field];
+    }
+  if($values['invoicing_list_POST']) {
+    $customer['invoicing_list'] = 
+      implode(',', array($customer['invoicing_list'], 'POST'));
+  }
+  $customer['_password']  = $values['password'];
+  $customer['country']    = 'US';
+  if($customer['payby'] == 'CARD') {
+    $customer['payinfo'] = preg_replace('/\D/','',$values['cardnum']);
+    $customer['paydate'] = $values['expmonth'] . '/' . $values['expyear'];
+    $customer['payname'] = isset($values['cardname']) ? 
+      $values['cardname'] :
+      ($values['first'] . ' ' . $values['last']);
+    $customer['paycvv'] = $values['paycvv'];
+  }
+  /* other paybys not implemented */
+
+  dkpr($customer);
+  $response = $freeside->new_customer($customer);
+  dkpr($response);
+  error_log("[new_customer] received response from Freeside: $response");
+  $error = $response['error'];
+  if ( $error ) {
+    drupal_set_message(t("Signup error: $error"), 'error');
+    $form_state['redirect'] = FALSE;
+  }
+  else {
+    drupal_set_message(t("Signup successful!"),'status');
+  }
+}
+
+?>