#!/usr/bin/perl
#  Copyright 2001-2021 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.


my %lex = ('Staff' => 'Staff',
	   'Preregistration' => 'Preregistration',
	   'Main' => 'Main',
	   'Eoy' => 'Eoy',
	   'Staff Member' => 'Staff Member',
	   'User Id' => 'User Id',
	   'Home' => 'Home',
	   'Room' => 'Room',
	   'Course' => 'Course',
	   'Edit' => 'Edit',
	   'Delete' => 'Delete',
	   'Error' => 'Error',
	   'Grade' => 'Grade',
	   'Access' => 'Access',
	   'Position' => 'Position',
	   'Count' => 'Count',
	   'Red' => 'Red',
	   'Absence' => 'Absence',
	   'Reason' => 'Reason',
	   'Day' => 'Day',
	   'Part' => 'Part',
	   'Save' => 'Save',
	   'Date' => 'Date',
	   'AM' => 'AM',
	   'PM' => 'PM',
	   'All Day' => 'All Day',
	   'Record Exists' => 'Record Exists',
	   'Skipping' => 'Skipping',
	   'Record Stored' => 'Record Stored',
	   'Absent' => 'Absent',
	   'Continue' => 'Continue',
	   'No Entry' => 'No Entry',
	   'Out of Range' => 'Out of Range',
	   'Invalid Date' => 'Invalid Date',
	   'Missing' => 'Missing',
	   'Other' => 'Other',
	   'Late' => 'Late',
	   
	   );


my $self = 'staffabsadd.pl';

my @dayparts; # put in translated values, if necessary.
foreach my $dp ( 'AM', 'PM', 'All Day' ) {
    push @dayparts, $lex{$dp};
}


use DBI;
use CGI;
use Time::JulianDay;

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

# Load audit write function
eval require "../../lib/libaudit.pl";
if ( $@ ) {
    print $lex{Error}. ": $@<br>\n";
    die $lex{Error}. ": $@\n";
}


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


my $dsn = "DBI:$dbtype:dbname=$dbase";
my $dbh = DBI->connect($dsn,$user,$password);
$dbh->{mysql_enable_utf8} = 1;


my @tim = localtime(time);
my $year = $tim[5] + 1900;
my $month = $tim[4] + 1;
my $day = $tim[3];
if (length($month) == 1){ $month = "0".$month;}
if (length($day) == 1){ $day = "0".$day;}
my $currdate = "$year-$month-$day";


# Print Page Header
my $title = "Add $lex{Staff} $lex{Absence}";

print qq{$doctype\n<html><head><title>$title</title>
<link rel="stylesheet" href="$css" type="text/css">
$chartype\n};

if ( not $arr{page} ) { # date function
    print qq{<link rel="stylesheet" type="text/css" media="all" };
    print qq{href="/js/calendar-blue.css" title="blue">\n};
    print qq{<script type="text/javascript" src="/js/calendar.js"></script>\n};
    print qq{<script type="text/javascript" src="/js/lang/calendar-en.js"></script>\n};
    print qq{<script type="text/javascript" src="/js/calendar-setup.js"></script>\n};
}


print qq{</head>\n<body style="padding:1.5em;">[ <a href="$homepage">$lex{Main}</a> ]\n};

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


if ( not $arr{page} ) {
    showStartPage();

} elsif ( $arr{page} == 1 ) {
    delete $arr{page};
    confirmEntry();

} elsif ( $arr{page} == 2 ) {
    delete $arr{page};
    writeRecords();
}



#----------------
sub showStartPage {
#----------------

    my $sth1 = $dbh->prepare("select field_value from staff_multi
     where field_name = ? and userid = ?");

    # select values from staff/prereg_staff table.
    $sth = $dbh->prepare("select id, lastname, firstname, userid
     from staff order by lastname, firstname");
    $sth->execute;
    if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
    

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

    # Get the date
    print qq{<table style="padding:1em;font-weight:bold;font-size:120%;border:1px solid black;">\n};
    print qq{<tr><td>$lex{Absent} $lex{Date}\n};
    print qq{<input type="text" name="date" id="date" size="10" value="$currdate">\n};
    print qq{<button type="reset" id="start_trigger">...</button></td></tr></table>\n};


    print qq{<table cellpadding="3" border="1" cellspacing="0">\n};
    print qq{<tr><th>$lex{'Staff Member'}</th><th>$lex{'User Id'}</th><th>$lex{Position}</th>\n};
    print qq{<th>$lex{Day}<br>$lex{Part}</th><th>$lex{Reason}</th>};
    print qq{<th>$lex{Reason}<br>$lex{Other}</th><th>$lex{Late}<br>(minutes)</th></tr>\n};

    print qq{<tr><td colspan="7" class="la"><input type="submit" value="$lex{Continue}"></td></tr>\n};
    
    while ( my ( $id, $lastname, $firstname, $userid ) = $sth->fetchrow) {

	# Load Positions (Jobs)
	$sth1->execute( 'position', $userid );
	if ($DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $positions;
	my $first = 1;
	while ( $pos = $sth1->fetchrow ) {
	    if ( not $first ) { $positions .= ', '; } else { $first = 0; }
	    $positions .= $pos;
	}


	print qq{<tr><td><b>$lastname</b>, $firstname</td><td>$userid</td><td>$positions</td>\n};

	# Day Parts
	print qq{<td><select name="F:$userid"><option></option>\n};
	foreach my $part ( @dayparts ) { # defined at top; also translated.
	    print qq{<option>$part</option>};
	}
	print qq{</select></td>\n};


	# Absence Reasons
	print qq{<td><select name="R:$userid"><option></option>\n};
	foreach my $rsn ( @g_StaffAbsReason ) {
	    print qq{<option>$rsn</option>};
	}
	print qq{</select></td>\n};

	# Other Reason
	print qq{<td><input type="text" name="O:$userid" size="12"></td>};
    
	# Late Minutes
	print qq{<td><input type="text" name="L:$userid" size="5"></td>};

	print qq{</tr>\n};

    }

    print qq{<tr><td colspan="7" class="la"><input type="submit" value="$lex{Continue}"></td></tr>\n};
    
    print qq{</table></form>\n};

    print qq{<script type="text/javascript">
     Calendar.setup({
      inputField     :    "date", // id of the input field
      ifFormat       :    "%Y-%m-%d", // format of the input field
      button         :    "start_trigger", // trigger for the calendar (button ID)
      singleClick    :    false,        // double-click mode
      step           :    1             // show all years in drop-down boxes
      });
     </script>\n};

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

    exit;
} # end of showStartPage


#---------------
sub confirmEntry {
#---------------

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

    print qq{<h3>Absence Confirmation</h3>\n};

    my $date = $arr{date};
    delete $arr{date};

    # Check Date for not in future and within current school year, and validity.
    if ( not checkdate( $date ) ) { 
	print qq{<h3>$lex{'Invalid Date'}</h3>\n};
	print qq{</body></html>\n};
	exit;
    }

    my $currjd = julian_day( split('-', $currdate));	
    my $startjd = julian_day( split('-', $schoolstart)); # global var
    my $datejd = julian_day( split('-', $date));
    if ( $datejd > $currjd + 7 or $datejd < $startjd ) {
	print qq{<h3>$lex{Error}: $lex{Date} $lex{'Out of Range'}</h3>\n};
	print qq{</body></html>\n};
	exit;
    }


    # Checking for existing records.
    my $sth1 = $dbh->prepare("select count(*) from staff_absent where 
			     adate = ? and daypart = ? and userid = ?");

    # Get Staff Name
    my $sth2 = $dbh->prepare("select lastname, firstname from staff where userid = ?");


    my $first = 1;

    foreach my $key ( sort keys %arr ) {
	if ( not $arr{$key} ) { next; } # skip if no value

	my ( $type, $userid ) = split(':', $key);
	if ( $type ne 'R' ) { next; } # skip if not a reason field

	my $latekey = qq{L:$userid};
	my $otherkey = qq{O:$userid};
	my $daypartkey = qq{F:$userid};

	my $daypart = $arr{$daypartkey};
	my $other = $arr{$otherkey};
	my $late = $arr{$latekey};


	# Get Name
	$sth2->execute( $userid );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my ( $lastname, $firstname ) = $sth2->fetchrow;


	# Check each userid group for completeness
	if ( not $daypart ) { 
	    print qq{<h3>$lex{Error}: $lex{Missing} $lex{Day} $lex{Part}; $firstname $lastname</h3>\n};
	    next;
	}

	if ( $arr{$key} eq 'Other (specify)' and not $other ) { 
	    print qq{<h3>$lex{Error}: $lex{Missing} $lex{Reason}: $firstname $lastname</h3>\n};
	    next;
	}


	# Check for an existing record for this userid for this date and for this day part.
	$sth1->execute($date, $lex{AM}, $userid );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $amcount = $sth1->fetchrow;

	$sth1->execute($date, $lex{PM}, $userid );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $pmcount = $sth1->fetchrow;

	$sth1->execute($date, $lex{'All Day'}, $userid );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $alldaycount = $sth1->fetchrow;

	# print qq{AM:$amcount PM:$pmcount ALL DAY:$alldaycount<br>\n};

	# not efficient but easier to understand.
	if ( $daypart eq $lex{AM} and ($amcount or $alldaycount) ) {
	    print qq{<h3>$lex{Error}: $lex{'Record Exists'}; };
	    print qq{$date - $userid - $daypart; $lex{Skipping}</h3>\n};
	    next;
	}

	if ( $daypart eq $lex{PM} and ($pmcount or $alldaycount) ) {
	    print qq{<h3>$lex{Error}: $lex{'Record Exists'}; };
	    print qq{$date - $userid - $daypart; $lex{Skipping}</h3>\n};
	    next;
	}

	if ( $daypart eq $lex{'All Day'} and ($amcount or $alldaycount or $pmcount) ) {
	    print qq{<h3>$lex{Error}: $lex{'Record Exists'}; };
	    print qq{$date - $userid - $daypart; $lex{Skipping}</h3>\n};
	    next;
	}

	if ( $first ) {
	    print qq{<table cellpadding="3" border="1" cellspacing="0">\n};
	    print qq{<tr><th>$lex{'Staff Member'}</th><th>$lex{Date}</th>};
	    print qq{<th>$lex{Day}<br>$lex{Part}</th><th>$lex{Reason}</th></tr>\n};
	    $first = 0;
	}


	print qq{<tr><td>$firstname $lastname ($userid)</td><td>$date</td>};
	print qq{<td>$daypart</td><td>$arr{$key}</td></tr>\n};

    }

    if ( $first ) {
	print qq{<h3>$lex{'No Entry'}</h3>\n};
	print qq{</body></html>\n};
	exit;

    } else { 
	print qq{</table>\n};
    }


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

    # Write the hidden values for next page
    print qq{<input type="hidden" name="date" value="$date">\n};
    foreach my $key ( sort keys %arr ) {
	if ( not $arr{$key} ) { next; } # skip if no value
	print qq{<input type="hidden" name="$key" value="$arr{$key}">\n};
    }

    print qq{<input type="submit" value="$lex{Save}">\n};
    print qq{</form>\n};

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

    exit;

}


#---------------
sub writeRecords {
#---------------

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

    my $date = $arr{date};
    delete $arr{date};

    my $fields = qq{userid, lastname, firstname, adate, reason, daypart, other, late, comment};
    my $qst = "?,?,?,?,?,?,?,?,?";
    my $sth = $dbh->prepare("insert into staff_absent ( $fields ) values( $qst )");

    my $sth1 = $dbh->prepare("select lastname, firstname from staff where userid = ?");
    my $sth2 = $dbh->prepare("select * from staff_absent where userid = ? and adate = ?");
    
    foreach my $key ( sort keys %arr ) {
	if ( not $arr{$key} ) { next; } # skip if no value

	my ( $type, $userid ) = split(':', $key);
	if ( $type ne 'R' ) { next; } # skip if not a reason field

	my $latekey = qq{L:$userid};
	my $otherkey = qq{O:$userid};
	my $daypartkey = qq{F:$userid};

	my $daypart = $arr{$daypartkey};
	my $other = $arr{$otherkey};
	my $late = $arr{$latekey};

	# Get Name
	$sth1->execute( $userid );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my ( $lastname, $firstname ) = $sth1->fetchrow;

	# Insert Record ( staff absent )
	$sth->execute( $userid, $lastname, $firstname, $date, $arr{$key}, $daypart,
		       $other, $late, NULL ); # no comment yet.
	
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	print qq{<div>$lex{'Record Stored'}: $firstname $lastname - $date - $daypart</div>\n};

	# Load Current Record for audit
	$sth2->execute( $userid,$date );
	if (DBI::errstr) { print $DBI::errstr; die $DBI::errstr; }
	my $startref = $sth2->fetchrow_hashref;
	my $recid = $startref->{id};
	my %r = %$startref;
	
	# print "StartREF:$startref\n";
	#foreach my $key ( sort keys %r ) {
	#    print "K:$key VAL:$r{$key}<br>\n";
	#}
	
	
	my %audit;
	$audit{userid} = $ENV{REMOTE_USER};
	$audit{ipaddr} = $ENV{REMOTE_ADDR};
	$audit{scriptname} = $self;
	$audit{tablename} = 'staff_absent';
	$audit{tableid} = $startref->{id};
	#$audit{startval} = $startref; # nothing to start, data to end
	$audit{endval} = $startref;

	addAudit( \%audit, $dbh );

	# print qq{<h3>$lex{Audit} $lex{'Record Stored'}</h3>\n};
    }

    print qq{<p>[ <a href="$homepage">$lex{Main}</a> | \n};
    print qq{ <a href="$self">$title</a> ]</p>\n};

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

    exit;

} # End of writeRecords



#------------
sub checkdate {  # check date for validity
#------------

    my @mdays = (0,31,28,31,30,31,30,31,31,30,31,30,31);
    my $maxyear = 2100;

    my $val = shift;

    if ( not $val =~ m/-/ ) {  # fail if no hyphens
	return undef;
    }

    # Strip Spaces
    $val =~ s/^\s+//g;
    $val =~ s/\s+$//g;

    my ( $year, $month, $day) = split(/-/, $val);


    # Check for non-digits
    if ($year =~ m/\D/) { return undef; }
    if ($month =~ m/\D/) { return undef; }
    if ($day =~ m/\D/) { return undef; }

    # reset Feb max days, if leap years
    if ($month == 2) {
	if ($year % 4 != 0) { $mdays[2] = 28; }
	elsif ($year % 400 == 0) { $mdays[2] = 29; }
	elsif ($year % 100 == 0) { $mdays[2] = 28; }
	else { $mdays[2] = 29; }
    }

    # check ranges
    if ( $day < 0 or $day > $mdays[$month] ) { # days out of range
	return undef;
    } elsif ( $month < 0 or $month > 12 ) { # month error
	return undef;
    } elsif ( $year < 0 or $year > $maxyear ) {
	return undef;
    }

    return $val;

}


