#!/usr/bin/perl
#  Copyright 2001-2024 Leslie Richardson

#  This file is part of Open Admin for Schools.

#  Open Admin for Schools is free software; you can redistribute it 
#  and/or modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2 of 
#  the License, or (at your option) any later version.


#### transchk.pl - check transfer table for several kinds of mistakes.

my %lex = (
	   'Transfer' => 'Transfer',
	   'Check' => 'Check',
	   'Main' => 'Main',
	   'Error' => 'Error',
	   'Name' => 'Name',
	   'Current' => 'Current',
	   'Duplicate' => 'Duplicate',
	   'Student Number' => 'Student Number',
	   'Previous' => 'Previous',
	   'Update' => 'Update',
	   'Record(s) Updated' => 'Record(s) Updated',
	   'Continue' => 'Continue',
	   'Not Found' => 'Not Found',


	   );

my $self = 'transchk.pl';

use DBI;
use CGI;


# Read config variables
eval require "../../etc/admin.conf";
if ( $@ ) {
    print $lex{Error}. ": $@<br>\n";
    die $lex{Error}. ": $@\n";
}

my $q = new CGI;
print $q->header( -charset, $charset );
%arr = $q->Vars;

$dsn = "DBI:$dbtype:dbname=$dbase";
$dbh = DBI->connect($dsn,$user,$password);


# Page Head Section.
my $title = qq{$lex{Transfer} $lex{Check}};
    
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">$chartype\n</head><body>\n};

print qq{<a name="top"></a>[ <a href="$homepage">$lex{Main}</a> ]\n};

print qq{<h1>$title</h1>\n};


if ( $arr{page} ) {
    delete $arr{page};
    updateStudentNumber();
}


print qq{<h3>Duplicate Students Check - Transfer Records</h3>\n};

# Duplicates: Same last name, first name, different studnum.
my $sth = $dbh->prepare("select distinct studnum, lastname, firstname, birthdate, date
  from transfer order by lastname, firstname");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

my $sth1 = $dbh->prepare("select count(*) from studentall where studnum = ?");
my $sth2 = $dbh->prepare("select count(*) from student where studnum = ?");

# Start Form
print qq{<form action="$self" method="post">\n};
print qq{<input type="hidden" name="page" value="1">\n};


my $first = 1;
my ( $currname, $oldname);
my ( $currstudnum, $oldstudnum );
my ( $currbd, $oldbd );
my @students = ();


while ( my ( $studnum,  $lastname, $firstname, $birthdate, $date ) = $sth->fetchrow ){

    $oldstudnum = $currstudnum;
    $oldname = $currname;
    $oldbd = $currbd;
    $olddate = $currdate;

    $currstudnum = $studnum;
    $currname = $lastname. $firstname;
    $currbd = $birthdate;
    $currdate = $date;

    if ( $currname eq $oldname and $currstudnum != $oldstudnum ) {

	if ( $first ) {
	    
	    # Start Table
	    print qq{<div>$lex{Duplicate} $lex{'Student Number'}<br>Click Boxes for Numbers to Change</div>\n};
	    print qq{<table cellpadding="3" cellspacing="0" border="1">\n};
	    print qq{<tr><th>$lex{Name}</th><th>$lex{Current}</th><th>$lex{Previous}</th></tr>\n};

	    print qq{<tr><td colspan="3" style="text-align:center;">\n};
	    print qq{<input type="submit" value="$lex{Update}"></td></tr>\n};
	    $first = 0;
	}


	# check for any student record - currentstudnum
	$sth1->execute( $currstudnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $currcount = $sth1->fetchrow;

	$sth1->execute( $oldstudnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $oldcount = $sth1->fetchrow;


	# check for active student record - currentstudnum
	$sth2->execute( $currstudnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $activecurrcount = $sth2->fetchrow;

	$sth2->execute( $oldstudnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my $activeoldcount = $sth2->fetchrow;

	print qq{<tr><td><b>$lastname</b>, $firstname</td>\n};
	print qq{<td>$currstudnum };
	print qq{StudRecs:$currcount Active:$activecurrcount\n};
	print qq{ $currdate <input type="checkbox" name="$oldstudnum:$currstudnum" value="1"></td>\n};

	print qq{<td>$oldstudnum };
	print qq{StudRecs:$oldcount Active:$activeoldcount\n};
	print qq{ $olddate <input type="checkbox" name="$currstudnum:$oldstudnum" value="1"></td></tr>\n};

    }

}

if ( not $first ) {
    print qq{<tr><td colspan="3" style="text-align:center;">\n};
    print qq{<input type="submit" value="$lex{Update}"></td></tr>\n};
    print qq{</table></form>\n};
} else {
    print qq{<p>$lex{Duplicate} $lex{'Student Number'} - OK</p>\n};
}

#-------------------------- Next Test -----------------------

print qq{<h3>Transfer Record Count Check</h3>\n};

# Now check for numbers of records, and ordering
$sth = $dbh->prepare("select distinct studnum from transfer order by lastname, firstname");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

$sth1 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");
$sth2 = $dbh->prepare("select count(*) from student where studnum = ?");
$sth3 = $dbh->prepare("select count(*) from transfer where studnum = ?");
$sth4 = $dbh->prepare("select id, date, type from transfer where studnum = ? order by date ");


my %hasStudRec = (); # track studnums in transfer that Have matching student records. 
# Then later find those who don't... (and remove?)

my $count = 1;
while ( my $studnum = $sth->fetchrow ) {

    # Find if active (ie. current student )
    $sth2->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $active = $sth2->fetchrow;

    # Find out if any student records ($hasStudRec) (and get name, if possible )
    $sth1->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my ($lastname, $firstname ) = $sth1->fetchrow;
    if ( $lastname ) { 
	$hasStudRec{$studnum} = 1;
    } else { # try a transfer record for a name

	my $sth5 = $dbh->prepare("select lastname, firstname from transfer where studnum = ?");
	$sth5->execute( $studnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	while (($lastname, $firstname ) = $sth5->fetchrow ) {
	    if ( $lastname ) { last; }
	}
	if ( not $lastname ) { $lastname = qq{<span style="color:red;">$lex{'Not Found'}</span>}; }

    }

    # Check for number of enrollment records (even for withdrawn studs; odd for active)
    $sth3->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $transcount = $sth3->fetchrow;

    if ( $transcount % 2 == 0 and $active ) { # even num; mistake
	print qq{$count. $lex{Error}: Transfers Uneven: };
	print qq{$transcount - Active:$active $firstname $lastname ($studnum)<br>\n};
	$count++;
    } 
    if ( $transcount % 2 == 1 and not $active ) { # odd num; mistake
	print qq{$count. $lex{Error}: Transfers Uneven: $transcount };
	print qq{- Active:$active $firstname $lastname ($studnum)<br>\n};
	$count++;
    } 


}




# ----------- Test for WD students having transfer records
print qq{<h3>Withdrawn Student without Transfer Records</h3>\n};
$first = 1;

# Now check for numbers of records, and ordering
$sth = $dbh->prepare("select studnum from studentall order by lastname, firstname");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

$sth1 = $dbh->prepare("select count(*) from transfer where studnum = ?");
$sth3 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");


while ( my $studnum = $sth->fetchrow ) {
    $sth1->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $transcount = $sth1->fetchrow;

    if ( not $transcount ) {

	$first = 0;
	$sth3->execute( $studnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth3->fetchrow;

	print qq{Missing Transfer records for: $firstname $lastname ($studnum)<br>\n};
    }
}
if ( $first ) { print qq{<p>No Students without Transfer Records</p>\n}; }




#------- Test for Initial / Final Transfer Record Error
print qq{<h3>Initial / Final Transfer Check</h3>\n};
my $first = 1;

# Now check for numbers of records, and ordering
$sth = $dbh->prepare("select distinct studnum from transfer order by lastname, firstname");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

$sth1 = $dbh->prepare("select type from transfer where studnum = ? order by date");
$sth2 = $dbh->prepare("select type from transfer where studnum = ? order by date desc");
$sth3 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");
$sth4 = $dbh->prepare("select count(*) from student where studnum = ?");

my $count = 1;
while ( my $studnum = $sth->fetchrow ) {

    # Get First Record
    $sth1->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $firsttranstype = $sth1->fetchrow;

    if ( $firsttranstype eq 'withdraw' ) { # Error

	$first = 0;
	$sth3->execute( $studnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth3->fetchrow;

	print qq{Initial Transfer Record for: $firstname $lastname ($studnum) is a withdrawal!<br>\n};
    }


    # Get Last Record
    $sth2->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $lasttranstype = $sth2->fetchrow;

    # Find if active (ie. current student )
    $sth4->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
    my $active = $sth4->fetchrow;

    if ( ( $active and $lasttranstype eq 'withdraw' ) or 
	 ( not $active and $lasttranstype ne 'withdraw' )) {

	$first = 0;
	$sth3->execute( $studnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	my ($lastname, $firstname) = $sth3->fetchrow;

	print qq{Current Enrollment Error for: $firstname $lastname ($studnum)<br>\n};
    }

}

if ( $first ) { print qq{<p>First / Last Transfers OK</p>\n}; }



#--------- Test for Doublet Transfers (2 in 1 day).
print qq{<h3>Transfer Doublet Error Check</h3>\n};

$sth = $dbh->prepare("select distinct studnum from transfer order by lastname, firstname");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

$sth1 = $dbh->prepare("select distinct date, count(*) from transfer where studnum = ? group by date");

$sth3 = $dbh->prepare("select lastname, firstname from studentall where studnum = ?");


my $count = 1;
while ( my $studnum = $sth->fetchrow ) {

    # Transfer Doublet Check
    $sth1->execute( $studnum );
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }

    while ( my ($date, $trcount ) = $sth1->fetchrow ) {

	if ( $trcount > 1 ) {

	    $sth3->execute( $studnum );
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
	    my ($lastname, $firstname) = $sth3->fetchrow;

	    $first = 0;
	    print qq{Double Transfer Record for: $firstname $lastname ($studnum) - $date - $trcount<br>\n};
	}
    }
}

if ( $first ) { print qq{<p>Double Record Checks - OK</p>\n}; }

print qq{</body></html>\n};




#----------------------
sub updateStudentNumber { # Update Student Numbers
#----------------------

    #foreach my $key (sort keys %arr){ print qq{K:$key V:$arr{$key}<br>\n}; }

    my $sth = $dbh->prepare("update transfer set studnum = ? where studnum = ?");

    foreach my $key (keys %arr){

	my ( $toStudnum, $fromStudnum ) = split /:/, $key;
	if ( not $toStudnum or not $fromStudnum ) { 
	    print qq{Missing Error!<br>\n};
	    next; 
	}

	$sth->execute( $toStudnum, $fromStudnum );
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}

    }

    print qq{<h1>$lex{'Record(s) Updated'}</h1>\n};

    # Start Form
    print qq{<form action="$self" method="post">\n};
    print qq{<input type="submit" value="$lex{Continue}"></form>\n};


    print qq{</body></html>\n};

    exit;

}
