diff --git a/components/susignup-admin.php b/components/susignup-admin.php index 4b287169deb17d1363f96a833a72bfdd8b7b27ee..eb27cfedebbd3ba1faf12f43bda161b64081dd89 100644 --- a/components/susignup-admin.php +++ b/components/susignup-admin.php @@ -7,6 +7,7 @@ ***/ include("../lib/member_functions.php"); +include("../lib/date.php"); include("../suapi.inc.php"); //Restrict access to staff. @@ -147,22 +148,164 @@ if (isset($session->groups[$permission])) { } } } + } else if ($mode=="renew") { + if (empty($_REQUEST['member'])){ + $mode='error'; + $smarty->assign('error_text',"Can't renew a member without knowing their username!"); + } else if (!isset($_REQUEST['renewconf'])) { + //Should be trying to renew $_REQUEST['member'] + $username=urldecode($_REQUEST['member']); + $q = "SELECT username, typename, sid, paid, email FROM members, member_type WHERE username=?"; + $res = $sucsDB->Execute($q,array($username)); + if (!$res) { + $mode='error'; + $smarty->assign('error_text', "A database error occurred while trying to retrieve member details"); + } else if ($res->fields['paid'] == paidUntil(time())) { + $mode='error'; + $smarty->assign('error_text', 'User appears to have been renewed already?'); + } else { + $smarty->assign('renew_user', $username); + $smarty->assign('renew_paid', $res->fields['paid']); + $smarty->assign('renew_type', $res->fields['typename']); + $url = "https://$suapi_user:$suapi_pass@hap.swansea-union.co.uk/memberships/Membership.asmx/IsPersonMember?strCriteria=".$res->fields['sid']."&GroupingId=6613"; + $apiReq = curl_init(); + curl_setopt($apiReq, CURLOPT_URL, $url); + curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE); + + $apiResult = curl_exec($apiReq); + $xml=new SimpleXMLElement($apiResult); + $ismember = $xml[0]; + + $user = posix_getpwnam($session->username); + + if ($ismember!="true") { + $mode='error'; + $smarty->assign('error_text', 'Member does not appear to have paid via the SU system. Use the old renewals system if they have paid using some other method');; + } else { + if (renew_member($username, $user['uid'], $user['name'])) { + message_flash("Successfully renewed"); + $mode='menu'; + } else { + $mode='error'; + $smarty->assign('error_text', 'An error occurred renewing account '.$username); + } + + } + + } + + } + + } else if ($mode == 'renewals') { + //Get list of members according to the SU + $url = "https://$suapi_user:$suapi_pass@hap.swansea-union.co.uk/memberships/Membership.asmx/GetMemberListData?GroupingId=6613"; + $apiReq = curl_init(); + curl_setopt($apiReq, CURLOPT_URL, $url); + curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE); + + $apiResult = curl_exec($apiReq); + $sumembers = su_response_decode($apiResult); + $matches = array(); + foreach ($sumembers as $sumem) { + $sucsmem = get_sucs_record($sumem['uni_card_number']); + if ($sucsmem && $sucsmem['paid'] != paidUntil(time()) && $sucsmem['type']==1) { + $matches[]=array($sumem['firstName']." ".$sumem['lastName'], $sucsmem['realname'], $sumem['uni_card_number'], $sucsmem['username'], $sucsmem['paid']); + } + } + $smarty->assign("matches", $matches); + } else if ($mode == 'renewals2') { + $failures = array(); + $successes = array(); + + if (empty($_REQUEST['renew'])) { + $mode='error'; + $smarty->assign("error_text", "Can't renew an empty list!"); + } else { + foreach($_REQUEST['renew'] as $user) { + $admin_user=posix_getpwnam($session->username); + if (renew_member($user, $admin_user['uid'], $admin_user['name'])) { + $successes[]=$user; + } else { + $failures[]=$user; + } + } + $smarty->assign("attempt", count($_REQUEST['renew'])); + $smarty->assign("failures", count($failures)); + $smarty->assign("failusers", $failures); + $smarty->assign("successes", count($successes)); + } } } + + +$smarty->assign('renewables', get_renewable_members()); $smarty->assign('title', 'SU Signup Admin'); $smarty->assign('mode', $mode); $body = $smarty->fetch("susignup-admin.tpl"); $smarty->assign('body', $body); $smarty->assign("extra_styles", array("$baseurl/css/susignup-admin.css")); -function su_json_decode($text) { - $re1='.*?'; - $re2='(\\{.*?\\})'; - if ($c=preg_match_all ("/".$re1.$re2."/is", $text, $matches)) - { - $json_string=$matches[1][0]; - }else{ - return FALSE; - } - return json_decode($json_string,TRUE); +function su_response_decode($text) { + $x = new SimpleXMLElement($text); + return json_decode($x[0],TRUE); } + +function get_sucs_record($sid) { + global $sucsDB; + + $query = "SELECT * FROM members WHERE sid=?;"; + $res = $sucsDB->Execute($query, array($sid)); + if (!$res || $res->RecordCount()>1) { + return FALSE; + } + return $res->FetchRow(); +} + +function get_renewable_members() { + global $sucsDB; + $q = "SELECT username, username||' ('||realname||')' AS display FROM members, member_type WHERE paid != ? AND type=1 AND type=member_type.id ORDER BY paid;"; + $r = $sucsDB->Execute($q, array(paidUntil(time()))); + if(!$r) { + return FALSE; + } + $retvals = array(); + while ($rec=$r->FetchRow()) { + $retvals[$rec['username']]=$rec['display']; + } + return $retvals; +} + +function renew_member($renew_name, $admin_uid, $admin_name) { + global $sucsDB; + + $q="UPDATE members SET paid=?, lastupdate=DEFAULT, lastedit=? WHERE username=?;"; + $r=$sucsDB->Execute($q, array(paidUntil(time()), $admin_uid, $renew_name)); + if (!$r) { + print $sucsDB->ErrorMsg(); + return FALSE; + } else { + $q="SELECT email, typename FROM members, member_type WHERE username=? AND type=member_type.id;"; + $r=$sucsDB->Execute($q, array($renew_name)); + + $message = "Account Renewal notification\n\n"; + $message .= "Account : ".$renew_name."\n"; + $message .= "User Type : ".$r->fields['typename']."\n"; + $message .= "Renewed by: ".$admin_name."\n\n"; + $message .= "**** Payment was made via the SU payments system ****\n"; + $message .= "Regards\n The SU Renewals script"; + mail("treasurer@sucs.org","Account Renewal",$message); + + $message = "Your Swansea University Computer Society (SUCS) membership has been renewed\n\n"; + $message .= "Username: ".$renew_name."\n"; + $message .= "If you do not know or have forgotten your password, please email admin@sucs.org to arrange for it to be changed.\n\n"; + $message .= "Regards\n The SUCS admin"; + $header = "From: admin@sucs.org\r\n"; + $header .= "Reply-To: admin@sucs.org"; + // Personal account + mail($r->fields['email'],"SUCS account renewal",$message,$header); + // sucs account + mail($renew_name."@sucs.org","SUCS account renewal",$message,$header); + return TRUE; + } + +} diff --git a/htdocs/css/susignup-admin.css b/htdocs/css/susignup-admin.css new file mode 100644 index 0000000000000000000000000000000000000000..8cd0251a9941eaab9b42bfcd7c09f447abf3787d --- /dev/null +++ b/htdocs/css/susignup-admin.css @@ -0,0 +1,48 @@ +div.susignup-admin-menu { + float: left; + width: 30%; + margin-left: 10px; + background: #E76808; + border-radius: 15px; + border-radius: 15px; + -moz-border-radius: 15px; + -moz-border-radius: 15px; +} + +div.susignup-admin-menu select { + position: relative; + width: 65%; +} + +div.susignup-admin-menu label { + position: relative; + width: 9em; +} + +div.susignup-admin-menu input#rnsubmit { + position: relative; + width: 70px; +} + +#susignup-renewals { + width: 90%; + border: 2px ridge; + border-collapse: collapse; +} + +#susignup-renewals td { + border: 2px ridge; + padding-left: 4px; + padding-right: 2px; +} + +#susignup-renewals th { + border: 2px ridge; + text-align: center; + padding-left: 2px; + padding-right: 2px; +} + +.centre{ + text-align: center; +} diff --git a/templates/susignup-admin.tpl b/templates/susignup-admin.tpl index ccc1791ae917a90cfb329984e68d3aa9b8c5d4f4..49a0b2b3e0a5e908dd6e042c6bc130b7ac17e28e 100644 --- a/templates/susignup-admin.tpl +++ b/templates/susignup-admin.tpl @@ -4,14 +4,44 @@ <strong>Error: </strong> {$error_text} </div> {/if} - {if $mode == 'renew'} - <div class='errorbar'> - <strong>Error: </strong> Not implemented yet - </div> - {elseif $mode == 'renewals'} - <div class='errorbar'> - <strong>Error: </strong> Not implemented yet - </div> + {if $mode == 'renewals'} +<form action='{$componentpath}' method='post'> + <table id='susignup-renewals'> + <thead> + <tr><th>Renew Now?</th><th>Name (SU)</th><th>Name (SUCS)</th><th>Student ID</th><th>SUCS Username</th><th>Paid Until</th></tr> + </thead> + <tbody> +{foreach from=$matches item=match} + <tr><td class='centre'><input name='renew[]' id='renew' value='{$match[3]}' type='checkbox' checked='checked'/></td><td>{$match[0]}</td><td>{$match[1]}</td><td class='centre'>{$match[2]}</td><td>{$match[3]}</td><td class='centre'>{$match[4]}</td></tr> +{foreachelse} + <tr><td colspan='6'><em>No matches found</em></td></tr> +{/foreach} + </tbody> + <tfoot> + <tr><td colspan='5'><strong>For large numbers of renewals, this can take a while!</strong></td><td class='centre'><input type='submit' name='rwsubmit' id='rwsubmit' value='Go!' /></td></tr> + </tfoot> +</table> +<input type='hidden' name='mode' id='mode' value='renewals2' /> +</form> + {elseif $mode == 'renewals2'} +<div class='centre'> +<div class='cbb' style='text-align: left'> +<h3> Mass renewal results </h3> +<strong>{$attempt}</strong> accounts marked for renewal<br /> +<hr /> +{if $successes == $attempt} +<strong>All</strong> of these requests were successful.<br /> +{else} +<strong>{$successes}</strong> requests were successful, and <span style='color: red'><strong>{$failures}</strong></span> requests failed.<br /> +The following accounts failed to renew: +<ul> +{foreach from=$failusers item=f} +<li>{$f}</li> +{/foreach} +</ul> +{/if} +</div> +</div> {elseif $mode == 'search'} <div style='text-align: center'> <div class='cbb' style='text-align: left'> @@ -26,7 +56,7 @@ </form> </div> </div> - {elseif $mode == 'menu' || $mode == 'error'} + {elseif $mode == 'menu' || $mode == 'error' || $mode == 'renew'} <p> This component allows staff members to sort out memberships and renewals that have been paid for via the SU payments system. </p> <p>Renew an individual member, generate a list of members that look like they've paid via the SU system or begin the signup process for a newbie who doesn't have their transaction ID by selecting the appropriate option below. @@ -34,12 +64,20 @@ This component allows staff members to sort out memberships and renewals that ha <div style='text-align: center'> <div class='susignup-admin-menu cbb'> <h3>Renew existing account:</h3> -Username selector -Submit Button +<form action='{$componentpath}' method='post'> + <label for='member'>Account:</label> + {html_options name=member options=$renewables} + <input type='hidden' name='mode' id='mode' value="renew" /> + <input type='submit' name='rnsubmit' id='rnsubmit' value="Renew" /> +</form> </div> <div class='susignup-admin-menu cbb'> -<h3>Suggest probable renewals</h3> -Submit Button +<h3>Bulk Renewals</h3> +<p style='text-align: left'>This will query the SU API for all current SUCS members and generate a list of corresponding SUCS accounts to be renewed.<br /> This process can take a little while to run</p><br /> +<form action='{$componentpath}' method='post'> + <input type='submit' name='rwsubmit' id='rwsubmit' value='Generate List' /> + <input type='hidden' name='mode' id='mode' value='renewals' /> +</form> </div> <div class='susignup-admin-menu cbb'> <h3>Signup a newbie</h3>