#! /usr/bin/perl # Copyright 2001-2006 Leslie Richardson # This file is part of Open Admin for Schools. # Query Function for StudentPersonal Objects # Passed Values: none. use DBI; use CGI; use XML::Writer; use XML::Writer::String; use Data::UUID; use HTTP::Request::Common qw(POST); use HTTP::Headers; use LWP::UserAgent; use XML::LibXML; my $self = 'syncenrol.pl'; # Read config variables require "../../etc/admin.conf" or die "Cannot read admin.conf: $!"; require "slxmllib.pl" or die "Cannot read slxmllib.pl: $!"; # Override V1 with V2 values # SDS XML Schema Declarations $xmlns = "http://www.sasked.gov.sk.ca/xsd/sl/2.x/SLMessage_V2.xsd"; $xmlnsxsi = "http://www.w3.org/2001/XMLSchema-instance"; $xsischemaLocation="http://www.sasked.gov.sk.ca/xsd/sl/2.x/SLMessage_V2.xsd http://www.sasked.gov.sk.ca/xsd/sl/2.x/SLMessage_V2.xsd"; my $q = new CGI; my %arr = $q->Vars; print $q->header; if ($arr{debug}){ $debug = 1; delete $arr{debug}; } my $dsn = "DBI:$dbtype:dbname=$dbase"; $dbh = DBI->connect($dsn,$user,$password); # Setup Date and Times my @month = ("","January","February","March","April","May","June","July", "August","September","October","November","December"); my @tim = localtime(time); my $year = $tim[5] + 1900; $tim[4]++; for (0..4){if (length($tim[$_]) == 1){ $tim[$_] = '0'.$tim[$_];}} my $currdate = "$year-$tim[4]-$tim[3]"; my $currtime = "$tim[2]:$tim[1]:$tim[0]"; my $currlongdate = "$month[$tim[4]] $tim[3], $year"; print "$doctype\nSDS Query: School Enrollment $chartype\n[ Main | Export ]

Query School Student Enrollment

$currlongdate

\n"; # This shows the records to update....(and select) if ($arr{transferflag}) { # Activate/Create Transfer records activateTransfer(); die; } #if ($arr{activatedflag}) { # Activate the selected record # delete $arr{activatedflag}; # not needed. # updateEnrol(%arr); # print "\n"; # die; #} # Find all local kids and push studnum into hash, display any blank provnum my $sth = $dbh->prepare("select studnum, provnum, lastname, firstname from student order by provnum"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} $studcount = $sth->rows; # Note any missing provincial numbers... my $foundmissing = 0; while (my ($studnum,$provnum,$lastname, $firstname) = $sth->fetchrow) { if (not $provnum) { if ($foundmissing == 0){ # print the table heading, once. print "\n"; } $foundmissing = 1; print "\n"; push @noprovnum, "$lastname:$firstname:$studnum"; # used to NOT withdraw them. next; } $localStudent{$provnum} = 1; $masterList{$provnum} = 1; } if ($foundmissing) { print "
Missing Provincial Number for: "; print "$firstname $lastname ($studnum)
\n"; print "

"; print "Run Identity Script (qryschident.pl)

\n"; print "

 

\n"; } # Create a new user agent my $ua = LWP::UserAgent->new(); $ua->agent("OpenAdmin"); $count++; mkQueryString($count); # Generate $output string # DEBUG Data Errors if ($debug){ print "
\n"; print "

DEBUG - Request sent to Sask Learning

\n"; my $temp = $output->value; $temp =~ s//>/g; print "
",$temp,"

\n"; } # Create the https post request my $req = POST $url, [ XML=>$output->value ]; $req->content_type('application/xml;charset="utf-8"'); $req->authorization_basic($sds_userid, $sds_password); # Issue the request and receive a response my $res = $ua->request($req); # Check the status of the response if ($res->is_success) { # For Debugging Data Errors if ($debug){ print "

DEBUG - Sask Learning XML Response

\n"; print "
\n"; my $temp = $res->content; $temp =~ s//>/g; print "
",$temp,"
\n"; } my $response = $res->content; # Parse the response. my $parser = XML::LibXML->new(); eval {$doc = $parser->parse_string($response)}; if ($@){ print "
Sask Learning Error:\n $@\n",$response,"

\n"; print "\n"; die; } $doc->setEncoding('UTF-8'); $root = $doc->getDocumentElement; $root->setNamespace($xmlns,'sl',1); $mastermsgid = $root->findvalue('//sl:SL_MsgId'); $status = $root->findvalue('//sl:SL_Status/sl:SL_StatusCode'); if ($status eq 'Errors' or $status eq 'Invalid'){ # Print out error and add to errorlog. &prErr($mastermsgid,"$lastname, $firstname ($studnum)"); } elsif ($status eq 'Successful'){ my @slprovnums = parseSPLite(); # main thing... get their list of kids. } else { # print warnings... ($status eq 'Warnings') print "There were warnings..."; } } else { # Transfer Error! my $err = $res->status_line; print "

Transfer Error: $err

"; die; } # Now create a master list from both lists. my $skcount = $#slprovnums + 1; foreach my $pn (@slprovnums) { $masterList{$pn} = 1; $saskStudent{$pn} = 1; } #other hash is: $localStudent{$provnum} = 1; foreach my $pn (keys %masterList) { # go through all students (on both lists) # Delete them if we have a match (they're registered in both systems) if ($saskStudent{$pn} == $localStudent{$pn} and $localStudent{$pn} == 1) { delete $saskStudent{$pn}; delete $localStudent{$pn}; } } print "\n"; print "\n"; print "\n"; print "\n"; print "
Local School Enrollment: (from local records)$studcount
Sask Learning Enrollment: (from SL records)$skcount

 

\n"; print "
\n"; print "\n"; if ($debug) { print "\n"; } print "

Students to be Withdrawn from Sask Learning

\n"; my $studcount = scalar keys %saskStudent; if (not $studcount) { print "No students to withdraw.\n"; } else { print "\n"; print ""; print "\n"; my $count = 1; foreach my $key (keys %saskStudent) { my $studnum; my ($lastname,$firstname,$middlename,$birthdate) = split /:/, $slname{$key}; ($firstname, $rest) = split /\s/,$firstname; print ""; my $sth1 = $dbh->prepare("select id, date from transfer where studnum = '$studnum' and type = 'withdraw' order by date desc"); $sth1->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} $transrows = $sth1->rows; print "\n"; $count++; } print "
Name / ProvNum / BdateLocal NumActivate
Withdrawal
$count: $lastname, $firstname ($key) $birthdate\n"; my $sth = $dbh->prepare("select studnum from studentall where lastname = '$lastname' and firstname = '$firstname'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $rows = $sth->rows; my $transrows; # count of transfer records... if ($rows < 1){ # student not found... print "Not Found\n"; print "Withdraw? "; print "\n"; } else { # student found $studnum = $sth->fetchrow; print "$studnum"; while (my ($id,$date) = $sth1->fetchrow) { print "$date | "; } } print "

\n"; print "\n"; } print "

\n"; # Now outstanding enrollments print "

Local Students to Enrol with SL

\n"; my $studcount = scalar keys (%localStudent); if (not $studcount){ print "No students to enrol.\n"; } else { print "\n"; print "\n"; print "\n"; my $count = 1; foreach my $key (keys %localStudent) { # Get studnum from provnum $key my $sth1 = $dbh->prepare("select studnum, birthdate from studentall where provnum = '$key'"); $sth1->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my ($studnum, $birthdate) = $sth1->fetchrow; my $rows = $sth1->rows; my ($lastname, $firstname, $wd, $trn) = split /:/, findStudent($key); if ($wd == 1) { $wd = 'Y'; } else { $wd = 'N'; } print "\n"; $count++; } print "
NameWDLocal NumEnrollment
$count: $lastname, $firstname ($key) "; print "$birthdate$wd\n"; if ($studnum) { print "$studnum"; } else { print "Not Found\n"; } my $sth2 = $dbh->prepare("select id, date from transfer where studnum = '$studnum' and (type = 'enrol' or type = 're-enrol') order by date desc"); $sth2->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } my $transrows = $sth2->rows; if ($transrows < 1){ # student transfers not found... print "Enrol? "; print "\n"; } else { # we have records... while (my ($id,$date) = $sth2->fetchrow) { print "$date | "; } } print "
WD = Withdrawn?

\n"; print "\n"; } # end of student display/no display print "
\n"; # Functions ============================= #---------------- sub mkQueryString { # QryBySchool for StudentPersonal objects. #---------------- my $idcount = shift; # Create Writer Instance $output = new XML::Writer::String; my $datamode = 0; if ($debug){ $datamode = 1;} # pretty print xml output $wr = new XML::Writer(OUTPUT => $output, DATA_MODE => $datamode, DATA_INDENT => '2'); # Set XML Header and write Root Element $wr->xmlDecl("UTF-8"); $wr->startTag('SL_Message','xmlns' =>$xmlns, 'xmlns:xsi' =>$xmlnsxsi, 'xsi:schemaLocation' => $xsischemaLocation); $wr->startTag('SL_Request'); &mkSL_Header($currdate, $currtime, $schoolnumber,$idcount); $wr->startTag('SL_Query'); $wr->startTag('QueryBySchool', 'RefId' => "$schoolnumber", 'ObjectName' => 'StudentPersonal' ); $wr->dataElement('SchoolId',$schoolnumber); my $cdate = $currdate; $cdate =~ s/-//g; # strip hyphens $wr->dataElement('FromDate',$cdate); $wr->dataElement('ToDate',$cdate); $wr->endTag('QueryBySchool'); $wr->endTag('SL_Query'); $wr->endTag('SL_Request'); $wr->endTag('SL_Message'); $wr->end(); } #--------- sub prErr { # Print Errors to Screen #--------- my @errors = $root->findnodes('//sl:SL_Error'); foreach my $error (@errors){ # Get Error Elements my $objectname = $error->getAttribute('ObjectName'); my $errmsg = $error->findvalue('./sl:SL_ErrorMsg'); $errmsg =~ s/[\r|\n]/ /g; my $errcode = $error->findvalue('./sl:SL_ErrorCode'); print "

$errmsg

\n"; } print "\n"; } #-------------- sub findStudent { #-------------- # Passed prov number... return data my $provnum = shift; # Get student record my $sth = $dbh->prepare("select lastname, firstname, initial, studnum from studentall where provnum = ?"); $sth->execute($provnum); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } my ($lastname, $firstname,$middlename,$studnum) = $sth->fetchrow; if (not $lastname) { $lastname = 'Not Found'; return $lastname; } # Check whether current or withdrawn. $wd = ''; $sth = $dbh->prepare("select count(studid) from student where provnum = ?"); $sth->execute($provnum); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $idcount = $sth->fetchrow; if ($idcount == 1){ $wd = 0 } else { $wd = 1; } $sth = $dbh->prepare("select studnum from student where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $studnum = $sth->fetchrow; # Check if records in transfer table (if missing...) $sth = $dbh->prepare("select count(id) from transfer where studnum = '$studnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $transcount = $sth->fetchrow; return "$lastname:$firstname:$wd:$transcount"; } #---------------------- sub parseStudentPersonal { # passed document root object. #---------------------- my @studinfo = $root->findnodes('//sl:StudentPersonal'); print "\n"; print ""; print "\n"; my $count = 1; foreach my $student (@studinfo){ my $provnum = $student->findvalue('sl:StudentIdentification/sl:DeptAssignedPersonId'); my $firstname = $student->findvalue('sl:StudentInfo/sl:Name/sl:FirstName'); my $lastname = $student->findvalue('sl:StudentInfo/sl:Name/sl:LastName'); my $middlename = $student->findvalue('sl:StudentInfo/sl:Name/sl:MiddleName'); # Get student record my $sth = $dbh->prepare("select lastname, firstname, initial, studnum from studentall where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my ($localLastname, $localFirstname,$localMiddlename,$studnum) = $sth->fetchrow; if (not $localLastname) { $mis = "MIS"; } else { $mis=''; } # Check whether current or withdrawn. $wd = ''; if ($localLastname) { $sth = $dbh->prepare("select count(studid) from student where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $idcount = $sth->fetchrow; if (not $idcount){ $wd = "WD"; } } $trn = ''; # Check if records in transfer table (if missing...) if (not $localLastname) { $sth = $dbh->prepare("select count(id) from transfer where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $transcount = $sth->fetchrow; if (not $transcount){ $trn = "Trn"; } } print ""; print ""; print ""; print "\n"; $count++; } print "
LastnameFirstnameMiddlenameStudnumSask Lrn #
$mis $wd $trn $count: $lastname [$localLastname]$firstname [$localFirstname]$middlename [$localMiddlename]$studnum$provnum
\n"; } # End of Sub #---------------------- sub parseSPLite { # parse only for provnum #---------------------- my @studinfo = $root->findnodes('//sl:StudentPersonal'); foreach my $student (@studinfo){ my $provnum = $student->findvalue('sl:StudentIdentification/sl:DeptAssignedPersonId'); my $birthdate = $student->findvalue('sl:StudentIdentification/sl:BirthDate'); my $firstname = $student->findvalue('sl:StudentInfo/sl:Name/sl:FirstName'); my $lastname = $student->findvalue('sl:StudentInfo/sl:Name/sl:LastName'); my $middlename = $student->findvalue('sl:StudentInfo/sl:Name/sl:MiddleName'); $slname{$provnum} = "$lastname:$firstname:$middlename:$birthdate"; push @slprovnums, $provnum; } return @slprovnums; # return list of kids in SL enrollment list. } # End of parseSPLite; #---------------------- sub checkIdent { # Match local and provincial students #---------------------- my @studinfo = $root->findnodes('//sl:StudentPersonal'); #print "\n"; #print ""; #print "\n"; #my $count = 1; foreach my $student (@studinfo){ my $provnum = $student->findvalue('sl:StudentIdentification/sl:DeptAssignedPersonId'); my $birthdate = $student->findvalue('sl:StudentIdentification/sl:BirthDate'); my $firstname = $student->findvalue('sl:StudentInfo/sl:Name/sl:FirstName'); my $lastname = $student->findvalue('sl:StudentInfo/sl:Name/sl:LastName'); my $middlename = $student->findvalue('sl:StudentInfo/sl:Name/sl:MiddleName'); # Check for student record my $sth = $dbh->prepare("select studnum from student where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my ($localLastname, $localFirstname,$localMiddlename,$studnum) = $sth->fetchrow; if (not $localLastname) { $mis = "MIS"; } else { $mis=''; } # Check whether current or withdrawn. $wd = ''; if ($localLastname) { $sth = $dbh->prepare("select count(studid) from student where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $idcount = $sth->fetchrow; if (not $idcount){ $wd = "WD"; } } $trn = ''; # Check if records in transfer table (if missing...) if (not $localLastname) { $sth = $dbh->prepare("select count(id) from transfer where provnum = '$provnum'"); $sth->execute; if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my $transcount = $sth->fetchrow; if (not $transcount){ $trn = "Trn"; } } print ""; print ""; print ""; print "\n"; $count++; #print ""; #print ""; #print ""; } print "
LastnameFirstnameMiddlenameStudnumSask Lrn #
$mis $wd $trn $count: $lastname [$localLastname]$firstname [$localFirstname]$middlename [$localMiddlename]$studnum$provnum
First Name$firstname
Last Name$lastname
Prov Num$lastname
\n"; } # End of checkIdent #------------------- sub activateTransfer { # passed list of transfer recs to setup date/code selects. #------------------- require "$globdir/global.conf" or die "Cannot open global.conf!\n"; print "

Student Withdrawals / Enrollments

\n"; delete $arr{transferflag}; # Now run external and use existing updatetransfer.pl (modified to accept correct input) print "
\n"; if ($debug) { print "\n"; } print "\n"; print "\n"; my $sth1 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?"); my $sth2 = $dbh->prepare("select lastname, firstname from studentall where provnum = ?"); my $reccount = 1; # a counter for those without a provincial number.... my $enrolflag = 1; foreach my $key (sort keys %arr) { # key is #print "K:$key V:$arr{$key}
\n"; my ($EnWd, $rectype, @value) = split /:/, $key; my (@tr, $date, $code, $type, $firstname, $lastname, $birthdate, $provnum); if ($EnWd eq 'EN') { $type = 'enroll'; } else { $type = 'withdraw'; #print "\n"; } if ($rectype eq 'TR') { # we have a TR (transfer record), read the record... my $id = $value[0]; my $sth = $dbh->prepare("select * from transfer where id = ?"); $sth->execute($id); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } @tr = $sth->fetchrow; $date = $tr[2]; if ( $EnWd eq 'EN' ) { $code = $tr[5]; } else { $code = $tr[6]; } if ( $tr[14] ) { $provnum = $tr[14]; } else { my $sth3 = $dbh->prepare("select provnum from studentall where studnum = ?"); $sth3->execute($tr[1]); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } $provnum = $sth3->fetchrow; #print "PN:$provnum SN:$tr[1]
\n"; } # Get name; tr[1] is studnum; if ($tr[10]) { # we have a name in the transfer record... $lastname = $tr[10]; $firstname = $tr[11]; } else { $sth1->execute($tr[1]); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } ($lastname, $firstname) = $sth1->fetchrow; } } else { # we have a PN - prov number data in the name, birthdate values in @values ($provnum, $lastname, $firstname, $middlename, $birthdate) = @value; if (not $lastname) { # We only have the provincial number for a local record... my $sth = $dbh->prepare("select lastname, firstname, initial, birthdate from studentall where provnum = ?"); $sth->execute($provnum); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; } ($lastname, $firstname, $middlename, $birthdate) = $sth->fetchrow; } } if (not $provnum) { $provnum = $tempcount; } $tempcount++; print "\n\n"; print "\n"; } print "
NameProvNumTypeDate
yyyy-mm-dd
Reason
$reccount. $lastname, $firstname "; if ( $birthdate ) { print "($birthdate)"; } $reccount++; print "$provnum$type"; print ""; print "
\n"; print "
\n"; } # End of activateTransfer