+ New consts 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.

+ 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()
This commit is contained in:
ethem
2006-10-16 09:09:14 +00:00
parent 74b0c7ac01
commit e9369e5282
9 changed files with 463 additions and 200 deletions
+43 -38
View 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;
}
?>
+38 -15
View 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);
/**#@-*/
?>
+9
View File
@@ -8,6 +8,15 @@ $enrol_authorize_capabilities = array(
'legacy' => array(
'admin' => CAP_ALLOW
)
),
'enrol/authorize:uploadcsv' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_USER,
'legacy' => array(
'admin' => CAP_ALLOW
)
)
);
+35 -102
View File
@@ -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) {
+4 -3
View File
@@ -21,10 +21,11 @@
}
/// 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
+61 -2
View 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');
+79 -39
View 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) {
case 'new':
case 'tested':
case 'cancelled':
case 'authorizedpendingcapture':
$color = '#FF6600'; // orange
switch ($status)
{
case 'settled':
case 'approvedreview':
case 'capturedpendingsettle':
$color = '#339900'; // green
break;
case 'capturedpendingsettle':
case 'capturedsettled':
case 'settled':
$color = '#339900'; // green
case 'new':
case 'tested':
case 'underreview':
case 'authorizedpendingcapture':
$color = '#FF6600'; // orange
break;
case 'expired':
case 'cancelled':
case 'refunded';
case 'reviewfailed':
$color = '#FF0033'; // red
break;
}
+193
View File
@@ -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);
}
}
?>
+1 -1
View File
@@ -1,6 +1,6 @@
<?php // $Id$
$plugin->version = 2006083100;
$plugin->version = 2006101700;
$plugin->requires = 2006091700;
?>