]> git.mjollnir.org Git - moodle.git/commitdiff
+ New consts for authorize_action() function:
authorethem <ethem>
Mon, 16 Oct 2006 09:39:08 +0000 (09:39 +0000)
committerethem <ethem>
Mon, 16 Oct 2006 09:39:08 +0000 (09:39 +0000)
  * AN_RETURNZERO: No connection was made on authorize.net.
  * AN_APPROVED: The transaction was accepted.
  * AN_DECLINED: The transaction was declined.
  * AN_REVIEW: The transaction was held for review.

+ Fix: Speacial handling for echecks: REVIEW; 'Under Review', 'Approved Review', 'Review Failed'
+ New feature: Upload a CSV file for echecks (capability: enrol/authorize:uploadcsv level: user)
+ New feature: Search payments by orderid and transid
+ New function: send_welcome_messages()

merged from 17stable.

enrol/authorize/authorizenetlib.php
enrol/authorize/const.php
enrol/authorize/enrol.php
enrol/authorize/index.php
enrol/authorize/localfuncs.php
enrol/authorize/locallib.php
enrol/authorize/uploadcsv.php [new file with mode: 0644]
enrol/authorize/version.php

index a1b4c5f2e3897cb1e4d469d931faf7bfe8080d96..69ce91d83079d6c228368ccad1911b8cb279d5ea 100644 (file)
@@ -4,9 +4,6 @@ if (!defined('MOODLE_INTERNAL')) {
     die('Direct access to this script is forbidden.');
 }
 
-define('AN_APPROVED', '1');
-define('AN_DECLINED', '2');
-define('AN_ERROR',    '3');
 define('AN_DELIM',    '|');
 define('AN_ENCAP',    '"');
 
@@ -86,11 +83,11 @@ function authorize_expired(&$order)
  * sends email to admin.
  *
  * @param object &$order Which transaction data will be sent. See enrol_authorize table.
- * @param string &$message Information about error message if this function returns false.
+ * @param string &$message Information about error message.
  * @param object &$extra Extra data that used for refunding and credit card information.
  * @param int $action Which action will be performed. See AN_ACTION_*
  * @param string $cctype Used internally to configure credit types automatically.
- * @return bool true Transaction was successful, false otherwise. Use $message for reason.
+ * @return int AN_APPROVED Transaction was successful, AN_RETURNZERO otherwise. Use $message for reason.
  * @author Ethem Evlice <ethem a.t evlice d.o.t com>
  * @uses $CFG
  */
@@ -122,7 +119,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
 
     if (empty($order) or empty($order->id)) {
         $message = "Check order->id!";
-        return false;
+        return AN_RETURNZERO;
     }
 
     $method = $order->paymentmethod;
@@ -131,20 +128,20 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
     }
     elseif ($method != AN_METHOD_CC && $method != AN_METHOD_ECHECK) {
         $message = "Invalid method: $method";
-        return false;
+        return AN_RETURNZERO;
     }
 
     $action = intval($action);
     if ($method == AN_METHOD_ECHECK) {
-        if ($action != AN_ACTION_AUTH_CAPTURE && $action != AN_ACTION_CREDIT) {
-            $message = "Please perform AUTH_CAPTURE or CREDIT for echecks";
-            return false;
+        if ($action != AN_ACTION_AUTH_CAPTURE /*&& $action != AN_ACTION_CREDIT*/) {
+            $message = "Please perform only AUTH_CAPTURE for echecks";
+            return AN_RETURNZERO;
         }
     }
 
     if ($action <= AN_ACTION_NONE or $action > AN_ACTION_VOID) {
         $message = "Invalid action!";
-        return false;
+        return AN_RETURNZERO;
     }
 
     $poststring = $conststring;
@@ -160,15 +157,15 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
         {
             if ($order->status != AN_STATUS_NONE) {
                 $message = "Order status must be AN_STATUS_NONE(0)!";
-                return false;
+                return AN_RETURNZERO;
             }
             elseif (empty($extra)) {
                 $message = "Need extra fields!";
-                return false;
+                return AN_RETURNZERO;
             }
             elseif (($action == AN_ACTION_CAPTURE_ONLY) and empty($extra->x_auth_code)) {
                 $message = "x_auth_code is required for capture only transactions!";
-                return false;
+                return AN_RETURNZERO;
             }
 
             $ext = (array)$extra;
@@ -185,11 +182,11 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
         {
             if ($order->status != AN_STATUS_AUTH) {
                 $message = "Order status must be authorized!";
-                return false;
+                return AN_RETURNZERO;
             }
             if (authorize_expired($order)) {
                 $message = "Transaction must be captured within 30 days. EXPIRED!";
-                return false;
+                return AN_RETURNZERO;
             }
             $poststring .= '&x_type=PRIOR_AUTH_CAPTURE&x_trans_id=' . urlencode($order->transid);
             break;
@@ -199,29 +196,30 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
         {
             if ($order->status != AN_STATUS_AUTHCAPTURE) {
                 $message = "Order status must be authorized/captured!";
-                return false;
+                return AN_RETURNZERO;
             }
             if (!authorize_settled($order)) {
                 $message = "Order must be settled. Try VOID, check Cut-Off time if it fails!";
-                return false;
+                return AN_RETURNZERO;
             }
             $timenowsettle = authorize_getsettletime(time());
             $timediff = $timenowsettle - (120 * 3600 * 24);
             if ($order->settletime < $timediff) {
                 $message = "Order must be credited within 120 days!";
-                return false;
+                return AN_RETURNZERO;
             }
             if (empty($extra)) {
                 $message = "Need extra fields to REFUND!";
-                return false;
+                return AN_RETURNZERO;
             }
             $total = floatval($extra->sum) + floatval($extra->amount);
             if (($extra->amount == 0) || ($total > $order->amount)) {
                 $message = "Can be credited up to original amount.";
-                return false;
+                return AN_RETURNZERO;
             }
             $poststring .= '&x_type=CREDIT&x_trans_id=' . urlencode($order->transid);
             $poststring .= '&x_currency_code=' . urlencode($order->currency);
+            $poststring .= '&x_invoice_num=' . urlencode($extra->orderid);
             $poststring .= '&x_amount=' . urlencode($extra->amount);
             if ($method == AN_METHOD_CC) {
                 $poststring .= '&x_card_num=' . sprintf("%04d", intval($order->cclastfour));
@@ -233,7 +231,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
         {
             if (authorize_expired($order) || authorize_settled($order)) {
                 $message = "The transaction cannot be voided due to the fact that it is expired or settled.";
-                return false;
+                return AN_RETURNZERO;
             }
             $poststring .= '&x_type=VOID&x_trans_id=' . urlencode($order->transid);
             break;
@@ -241,7 +239,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
 
         default: {
             $message = "Invalid action: $action";
-            return false;
+            return AN_RETURNZERO;
         }
     }
 
@@ -254,7 +252,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
     $fp = fsockopen("ssl://$host", 443, $errno, $errstr, 60);
     if (!$fp) {
         $message =  "no connection: $errstr ($errno)";
-        return false;
+        return AN_RETURNZERO;
     }
 
     // critical section
@@ -278,7 +276,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
     if (!stristr($tmpstr, 'content-length')) {
         $message =  "content-length error";
         @fclose($fp);
-        return false;
+        return AN_RETURNZERO;
     }
     $length = trim(substr($tmpstr, strpos($tmpstr,'content-length')+15));
     fgets($fp, 4096);
@@ -287,7 +285,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
     $response = explode(AN_ENCAP.AN_DELIM.AN_ENCAP, $data);
     if ($response === false) {
         $message = "response error";
-        return false;
+        return AN_RETURNZERO;
     }
     $rcount = count($response) - 1;
     if ($response[0]{0} == AN_ENCAP) {
@@ -297,11 +295,12 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
         $response[$rcount] = substr($response[$rcount], 0, -1);
     }
 
-    if ($response[0] == AN_APPROVED)
+    $responsecode = intval($response[0]);
+    if ($responsecode == AN_APPROVED || $responsecode == AN_REVIEW)
     {
         $transid = intval($response[6]);
         if ($test || $transid == 0) {
-            return true; // don't update original transaction in test mode.
+            return $responsecode; // don't update original transaction in test mode.
         }
         switch ($action) {
             case AN_ACTION_AUTH_ONLY:
@@ -310,13 +309,19 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
             case AN_ACTION_PRIOR_AUTH_CAPTURE:
             {
                 $order->transid = $transid;
-                if ($action == AN_ACTION_AUTH_ONLY) {
-                    $order->status = AN_STATUS_AUTH;
-                    // don't update order->settletime
-                } else {
-                    $order->status = AN_STATUS_AUTHCAPTURE;
-                    $order->settletime = authorize_getsettletime(time());
+
+                if ($method == AN_METHOD_CC) {
+                    if ($action == AN_ACTION_AUTH_ONLY || $responsecode == AN_REVIEW) {
+                        $order->status = AN_STATUS_AUTH;
+                    } else {
+                        $order->status = AN_STATUS_AUTHCAPTURE;
+                        $order->settletime = authorize_getsettletime(time());
+                    }
+                }
+                elseif ($method == AN_METHOD_ECHECK) {
+                    $order->status = AN_STATUS_UNDERREVIEW;
                 }
+
                 if (! update_record('enrol_authorize', $order)) {
                     email_to_admin("Error while trying to update data " .
                     "in table enrol_authorize. Please edit manually this record: ID=$order->id.", $order);
@@ -332,6 +337,7 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
                 $extra->settletime = authorize_getsettletime(time());
                 unset($extra->sum); // this is not used in refunds table.
                 if (! $extra->id = insert_record('enrol_authorize_refunds', $extra)) {
+                    unset($extra->id);
                     email_to_admin("Error while trying to insert data " .
                     "into table enrol_authorize_refunds. Please add manually this record:", $extra);
                 }
@@ -345,16 +351,15 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
                     unset($order->paymentmethod);
                 }
                 $order->status = AN_STATUS_VOID;
-                // don't update order->settletime
                 if (! update_record($tableupdate, $order)) {
                     email_to_admin("Error while trying to update data " .
                     "in table $tableupdate. Please edit manually this record: ID=$order->id.", $order);
                 }
                 break;
             }
-            default: return false;
+            default:
+                return AN_RETURNZERO;
         }
-        return true;
     }
     else
     {
@@ -428,8 +433,8 @@ function authorize_action(&$order, &$message, &$extra, $action=AN_ACTION_NONE, $
                 }
             }
         }
-        return false;
     }
+    return $responsecode;
 }
 
 ?>
index 851b2f7c3987e5edabf26242f1b215167c0180ef..c66698625b61dfd2576f7d4c44ab60b011491aed 100644 (file)
@@ -1,10 +1,10 @@
 <?php // $Id$
 
 /**#@+
- * Authorize.net methods.
+ * Authorize.net payment methods.
  *
- * Credit Card (CC)
- * ECheck (ECHECK)
+ * Credit Card (cc)
+ * eCheck (echeck)
  */
 define('AN_METHOD_CC',     'cc');
 define('AN_METHOD_ECHECK', 'echeck');
@@ -20,25 +20,33 @@ define('AN_METHOD_ECHECK', 'echeck');
  * CREDIT: Refunded.
  * VOID: Cancelled.
  * EXPIRE: Expired. Orders be expired unless be accepted within 30 days.
- * TEST: Tested. It means created in TEST mode and TransactionID is 0.
+ * 
+ * These are valid only for ECHECK:
+ * UNDERREVIEW: Hold for review.
+ * APPROVEDREVIEW: Approved review.
+ * REVIEWFAILED: Review failed.
+ * TEST: Tested (dummy status). Created in TEST mode and TransactionID is 0.
  */
-define('AN_STATUS_NONE',        0x00);
-define('AN_STATUS_AUTH',        0x01);
-define('AN_STATUS_CAPTURE',     0x02);
-define('AN_STATUS_AUTHCAPTURE', 0x03);
-define('AN_STATUS_CREDIT',      0x04);
-define('AN_STATUS_VOID',        0x08);
-define('AN_STATUS_EXPIRE',      0x10);
-define('AN_STATUS_TEST',        0x80);
+define('AN_STATUS_NONE',            0x00);
+define('AN_STATUS_AUTH',            0x01);
+define('AN_STATUS_CAPTURE',         0x02);
+define('AN_STATUS_AUTHCAPTURE',     0x03);
+define('AN_STATUS_CREDIT',          0x04);
+define('AN_STATUS_VOID',            0x08);
+define('AN_STATUS_EXPIRE',          0x10);
+define('AN_STATUS_UNDERREVIEW',     0x20);
+define('AN_STATUS_APPROVEDREVIEW',  0x40);
+define('AN_STATUS_REVIEWFAILED',    0x80);
+define('AN_STATUS_TEST',            0xff); // dummy status
 /**#@-*/
 
 /**#@+
- * Actions used in authorize_action function.
+ * Actions used in authorize_action() function.
  *
  * NONE: No action. Function always returns false.
  * AUTH_ONLY: Used to authorize only, don't capture.
- * CAPTURE_ONLY: Authorization code received from a bank over the phone and capture now.
- * AUTH_CAPTURE: Used to authorize and capture.
+ * CAPTURE_ONLY: Authorization code was received from a bank over the phone.
+ * AUTH_CAPTURE: Used to authorize and capture (default action).
  * PRIOR_AUTH_CAPTURE:  Used to capture, it was authorized before.
  * CREDIT: Used to return funds to a customer's credit card.
  * VOID: Used to cancel an exiting pending transaction.
@@ -66,4 +74,19 @@ define('AN_ACTION_CREDIT',              5);
 define('AN_ACTION_VOID',                6);
 /**#@-*/
 
+/**#@+
+ * Return codes for authorize_action() function.
+ *
+ * AN_RETURNZERO: No connection was made on authorize.net.
+ * AN_APPROVED: The transaction was accepted.
+ * AN_DECLINED: The transaction was declined.
+ * AN_REVIEW: The transaction was held for review.
+ */
+define('AN_RETURNZERO', 0);
+define('AN_APPROVED',   1);
+define('AN_DECLINED',   2);
+define('AN_ERROR',      3);
+define('AN_REVIEW',     4);
+/**#@-*/
+
 ?>
index a822d1f2043eb4b3d571559d8293fe09f463b097..ca0569a4893f160c88f5748a7bfb69e31180e9a9 100755 (executable)
@@ -27,7 +27,7 @@ class enrolment_plugin_authorize
 
 
     /**
-     * Shows a credit card form for registration.
+     * Presents registration forms.
      *
      * @param object $course Course info
      * @access public
@@ -93,7 +93,7 @@ class enrolment_plugin_authorize
 
 
     /**
-     * Checks form params.
+     * Validates registration forms and enrols student to course.
      *
      * @param object $form Form parameters
      * @param object $course Course info
@@ -122,8 +122,7 @@ class enrolment_plugin_authorize
 
 
     /**
-     * Credit card number mode.
-     * Send to authorize.net.
+     * The user submitted credit card form.
      *
      * @param object $form Form parameters
      * @param object $course Course info
@@ -188,8 +187,7 @@ class enrolment_plugin_authorize
         $message = '';
         $an_review = !empty($CFG->an_review);
         $action = $an_review ? AN_ACTION_AUTH_ONLY : AN_ACTION_AUTH_CAPTURE;
-        $success = authorize_action($order, $message, $extra, $action, $form->cctype);
-        if (!$success) {
+        if (AN_APPROVED != authorize_action($order, $message, $extra, $action, $form->cctype)) {
             email_to_admin($message, $order);
             $this->authorizeerrors['header'] = $message;
             return;
@@ -234,14 +232,10 @@ class enrolment_plugin_authorize
         }
 
         // Credit card captured, ENROL student now...
-        if (!empty($CFG->enrol_mailstudents)) {
-            $a = new stdClass;
-            $a->courses = $course->fullname;
-            $a->profileurl = "$CFG->wwwroot/user/view.php?id=$USER->id";
-            $a->paymenturl = "$CFG->wwwroot/enrol/authorize/index.php?user=$USER->id";
-            $course->welcomemessage = get_string('welcometocoursesemail', 'enrol_authorize', $a);
-        }
         if (enrol_into_course($course, $USER, 'manual')) {
+            if (!empty($CFG->enrol_mailstudents)) {
+                send_welcome_messages($order->id);
+            }
             $teacher = get_teacher($course->id);
             if (!empty($CFG->enrol_mailteachers)) {
                 $a = new stdClass;
@@ -277,6 +271,14 @@ class enrolment_plugin_authorize
         redirect($destination);
     }
 
+
+    /**
+     * The user submitted echeck form.
+     *
+     * @param object $form Form parameters
+     * @param object $course Course info
+     * @access private
+     */
     function echeck_submit($form, $course)
     {
         global $CFG, $USER, $SESSION;
@@ -334,62 +336,15 @@ class enrolment_plugin_authorize
         $extra->x_phone = '';
         $extra->x_fax = '';
 
-        $message = ''; // 2 actions only for echecks: auth_capture and credit
-        $success = authorize_action($order, $message, $extra, AN_ACTION_AUTH_CAPTURE);
-        if (!$success) {
+        $message = '';
+        if (AN_REVIEW != authorize_action($order, $message, $extra, AN_ACTION_AUTH_CAPTURE)) {
             email_to_admin($message, $order);
             $this->authorizeerrors['header'] = $message;
             return;
         }
 
         $SESSION->ccpaid = 1; // security check: don't duplicate payment
-        if ($order->transid == 0) { // TEST MODE
-            enrol_into_course($course, $USER, 'manual');
-            redirect("$CFG->wwwroot/course/view.php?id=$course->id");
-        }
-
-        // ENROL student now ...
-        if (!empty($CFG->enrol_mailstudents)) {
-            $a = new stdClass;
-            $a->courses = $course->fullname;
-            $a->profileurl = "$CFG->wwwroot/user/view.php?id=$USER->id";
-            $a->paymenturl = "$CFG->wwwroot/enrol/authorize/index.php?user=$USER->id";
-            $course->welcomemessage = get_string('welcometocoursesemail', 'enrol_authorize', $a);
-        }
-        if (enrol_into_course($course, $USER, 'manual')) {
-            $teacher = get_teacher($course->id);
-            if (!empty($CFG->enrol_mailteachers)) {
-                $a = new stdClass;
-                $a->course = "$course->fullname";
-                $a->user = fullname($USER);
-                email_to_user($teacher,
-                              $USER,
-                              get_string("enrolmentnew", '', $course->shortname),
-                              get_string('enrolmentnewuser', '', $a));
-            }
-            if (!empty($CFG->enrol_mailadmins)) {
-                $a = new stdClass;
-                $a->course = "$course->fullname";
-                $a->user = fullname($USER);
-                $admins = get_admins();
-                foreach ($admins as $admin) {
-                    email_to_user($admin,
-                                  $USER,
-                                  get_string("enrolmentnew", '', $course->shortname),
-                                  get_string('enrolmentnewuser', '', $a));
-                }
-            }
-        } else {
-            email_to_admin("Error while trying to enrol " .
-            fullname($USER) . " in '$course->fullname'", $order);
-        }
-
-        if ($SESSION->wantsurl) {
-            $destination = $SESSION->wantsurl; unset($SESSION->wantsurl);
-        } else {
-            $destination = "$CFG->wwwroot/course/view.php?id=$course->id";
-        }
-        redirect($destination);
+        redirect($CFG->wwwroot, get_string("reviewnotify", "enrol_authorize"), '30');
     }
 
 
@@ -580,7 +535,7 @@ class enrolment_plugin_authorize
      */
     function cron()
     {
-        global $CFG, $SITE;
+        global $CFG;
         require_once($CFG->dirroot.'/enrol/authorize/authorizenetlib.php');
 
         $oneday = 86400;
@@ -642,8 +597,7 @@ class enrolment_plugin_authorize
         foreach ($orders as $order) {
             $message = '';
             $extra = NULL;
-            $success = authorize_action($order, $message, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE);
-            if ($success) {
+            if (AN_APPROVED == authorize_action($order, $message, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE)) {
                 if ($lastcourseid != $order->courseid) {
                     $lastcourseid = $order->courseid;
                     $course = get_record('course', 'id', $lastcourseid);
@@ -692,37 +646,11 @@ class enrolment_plugin_authorize
         }
 
         // Send emails to students about which courses have enrolled.
-        if (empty($sendem)) {
-            return;
+        if (!empty($sendem)) {
+            mtrace("    sending welcome messages to students", ": ");
+            send_welcome_messages($sendem);
+            mtrace("sent");
         }
-
-        mtrace("    sending welcome messages to students", ": ");
-        $select = "SELECT E.id, E.courseid, E.userid, C.fullname " .
-                  "FROM {$CFG->prefix}enrol_authorize E " .
-                  "INNER JOIN {$CFG->prefix}course C ON C.id = E.courseid " .
-                  "WHERE E.id IN(" . implode(',', $sendem) . ") " .
-                  "ORDER BY E.userid";
-        $emailinfo = get_records_sql($select);
-        $emailcount = count($emailinfo);
-        for($i = 0; $i < $emailcount; ) {
-            $usercourses = array();
-            $lastuserid = $emailinfo[$i]->userid;
-            for ($j=$i; $j < $emailcount and $emailinfo[$j]->userid == $lastuserid; $j++) {
-                $usercourses[] = $emailinfo[$j]->fullname;
-            }
-            $a = new stdClass;
-            $a->courses = implode("\n", $usercourses);
-            $a->profileurl = "$CFG->wwwroot/user/view.php?id=$lastuserid";
-            $a->paymenturl = "$CFG->wwwroot/enrol/authorize/index.php?user=$lastuserid";
-            $emailmessage = get_string('welcometocoursesemail', 'enrol_authorize', $a);
-            $user = get_record('user', 'id', $lastuserid);
-            email_to_user($user,
-                          $adminuser,
-                          get_string("enrolmentnew", '', $SITE->shortname),
-                          $emailmessage);
-            $i = $j;
-        }
-        mtrace("sent");
     }
 
     /**
@@ -753,6 +681,8 @@ class enrolment_plugin_authorize
         $select = "(status='".AN_STATUS_EXPIRE."') AND (timecreated<'$timediff60')";
         delete_records_select('enrol_authorize', $select);
 
+        // XXX TODO SEND EMAIL to uploadcsv user
+
         // Daily warning email for pending orders expiring.
         if (empty($CFG->an_emailexpired)) {
             return; // not enabled
@@ -788,12 +718,15 @@ class enrolment_plugin_authorize
         }
 
         $sorttype = empty($CFG->an_sorttype) ? 'ttl' : $CFG->an_sorttype;
-        $where = "(E.status='". AN_STATUS_AUTH ."') AND (E.timecreated<'$timediffem') AND (E.timecreated>'$timediff30')";
-        $sql = "SELECT E.courseid, E.currency, C.fullname, C.shortname, " .
-               "COUNT(E.courseid) AS cnt, SUM(E.amount) as ttl " .
-               "FROM {$CFG->prefix}enrol_authorize E " .
-               "INNER JOIN {$CFG->prefix}course C ON C.id = E.courseid " .
-               "WHERE $where GROUP BY E.courseid ORDER BY $sorttype DESC";
+        $sql = "SELECT e.courseid, e.currency, c.fullname, c.shortname,
+                  COUNT(e.courseid) AS cnt, SUM(e.amount) as ttl
+                FROM {$CFG->prefix}enrol_authorize e
+                  INNER JOIN {$CFG->prefix}course c ON c.id = e.courseid
+                WHERE (e.status = ". AN_STATUS_AUTH .")
+                  AND (e.timecreated < $timediffem)
+                  AND (e.timecreated > $timediff30)
+                GROUP BY e.courseid
+                ORDER BY $sorttype DESC";
 
         $courseinfos = get_records_sql($sql);
         foreach($courseinfos as $courseinfo) {
index e806e656f643398c6f3d7b6d486b84a014eeb6cc..7d8491992ab6ba2a7c705027f43d3d1c3dc8f44f 100644 (file)
     }
 
 /// Load strings. All strings should be defined here. locallib.php uses these strings.
-    $strs = get_strings(array('status','action','time','course','confirm','no','all','none','error'));
+    $strs = get_strings(array('search','status','action','time','course','confirm','no','all','none','error'));
     $authstrs = get_strings(array('orderid','nameoncard','echeckfirslasttname','void','capture','refund','delete',
-                'authcaptured','authorizedpendingcapture','capturedpendingsettle','capturedsettled',
-                'settled','refunded','cancelled','expired','tested','new','paymentmethod','methodcc','methodecheck',
+                'authcaptured','authorizedpendingcapture','capturedpendingsettle','settled',
+                'refunded','cancelled','expired','underreview','approvedreview','reviewfailed','tested','new',
+                'paymentmethod','methodcc','methodecheck',
                 'transid','settlementdate','notsettled','amount','unenrolstudent'), 'enrol_authorize');
 
 /// Print header
index e469856758cfac305d859b86a62117a3478fbc92..37fd5e9f91d2b2972f459b65d9906cc77c850b07 100644 (file)
@@ -31,9 +31,18 @@ function prevent_double_paid($course)
 {
     global $CFG, $SESSION, $USER;
 
-    $status = empty($CFG->an_test) ? AN_STATUS_AUTH : AN_STATUS_NONE;
+    $sql = "SELECT id FROM {$CFG->prefix}enrol_authorize
+            WHERE userid = $USER->id
+              AND courseid = $course->id ";
 
-    if ($rec=get_record('enrol_authorize','userid',$USER->id,'courseid',$course->id,'status',$status,'id')) {
+    if (empty($CFG->an_test)) { // Real mode
+        $sql .= 'AND status IN('.AN_STATUS_AUTH.','.AN_STATUS_UNDERREVIEW.','.AN_STATUS_APPROVEDREVIEW.')';
+    }
+    else { // Test mode
+        $sql .= 'AND status='.AN_STATUS_NONE;
+    }
+
+    if ($rec = get_record_sql($sql)) {
         $a = new stdClass;
         $a->orderid = $rec->id;
         $a->url = "$CFG->wwwroot/enrol/authorize/index.php?order=$a->orderid";
@@ -307,6 +316,56 @@ function email_to_admin($subject, $data)
     email_to_user($admin, $admin, "$SITE->fullname: Authorize.net ERROR", $message);
 }
 
+
+function send_welcome_messages($orderdata)
+{
+    global $CFG, $SITE;
+
+    if (empty($orderdata)) {
+       return;
+    }
+
+    if (is_numeric($orderdata)) {
+        $orderdata = array($orderdata);
+    }
+
+    $select = "SELECT e.id, e.courseid, e.userid, c.fullname
+                 FROM {$CFG->prefix}enrol_authorize e
+                 INNER JOIN {$CFG->prefix}course c ON c.id = e.courseid
+               WHERE e.id IN(" . implode(',', $orderdata) . ")
+               ORDER BY e.userid";
+
+    $emailinfo = get_records_sql($select);
+    $emailcount = count($emailinfo);
+    if ($emailcount == 1) {
+        $ei = reset($emailinfo);
+        if (!$sender = get_teacher($ei->courseid)) {
+            $sender = get_admin();
+        }
+    }
+    else {
+        $sender = get_admin();
+    }
+
+    $ei = reset($emailinfo);
+    while ($ei !== false) {
+        $usercourses = array();
+        $lastuserid = $ei->userid;
+        for ($current = $ei; $current !== false && $current->userid == $lastuserid; $current = next($emailinfo)) {   
+             $usercourses[] = $current->fullname;
+        }
+        $ei = $current;
+        $a = new stdClass;
+        $a->courses = implode("\n", $usercourses);
+        $a->profileurl = "$CFG->wwwroot/user/view.php?id=$lastuserid";
+        $a->paymenturl = "$CFG->wwwroot/enrol/authorize/index.php?user=$lastuserid";
+        $emailmessage = get_string('welcometocoursesemail', 'enrol_authorize', $a);
+        $user = get_record('user', 'id', $lastuserid);
+        @email_to_user($user, $sender, get_string("enrolmentnew", '', $SITE->shortname), $emailmessage);
+    }
+}
+
+
 function check_openssl_loaded()
 {
     return extension_loaded('openssl');
index 47e160d67741b98f99767ad47071b8c08e59ef44..71ec8a705328828c7fe7f85757e07c8754e53c69 100644 (file)
@@ -24,6 +24,8 @@ function authorize_print_orders($courseid, $userid)
 
     $perpage = 10;
     $status = optional_param('status', AN_STATUS_NONE, PARAM_INT);
+    $searchtype = optional_param('searchtype', 'id', PARAM_ALPHA);
+    $idortransid = optional_param('idortransid', '0', PARAM_INT);
 
     if (! has_capability('enrol/authorize:managepayments', get_context_instance(CONTEXT_COURSE, $courseid))) {
         $userid = $USER->id;
@@ -36,6 +38,9 @@ function authorize_print_orders($courseid, $userid)
                         AN_STATUS_CREDIT => $authstrs->refunded,
                         AN_STATUS_VOID => $authstrs->cancelled,
                         AN_STATUS_EXPIRE => $authstrs->expired,
+                        AN_STATUS_UNDERREVIEW => $authstrs->underreview,
+                        AN_STATUS_APPROVEDREVIEW => $authstrs->approvedreview,
+                        AN_STATUS_REVIEWFAILED => $authstrs->reviewfailed,
                         AN_STATUS_TEST => $authstrs->tested
     );
 
@@ -47,12 +52,28 @@ function authorize_print_orders($courseid, $userid)
             }
         }
         if (!empty($popupcrs)) {
-            print_simple_box_start('center', '100%');
-            echo "$strs->status: ";
-            echo popup_form($baseurl.'&amp;course='.$courseid.'&amp;status=',$statusmenu,'statusmenu',$status,'','','',true);
-            echo " &nbsp; $strs->course: ";
-            echo popup_form($baseurl.'&amp;status='.$status.'&amp;course=',$popupcrs,'coursesmenu',$courseid,'','','',true);
-            print_simple_box_end();
+            echo "<table border='0' width='100%' cellspacing=0 cellpadding=3 class='generaltable generalbox'>";
+            echo "<tr>";
+            echo "<td width='5%'>$strs->status: </td><td width='10%'>";popup_form($baseurl.'&amp;course='.$courseid.'&amp;status=',$statusmenu,'statusmenu',$status,'','','',false);echo"</td>\n";
+            echo "<td width='5%'>$strs->course: </td><td width='10%'>";popup_form($baseurl.'&amp;status='.$status.'&amp;course=',$popupcrs,'coursesmenu',$courseid,'','','',false);echo"</td>\n";
+            if (has_capability('enrol/authorize:uploadcsv', get_context_instance(CONTEXT_USER, $USER->id))) {
+                echo "<form method='get' action='uploadcsv.php'>";
+                echo "<td rowspan=2 align='center' valign='middle' width='50%'><input type='submit' value='".get_string('uploadcsv', 'enrol_authorize')."'></td>";
+                echo "</form>";
+            }
+            else {
+                echo "<td rowspan=2 width='100%'>&nbsp;</td>";
+            }
+            echo "</tr>\n";
+
+            echo "<tr><td>$strs->search: </td>"; $searchmenu = array('id' => $authstrs->orderid, 'transid' => $authstrs->transid);
+            echo "<form method='POST' action='index.php' autocomplete='off'>";
+            echo "<td colspan=3>"; choose_from_menu($searchmenu, 'searchtype', $searchtype, '');
+            echo " = <input type='text' size='14' name='idortransid' value='' /> ";
+            echo "<input type='submit' value='$strs->search' /></td>";
+            echo "</form>";
+            echo "</tr>";
+            echo "</table>";
         }
     }
 
@@ -99,13 +120,25 @@ function authorize_print_orders($courseid, $userid)
         }
     }
 
-    if ($userid > 0) {
-        $where .= "AND (e.userid = '" . $userid . "') ";
-    }
     if ($courseid != SITEID) {
         $where .= "AND (e.courseid = '" . $courseid . "') ";
     }
 
+    if (!empty($idortransid)) {
+        // Ignore old where.
+        if ($searchtype == 'transid') {
+            $where = "WHERE (e.transid = $idortransid) ";
+        }
+        else {
+            $where = "WHERE (e.id = $idortransid) ";
+        }
+    }
+
+    // This must be always last where!!!
+    if ($userid > 0) {
+        $where .= "AND (e.userid = '" . $userid . "') ";
+    }
+
     if ($sort = $table->get_sql_sort()) {
         $sort = ' ORDER BY ' . $sort;
     }
@@ -181,9 +214,7 @@ function authorize_print_order_details($orderno)
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
 
     if ($USER->id != $order->userid) { // Current user viewing someone else's order
-        if (! has_capability('enrol/authorize:managepayments', $coursecontext)) {
-           error("You don't have access rights on this order.");
-        }
+        require_capability('enrol/authorize:managepayments', $coursecontext);
     }
 
     echo "<form action=\"index.php\" method=\"post\">\n";
@@ -231,21 +262,16 @@ function authorize_print_order_details($orderno)
         else {
             $message = '';
             $extra = NULL;
-            $success = authorize_action($order, $message, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE);
-            if (!$success) {
+            if (AN_APPROVED != authorize_action($order, $message, $extra, AN_ACTION_PRIOR_AUTH_CAPTURE)) {
                 $table->data[] = array("<b><font color='red'>$strs->error:</font></b>", $message);
             }
             else {
                 if (empty($CFG->an_test)) {
                     $user = get_record('user', 'id', $order->userid);
-                    if (!empty($CFG->enrol_mailstudents)) {
-                        $a = new stdClass;
-                        $a->courses = $course->fullname;
-                        $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id";
-                        $a->paymenturl = "$CFG->wwwroot/enrol/authorize/index.php?user=$user->id";
-                        $course->welcomemessage = get_string('welcometocoursesemail', 'enrol_authorize', $a);
-                    }
                     if (enrol_into_course($course, $user, 'manual')) {
+                        if (!empty($CFG->enrol_mailstudents)) {
+                            send_welcome_messages($order->id);
+                        }
                         redirect("index.php?order=$orderno");
                     }
                     else {
@@ -299,8 +325,7 @@ function authorize_print_order_details($orderno)
             else {
                 $extra->amount = $amount;
                 $message = '';
-                $success = authorize_action($order, $message, $extra, AN_ACTION_CREDIT);
-                if ($success) {
+                if (AN_APPROVED == authorize_action($order, $message, $extra, AN_ACTION_CREDIT)) {
                     if (empty($CFG->an_test)) {
                         if (empty($extra->id)) {
                             $table->data[] = array("<b><font color=red>$strs->error:</font></b>", 'insert record error');
@@ -343,8 +368,7 @@ function authorize_print_order_details($orderno)
             else {
                 $extra = NULL;
                 $message = '';
-                $success = authorize_action($order, $message, $extra, AN_ACTION_VOID);
-                if ($success) {
+                if (AN_APPROVED == authorize_action($order, $message, $extra, AN_ACTION_VOID)) {
                     if (empty($CFG->an_test)) {
                         redirect("index.php?order=$orderno");
                     }
@@ -392,8 +416,7 @@ function authorize_print_order_details($orderno)
                 else {
                     $message = '';
                     $extra = NULL;
-                    $success = authorize_action($suborder, $message, $extra, AN_ACTION_VOID);
-                    if ($success) {
+                    if (AN_APPROVED == authorize_action($suborder, $message, $extra, AN_ACTION_VOID)) {
                         if (empty($CFG->an_test)) {
                             if (!empty($unenrol)) {
                                 role_unassign(0, $order->userid, 0, $coursecontext->id);
@@ -555,10 +578,10 @@ function authorize_get_status_action($order)
 
     case AN_STATUS_AUTHCAPTURE:
         if (authorize_settled($order)) {
-            if ($canmanage) {
+            if ($order->paymentmethod == AN_METHOD_CC && $canmanage) {
                 $ret->actions = array(ORDER_REFUND);
             }
-            $ret->status = 'capturedsettled';
+            $ret->status = 'settled';
         }
         else {
             if ($order->paymentmethod == AN_METHOD_CC && $canmanage) {
@@ -591,6 +614,21 @@ function authorize_get_status_action($order)
         $ret->status = 'expired';
         return $ret;
 
+    case AN_STATUS_UNDERREVIEW:
+        $ret->status = 'underreview';
+        return $ret;
+
+    case AN_STATUS_APPROVEDREVIEW:
+        $ret->status = 'approvedreview';
+        return $ret;
+
+    case AN_STATUS_REVIEWFAILED:
+        if ($canmanage) {
+            $ret->actions = array(ORDER_DELETE);
+        }
+        $ret->status = 'reviewfailed';
+        return $ret;
+
     default:
         return $ret;
     }
@@ -600,23 +638,25 @@ function authorize_get_status_action($order)
 function authorize_get_status_color($status)
 {
     $color = 'black';
-    switch ($status) {
+    switch ($status)
+    {
+        case 'settled':
+        case 'approvedreview':
+        case 'capturedpendingsettle':
+            $color = '#339900'; // green
+            break;
+
         case 'new':
         case 'tested':
-        case 'cancelled':
+        case 'underreview':
         case 'authorizedpendingcapture':
             $color = '#FF6600'; // orange
             break;
 
-        case 'capturedpendingsettle':
-        case 'capturedsettled':
-        case 'settled':
-            $color = '#339900'; // green
-            break;
-
         case 'expired':
         case 'cancelled':
         case 'refunded';
+        case 'reviewfailed':
             $color = '#FF0033'; // red
             break;
     }
diff --git a/enrol/authorize/uploadcsv.php b/enrol/authorize/uploadcsv.php
new file mode 100644 (file)
index 0000000..36cc776
--- /dev/null
@@ -0,0 +1,193 @@
+<?php // $Id$
+
+/// Load libraries
+    require_once('../../config.php');
+    require_once($CFG->libdir.'/uploadlib.php');
+    require_once($CFG->dirroot.'/enrol/authorize/const.php');
+    require_once($CFG->dirroot.'/enrol/authorize/localfuncs.php');
+
+/// Require capabilites
+    require_login();
+    require_capability('enrol/authorize:uploadcsv', get_context_instance(CONTEXT_USER, $USER->id));
+
+/// Print header
+    $struploadcsv = get_string('uploadcsv', 'enrol_authorize');
+    print_header_simple($struploadcsv, "", "<a href=\"uploadcsv.php\">$struploadcsv</a>");
+    print_heading_with_help($struploadcsv, 'uploadcsv', 'enrol/authorize');
+
+/// Handle CSV file
+    if ($form = data_submitted() && confirm_sesskey()) {
+        $um = new upload_manager('csvfile', false, false, null, false, 0);
+        if ($um->preprocess_files()) {
+            $filename = $um->files['csvfile']['tmp_name'];
+            // Fix mac/dos newlines
+            $text = file_get_contents($filename);
+            $text = preg_replace('!\r\n?!', "\n", $text);
+            $fp = fopen($filename, "w");
+            fwrite($fp, $text);
+            fclose($fp);
+            authorize_process_csv($filename);
+        }
+    }
+
+/// Print submit form
+    $maxuploadsize = get_max_upload_file_size();
+    echo '<center><form method="post" enctype="multipart/form-data" action="uploadcsv.php">
+          <input type="hidden" name="MAX_FILE_SIZE" value="'.$maxuploadsize.'">
+          <input type="hidden" name="sesskey" value="'.$USER->sesskey.'">';
+          upload_print_form_fragment(1, array('csvfile'), array(get_string('file')));
+    echo '<input type="submit" value="'.get_string('upload').'">';
+    echo '</form></center><br />';
+
+/// Print footer
+    print_footer();
+
+?><?php
+
+function authorize_process_csv($filename)
+{
+    global $CFG;
+
+/// We need these fields
+    $myfields = array(
+        'Transaction ID',           // enrol_authorize.transid
+        'Transaction Status',       // Under Review,Approved Review,Review Failed,Settled Successfully
+        'Transaction Type',         // Authorization w/ Auto Capture, Authorization Only, Capture Only, Credit, Void, Prior Authorization Capture
+        'Settlement Amount',        //
+        'Settlement Currency',      //
+        'Settlement Date/Time',     //
+        'Authorization Amount',     //
+        'Authorization Currency',   //
+        'Submit Date/Time',         // timecreated
+        'Reference Transaction ID', // enrol_authorize_refunds.transid
+        'Total Amount',             // enrol_authorize.cost
+        'Currency',                 // enrol_authorize.currency
+        'Invoice Number',           // enrol_authorize.id: Don't trust this! Backup/Restore changes this
+        'Customer ID'               // enrol_authorize.userid
+    );
+
+/// Open the file and get first line
+    $handle = fopen($filename, "r");
+    if (!$handle) {
+        error('CANNOT OPEN CSV FILE');
+    }
+    $firstline = fgetcsv($handle, 8192, ",");
+    $numfields = count($firstline);
+    if ($numfields != 49 && $numfields != 70) {
+        @fclose($handle);
+        error('INVALID CSV FILE; Each line must include 49 or 70 fields');
+    }
+
+/// Re-sort fields
+    $csvfields = array();
+    foreach ($myfields as $myfield) {
+        $csvindex = array_search($myfield, $firstline);
+        if ($csvindex === false) {
+            $csvfields = array();
+            break;
+        }
+        $csvfields[$myfield] = $csvindex;
+    }
+    if (empty($csvfields)) {
+        @fclose($handle);
+        error("<b>INVALID CSV FILE:</b> First line must include 'Header Fields' and
+               the file must be type of <br />'Expanded Fields/Comma Separated'<br />or<br />
+              'Expanded Fields with CAVV Result Code/Comma Separated'");
+    }
+
+/// Read lines
+    $sendem = array();
+    $ignoredlines = '';
+    $faultlog = '';
+    $imported = 0;
+    while (($data = fgetcsv($handle, 8192, ",")) !== FALSE) {
+        if (count($data) != $numfields) {
+            continue; // ignore empty lines
+        }
+
+        $transstatus = $data[$csvfields['Transaction Status']];
+        $transtype = $data[$csvfields['Transaction Type']];
+        $transid = $data[$csvfields['Transaction ID']];
+        $settlementdatetime = strtotime($data[$csvfields['Settlement Date/Time']]);
+
+        if ($transstatus == 'Approved Review' || $transstatus == 'Review Failed') {
+            if ($order = get_record('enrol_authorize', 'transid', $transid)) {
+                $order->status = ($transstatus == 'Approved Review') ? AN_STATUS_APPROVEDREVIEW : AN_STATUS_REVIEWFAILED;
+                update_record('enrol_authorize', $order);
+            }
+            continue;
+        }
+
+        // We want only status=Settled Successfully and type=Authorization w/ Auto Capture
+        if (! ($transstatus == 'Settled Successfully' && $transtype == 'Authorization w/ Auto Capture')) {
+            $ignoredlines .= $transid . "\n";
+            continue;
+        }
+
+        // TransactionId must match
+        $order = get_record('enrol_authorize', 'transid', $transid);
+        if (!$order) { // Not our business
+            $ignoredlines .= $transid . "\n";
+            continue;
+        }
+
+        // Authorized/Captured and Settled
+        $order->status = AN_STATUS_AUTHCAPTURE;
+        $order->settletime = $settlementdatetime;
+        update_record('enrol_authorize', $order);
+
+        if ($order->paymentmethod != AN_METHOD_ECHECK) {
+            $ignoredlines .= $transid . "\n";
+            continue; // We only interest in ECHECK
+        }
+
+        // Get course and context
+        $course = get_record('course', 'id', $order->courseid);
+        if (!$course) {
+            $ignoredlines .= $transid . "\n";
+            continue; // Could not find this course
+        }
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
+        if (!$coursecontext) {
+            $ignoredlines .= $transid . "\n";
+            continue; // Could not find this course context
+        }
+
+        // Get user
+        $user = get_record('user', 'id', $order->userid);
+        if (!$user) {
+            $ignoredlines .= $transid . "\n";
+            continue; // Could not find this user
+        }
+
+        // If user wasn't enrolled, enrol now. Ignore otherwise. Because admin user might submit this file again.
+        if ($role = get_default_course_role($course)) {
+            $ra = get_record('role_assignments', 'roleid', $role->id, 'contextid', $coursecontext->id, 'userid', $user->id);
+            if (empty($ra)) { // Not enrolled, so enrol
+                $timestart = $timeend = 0;
+                if ($course->enrolperiod) {
+                    $timestart = time();
+                    $timeend = $timestart + $course->enrolperiod;
+                }
+                if (role_assign($role->id, $user->id, 0, $coursecontext->id, $timestart, $timeend, 0, 'manual')) {
+                    $imported++;
+                    if (!empty($CFG->enrol_mailstudents)) {
+                        $sendem[] = $order->id;
+                    }
+                }
+                else {
+                    $faultlog .= "Error while trying to enrol ".fullname($user)." in '$course->fullname' \n";
+                }
+            }
+        }
+    }
+    fclose($handle);
+    notice("Done... Total $imported record(s) has been imported.");
+
+/// Send welcome messages to users
+    if (!empty($sendem)) {
+        send_welcome_messages($sendem);
+    }
+}
+
+?>
index abe785a6602b38b2254277cbe88d49cfe67cc337..9aa012f225c801faf57ae8eb80643464a711868f 100755 (executable)
@@ -1,6 +1,6 @@
 <?php // $Id$
 
-$plugin->version  = 2006083100;
+$plugin->version  = 2006101700;
 $plugin->requires = 2006091700;
 
 ?>