--- loncom/enrollment/Enrollment.pm 2010/08/20 21:44:59 1.43
+++ loncom/enrollment/Enrollment.pm 2017/09/18 14:21:45 1.51
@@ -1,5 +1,5 @@
# Automated Enrollment manager
-# $Id: Enrollment.pm,v 1.43 2010/08/20 21:44:59 raeburn Exp $
+# $Id: Enrollment.pm,v 1.51 2017/09/18 14:21:45 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -38,7 +38,9 @@ use lib '/home/httpd/lib/perl';
use strict;
sub update_LC {
- my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,$classesref,$groupref,$logmsg,$newusermsg,$context,$phototypes) = @_;
+ my ($dom,$crs,$adds,$drops,$startdate,$enddate,$authtype,$autharg,
+ $showcredits,$defaultcredits,$autofailsafe,$classesref,$groupref,
+ $logmsg,$newusermsg,$context,$phototypes) = @_;
# Get institutional code and title of this class
my %courseinfo = ();
&get_courseinfo($dom,$crs,\%courseinfo);
@@ -53,11 +55,14 @@ sub update_LC {
my $status=&Apache::loncoursedata::CL_STATUS;
my $type=&Apache::loncoursedata::CL_TYPE;
my $lockedtype=&Apache::loncoursedata::CL_LOCKEDTYPE;
+ my $credidx=&Apache::loncoursedata::CL_CREDITS;
+ my $instidx = &Apache::loncoursedata::CL_INSTSEC;
my @localstudents = ();
my @futurestudents = ();
my @activestudents = ();
my @excludedstudents = ();
my $currlist;
+ my $now = time;
foreach my $uname (keys %{$roster} ) {
if ($uname =~ m/^(.+):$dom$/) {
if ($$roster{$uname}[$status] eq "Active") {
@@ -126,9 +131,11 @@ sub update_LC {
my %place = &place_hash();
my %ucount = ();
my %enrollinfo = ();
+ my %classcount;
foreach my $class (@{$classesref}) {
my %enrolled = ();
&parse_classlist($$configvars{'lonDaemons'},$dom,$crs,$class,\%place,$$groupref{$class},\%enrolled);
+ $classcount{$class} = scalar(keys(%enrolled));
foreach my $uname (sort keys %enrolled ) {
if (!grep/^$uname$/,@reg_students) {
push @reg_students,$uname;
@@ -193,9 +200,11 @@ sub update_LC {
}
}
-# Explicitly allow access to creation/modification of students if called as an automated process.
+# Explicitly allow access to creation/modification of students and group membership changes
+# when called as an automated process.
if ($context eq 'automated') {
$env{'allowed.cst'}='F';
+ $env{'allowed.mdg'}='F';
}
# Compare IDs with existing LON-CAPA enrollment for this class
@@ -203,7 +212,17 @@ sub update_LC {
unless ($uname eq '') {
my %uidhash=&Apache::lonnet::idrget($dom,$uname);
my @stuinfo = @{$enrollinfo{$uname}};
- my $access = '';
+ my ($access,$added,$inststatus,$instsec);
+ my $credits;
+ if ($showcredits) {
+ $credits = $stuinfo[$place{'credits'}];
+ $credits =~ s/[^\d\.]//g;
+ if ($credits eq $defaultcredits) {
+ undef($credits);
+ }
+ }
+ $inststatus = $stuinfo[$place{inststatus}];
+ $instsec = $stuinfo[$place{instsec}];
if (grep/^$uname$/,@localstudents) {
# Check for studentID changes
if ( ($uidhash{$uname}) && ($uidhash{$uname} !~ /error\:/) ) {
@@ -217,7 +236,7 @@ sub update_LC {
my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
# re-enroll as auto student
if ($drop_reply !~ /^ok/) {
- $$logmsg .= &mt('An error occured during the attempt to convert [_1] from a manual type to an auto type student - [_2].',$uname,$drop_reply).$linefeed;
+ $$logmsg .= &mt('An error occurred during the attempt to convert [_1] from a manual type to an auto type student - [_2].',$uname,$drop_reply).$linefeed;
} else {
# re-enroll as auto student
my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);
@@ -231,25 +250,31 @@ sub update_LC {
if ($usec eq '') {
$showsec = &mt('none');
}
- $switchresult .= &mt("Section for [_1] switched from '[_2]' to '[_3]'.",$uname,$showoldsec,$showsec).$linefeed;
+ $switchresult .= &mt('Section for [_1] switched from [_2] to [_3].',$uname,$showoldsec,$showsec).$linefeed;
if ($context eq 'automated') {
- $$logmsg .= &mt("Section switch for [_1] from '[_2]' to '[_3]'.",$uname,$showoldsec,$usec).$linefeed;
+ $$logmsg .= &mt('Section switch for [_1] from [_2] to [_3].',$uname,$showoldsec,$usec).$linefeed;
}
$switchcount ++;
}
- &execute_add($context,'switchtype',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);
+ &execute_add($context,'switchtype',$uname,$dom,$auth,
+ $authparam,$first,$middle,$last,$gene,
+ $pid,$usec,$end,$start,$emailenc,
+ $credits,$instsec,$cid,\$addresult,\$enrollcount,
+ $linefeed,$logmsg);
+ $added = 1;
}
- }
+ }
# Check for section changes
if ($$currlist{$uname}[$sec] eq $stuinfo[ $place{groupID} ]) {
# Check for access date changes for students with access starting in the future.
if ( (grep/^$uname$/,@futurestudents) && ($$currlist{$uname}[$type] eq "auto") && ($adds == 1) ) {
my $datechange = &datechange_check($$currlist{$uname}[$cstart],$$currlist{$uname}[$cend],$startdate,$enddate);
if ($datechange) {
- my $modify_access_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context);
+ my $modify_access_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
$access = &showaccess($enddate,$startdate);
if ($modify_access_result =~ /^ok/) {
$$logmsg .= &mt('Change in access dates for [_1].',$uname).$access.$linefeed;
+ $added = 1;
} else {
$$logmsg .= &mt('Error when attempting to change start and/or end access dates for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_access_result).$linefeed;
}
@@ -268,15 +293,16 @@ sub update_LC {
if ($expire_role_result eq 'ok') {
my $modify_section_result;
if (grep/^$uname$/,@activestudents) {
- $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$$currlist{$uname}[$cend],$$currlist{$uname}[$cstart],'auto','',$cid,'',$context);
+ $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$$currlist{$uname}[$cend],$$currlist{$uname}[$cstart],'auto','',$cid,'',$context,$credits,$instsec);
} else {
- $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context);
+ $modify_section_result = &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
$access = &showaccess($enddate,$startdate);
}
if ($modify_section_result =~ /^ok/) {
- $switchresult .= &mt("Section for [_1] switched from old section: '[_2]' to new section: '[_3]'.",$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$access.$linefeed;
+ $switchresult .= &mt('Section for [_1] switched from old section: [_2] to new section: [_3].',$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$access.$linefeed;
+ $added = 1;
if ($context eq 'automated') {
- $$logmsg .= &mt('Section switch for [_1] from [_2] to [_3]',$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$linefeed;
+ $$logmsg .= &mt('Section switch for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$sec],$stuinfo[ $place{groupID} ]).$linefeed;
}
$switchcount ++;
} else {
@@ -287,6 +313,31 @@ sub update_LC {
}
}
}
+# Check for credits changes
+ if (($showcredits) &&
+ ($$currlist{$uname}[$credidx] ne $credits) && (!$added)) {
+ my $modify_credits_result =
+ &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
+ if ($modify_credits_result =~ /^ok/) {
+ if ($credits ne '') {
+ $$logmsg .= &mt('Credits change for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$credidx],$credits).$linefeed;
+ } else {
+ $$logmsg .= &mt('Credits change for [_1] from [_2] to course default [_3].',$uname,$$currlist{$uname}[$credidx],$defaultcredits).$linefeed;
+ }
+ } else {
+ $$logmsg .= &mt('Error when attempting to change credits for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_credits_result).$linefeed;
+ }
+ }
+# Check for institutional section change
+ if (($$currlist{$uname}[$instidx] ne $instsec) && (!$added)) {
+ my $modify_instsec_result =
+ &Apache::lonnet::modify_student_enrollment($dom,$uname,undef,undef,undef,undef,undef,$stuinfo[ $place{groupID} ],$enddate,$startdate,'auto','',$cid,'',$context,$credits,$instsec);
+ if ($modify_instsec_result =~ /^ok/) {
+ $$logmsg .= &mt('Institutional section change for [_1] from [_2] to [_3].',$uname,$$currlist{$uname}[$instidx],$instsec).$linefeed;
+ } else {
+ $$logmsg .= &mt('Error when attempting to change institutional section for [_1] in section: [_2] -error [_3].',$uname,$stuinfo[$place{groupID}],$modify_instsec_result).$linefeed;
+ }
+ }
} else {
# Check for changed usernames by checking studentIDs
if ( ($stuinfo[ $place{studentID} ] ne '') && (grep/^$stuinfo[ $place{studentID} ]$/,@LCids) ) {
@@ -302,9 +353,10 @@ sub update_LC {
$$logmsg .= &mt('Because of this student/employee ID conflict, the new username - [_1] - has not been added to the LON-CAPA classlist',$uname).$linefeed;
}
} elsif ($adds == 1) {
- my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc);
+ my ($auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,$emailaddr,$pid,$emailenc,$credithours);
&prepare_add($authtype,$autharg,$enddate,$startdate,\@stuinfo,\%place,\$dom,\$uname,\$auth,\$authparam,\$first,\$middle,\$last,\$gene,\$usec,\$end,\$start,\$emailaddr,\$pid,\$emailenc);
# Check for existing account in this LON-CAPA domain for this username
+ next if (($end) && ($end < $now));
my $uhome=&Apache::lonnet::homeserver($uname,$dom);
if ($uhome eq 'no_host') { # User does not exist
my $args = {'auth' => $auth,
@@ -326,11 +378,20 @@ sub update_LC {
'cdom' => $dom,
'context' => $context,
'linefeed' => $linefeed,
- 'role' => 'st'
+ 'inststatus' => $inststatus,
+ 'instsec' => $instsec,
+ 'role' => 'st',
};
+ if ($credits) {
+ $args->{'credits'} = $credits;
+ }
my $outcome = &create_newuser($args,$logmsg,$newusermsg,\$enrollcount,\$addresult,\%longroles,\%courseinfo,$context);
} else {
- &execute_add($context,'newstudent',$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,\$addresult,\$enrollcount,$linefeed,$logmsg);
+ &execute_add($context,'newstudent',$uname,$dom,$auth,
+ $authparam,$first,$middle,$last,$gene,$pid,
+ $usec,$end,$start,$emailenc,$credits,$instsec,
+ $cid,\$addresult,\$enrollcount,$linefeed,
+ $logmsg);
}
if ($courseinfo{'showphoto'}) {
my ($result,$resulttype) =
@@ -374,6 +435,7 @@ sub update_LC {
# Do drops
if ( ($drops == 1) && (@reg_students > 0) ) {
+ my %delaydrops;
foreach my $uname (@localstudents) {
if ($$currlist{$uname}[$type] eq "auto") {
my @saved = ();
@@ -385,9 +447,20 @@ sub update_LC {
push @saved,$uname;
}
} elsif (@saved == 0) {
+# Check enrollment count for institutional section of student to be dropped
+ if ($$currlist{$uname}[$instidx]) {
+ if (exists($classcount{$$currlist{$uname}[$instidx]})) {
+ if ($classcount{$$currlist{$uname}[$instidx]} == 0) {
+ if ($autofailsafe) {
+ push(@{$delaydrops{$$currlist{$uname}[$instidx]}},$uname);
+ next;
+ }
+ }
+ }
+ }
my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
if ($drop_reply !~ /^ok/) {
- $$logmsg .= &mt('An error occured during the attempt to expire the [_1] from the old section [_2] - [_3].',$uname,$$currlist{$uname}[$sec],$drop_reply).$linefeed;
+ $$logmsg .= &mt('An error occurred during the attempt to expire the [_1] from the old section [_2] - [_3].',$uname,$$currlist{$uname}[$sec],$drop_reply).$linefeed;
} else {
$dropcount ++;
my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);
@@ -400,11 +473,41 @@ sub update_LC {
}
}
}
+ if (scalar(keys(%delaydrops)) > 0) {
+ foreach my $class (keys(%delaydrops)) {
+ if (ref($delaydrops{$class}) eq 'ARRAY') {
+ if ($autofailsafe < scalar(@{$delaydrops{$class}})) {
+ $$logmsg .= &mt('The following students were not expired from the old section [_1] because the enrollment count retrieved for that institutional section was zero, and the number of students with roles to expire exceeded the failsafe threshold of [_2]:',$class,$autofailsafe);
+ if ($context eq "updatenow") {
+ $$logmsg .= '
'.join('
',@{$delaydrops{$class}}).$linefeed;
+ } elsif ($context eq "automated") {
+ $$logmsg .= $linefeed.join($linefeed,@{$delaydrops{$class}}).$linefeed;
+ }
+ } else {
+ foreach my $uname (@{$delaydrops{$class}}) {
+ my $drop_reply = &Apache::lonnet::modifystudent($dom,$uname,'','','',undef,undef,undef,undef,$$currlist{$uname}[$sec],time,undef,undef,undef,undef,'auto','',$cid,'',$context);
+ if ($drop_reply !~ /^ok/) {
+ $$logmsg .= &mt('An error occurred during the attempt to expire the [_1] from the old section [_2] - [_3].',$uname,$$currlist{$uname}[$sec],$drop_reply).$linefeed;
+ } else {
+ $dropcount ++;
+ my %userenv = &Apache::lonnet::get('environment',['firstname','lastname','id'],$dom,$uname);
+ $dropresult .= $userenv{'firstname'}." ".$userenv{'lastname'}." (".$userenv{'id'}.") - ".$uname.' '.&mt("dropped from section: '[_1]'.",$$currlist{$uname}[$sec]).$linefeed;
+ if ($context eq 'automated') {
+ $$logmsg .= &mt('User [_1] student role expired from course.',$uname).$linefeed;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
-# Terminated explictly allowed access to student creation/modification
+# Terminated explictly allowed access to student creation/modification
+# and group membership changes
if ($context eq 'automated') {
delete($env{'allowed.cst'});
+ delete($env{'allowed.mdg'});
}
if ($enrollcount > 0) {
if ($context eq "updatenow") {
@@ -473,6 +576,9 @@ sub create_newuser {
my $context = $args->{'context'};
my $linefeed = $args->{'linefeed'};
my $role = $args->{'role'};
+ my $inststatus = $args->{'inststatus'};
+ my $credits = $args->{'credits'};
+ my $instsec = $args->{'instsec'};
my $create_passwd = 0;
my $authchk = '';
my $outcome;
@@ -517,7 +623,7 @@ sub create_newuser {
$outcome = $result;
}
} else {
- $outcome=&Apache::lonnet::modifystudent($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,'',undef,$emailaddr,'auto','',$cid,'',$called_context);
+ $outcome=&Apache::lonnet::modifystudent($udom,$uname,$pid,$auth,$authparam,$first,$middle,$last,$gene,$usec,$end,$start,'',undef,$emailaddr,'auto','',$cid,'',$called_context,$inststatus,$credits,$instsec);
}
if ($outcome eq 'ok') {
my $access = &showaccess($end,$start);
@@ -569,7 +675,11 @@ sub create_newuser {
if ($start > 0) {
$access_start = localtime($start)
}
- $body = &mt('You have been enrolled in the LON-CAPA system at your institution, because you are a registered student in a class which is using the LON-CAPA couse management and online homework system.')."\n\n".&mt("You should log-in to the system using the following credentials:\nusername: [_1]\npassword: [_2]",$uname,$authparam)."\n\n".&mt('The URL you should use to access the LON-CAPA system at your institution is: ').$portalurl."\n\n".&mt('When you log-in you will be able to access the LON-CAPA course for [_1] - [_2] starting [_3].',$$courseinfo{'description'},$$courseinfo{'inst_code'},$access_start)."\n";
+ $body =
+ &mt('You have been enrolled in the LON-CAPA system at your institution, because you are a registered student in a class which is using the LON-CAPA course management and online homework system.')."\n\n"
+ .&mt("You should log-in to the system using the following credentials:\nusername: [_1]\npassword: [_2]",$uname,$authparam)."\n\n"
+ .&mt('The URL you should use to access the LON-CAPA system at your institution is: ').$portalurl."\n\n"
+ .&mt('When you log-in you will be able to access the LON-CAPA course for [_1] - [_2] starting [_3].',$$courseinfo{'description'},$$courseinfo{'inst_code'},$access_start)."\n";
}
&Apache::lonmsg::sendemail($emailaddr,$subject,$body);
}
@@ -603,7 +713,7 @@ sub prepare_add {
$$start = $$stuinfo[ $$place{'startdate'} ];
$$emailaddr = $$stuinfo[ $$place{'email'} ];
$$pid = $$stuinfo[ $$place{'studentID'} ];
-
+
# remove non alphanumeric values from section
$$usec =~ s/\W//g;
@@ -631,9 +741,11 @@ sub prepare_add {
}
sub execute_add {
- my ($context,$caller,$uname,$dom,$auth,$authparam,$first,$middle,$last,$gene,$pid,$usec,$end,$start,$emailenc,$cid,$addresult,$enrollcount,$linefeed,$logmsg) = @_;
+ my ($context,$caller,$uname,$dom,$auth,$authparam,$first,$middle,$last,
+ $gene,$pid,$usec,$end,$start,$emailenc,$credits,$instsec,$cid,$addresult,
+ $enrollcount,$linefeed,$logmsg) = @_;
# Get the user's information and authentication
- my %userenv = &Apache::lonnet::get('environment',['firstname','middlename','lastname','generation','id','critnotification','notification','permanentemail'],$dom,$uname);
+ my %userenv = &Apache::lonnet::get('environment',['firstname','middlename','lastname','generation','id','critnotification','notification','permanentemail','inststatus'],$dom,$uname);
my ($tmp) = keys(%userenv);
if ($tmp =~ /^(con_lost|error)/i) {
%userenv = ();
@@ -702,7 +814,11 @@ sub execute_add {
}
# Assign the role of student in the course.
- my $classlist_reply = &Apache::lonnet::modify_student_enrollment($dom,$uname,$pid,$first,$middle,$last,$gene,$usec,$end,$start,'auto','',$cid,'',$context);
+ my $classlist_reply =
+ &Apache::lonnet::modify_student_enrollment($dom,$uname,$pid,$first,$middle,
+ $last,$gene,$usec,$end,$start,
+ 'auto','',$cid,'',$context,
+ $credits,$instsec);
if ($classlist_reply eq 'ok') {
my $access = &showaccess($end,$start);
my $showsec = $usec;
@@ -765,7 +881,7 @@ sub parse_classlist {
my $xmlfile = $tmpdir."/tmp/".$dom."_".$crs."_".$class."_classlist.xml";
my $uname = '';
my @state;
- my @items = ('autharg','authtype','email','firstname','generation','lastname','middlename','studentID');
+ my @items = ('autharg','authtype','email','firstname','generation','lastname','middlename','studentID','credits','inststatus');
my $p = HTML::Parser->new
(
xml_mode => 1,
@@ -776,6 +892,7 @@ sub parse_classlist {
if ("@state" eq "students student") {
$uname = $attr->{username};
$$studentsref{$uname}[ $$placeref{'groupID'} ] = $groupID;
+ $$studentsref{$uname}[ $$placeref{'instsec'} ] = $class;
}
}, "tagname, attr"],
text_h =>
@@ -856,7 +973,7 @@ sub get_courseinfo {
my ($dom,$crs,$courseinfo) = @_;
my $owner;
if (defined($dom) && defined($crs)) {
- my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphoto','description'],$dom,$crs);
+ my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.showphoto','description','internal.defaultcredits'],$dom,$crs);
if ( defined($settings{'internal.coursecode'}) ) {
$$courseinfo{'inst_code'} = $settings{'internal.coursecode'};
}
@@ -866,6 +983,9 @@ sub get_courseinfo {
if ( defined($settings{'internal.showphoto'}) ) {
$$courseinfo{'showphoto'} = $settings{'internal.showphoto'};
}
+ if ( defined($settings{'internal.credithours'}) ) {
+ $$courseinfo{'defaultcredits'} = $settings{'internal.defaultcredits'};
+ }
}
return;
}
@@ -883,6 +1003,9 @@ sub place_hash {
middlename => 8,
startdate => 9,
studentID => 10,
+ credits => 11,
+ inststatus => 12,
+ instsec => 13,
);
return %place;
}