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

#  This file is part of Open Admin for Schools.

my  %lex = ('Phone' => 'Phone',
	    'Report' => 'Report',
	    'Student' => 'Student',
	    'Main' => 'Main',
	    'Emergency' => 'Emergency',
	    'Parent 1' => 'Parent 1',
	    'Parent 2' => 'Parent 2',
	    'Student' => 'Student',
	    'Emergency' => 'Emergency',
	    'HRm' => 'HRm',
	    'Gr' => 'Gr',
	    'Work' => 'Work',
	    'Home' => 'Home',
	    'Cell' => 'Cell',
	    'Error' => 'Error',
	    'Blank=All' => 'Blank=All',
	    'Select by' => 'Select by',
	    'Continue' => 'Continue',
	    'Grade' => 'Grade',
	    'Homeroom' => 'Homeroom',
	    'Name' => 'Name',
	    'Group' => 'Group',
	    'Sort by' => 'Sort by',
	    );

use DBI;
use CGI;
use Cwd;

use Time::JulianDay;

my $self = 'atpRpt1.pl';

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

# Attendance Functions.
eval require "../../lib/libattend.pl";
if ( $@ ) {
    print $lex{Error}. ": $@<br>\n";
    die $lex{Error}. ": $@\n";
}

# Absent/Late strings for libattend library.
my %lexi = ('Absent' => 'Absent',
	    'Late' => 'Late'
    );


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);


# Get current dir so know what CSS to display;
if ( getcwd() =~ /tcgi/ ){ # we are in tcgi
    $css = $tchcss;
    $homepage = $tchpage;
}


my $title = qq{AttPlus (AAA) Report 1};
print qq{$doctype\n<html><head><title>$title</title>\n};
print qq{<link rel="stylesheet" href="$css" type="text/css">\n};
print qq{$chartype\n</head><body style="margin:1em;">\n};

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


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

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


#-------------
sub showReport {
#-------------    

    # Outline: 4 column table for each grade, floated. Attendance, academic, attitude, total
    
    # foreach my $key ( sort keys %arr ) { print "K:$key VAL:$arr{$key}<br>\n"; }
    # passed yrmo, group, skip
    
    my $yrmo = $arr{yrmo}; # year-month
    my $group = $arr{group};
    my $skip = $arr{skip};

    # those group members to skip over
    my %skip;
    my @skip = split(/\s/, $skip);
    foreach my $g ( @skip ) {
	$skip{$g} = 1;
    }
    
        
    my ($year,$month) = split('-', $yrmo);
    my $display = qq{$month[$month], $year};
   
    print qq{<h3>$display</h3>\n};

    # Get Previous Yr-Mo
    my ($prevyr, $prevmo, $prevyrmo);
    if ( $month == 1 ) {
	$prevmo = 12;
	$prevyr = $year - 1;
    } else {
	$prevmo = $month - 1;
	$prevyr = $year;
    }
    $prevyrmo = qq{$prevyr-$prevmo};
#    print qq{<div>Prev $prevyrmo</div>\n};
    
    
    my $startjd = julian_day(split('-',$schoolstart));
    my $endjd = julian_day(split('-',$schoolend));
    
    my $startdate = $yrmo. '-01';
    my $tempstart = julian_day(split('-',$startdate));
    if ( $startjd > $tempstart ) { # school start in this month (Sept) is later than the 1st.
	$startdate = join('-', inverse_julian_day($startjd));
    }
#    print qq{<div>Start Date:$startdate</div>\n};
    
    my $endday = (0,31,28,31,30,31,30,31,31,30,31,30,31)[$month]; # array is zero based
    if ( ($year % 4 == 0) && ($year % 100 != 0) && ($year % 400 == 0) ) {
	$endday++;
    }
    my $enddate = $yrmo. qq{-$endday};

    # Verify against school end date;
    my $tempend = julian_day(split('-',$enddate));
    if ( $tempend > $endjd ) { # school ends earlier than the end of the month
	$enddate = join('-', inverse_julian_day($endjd));
    }
 #   print qq{<div>End Date:$enddate</div>\n};

    # we have the start and end dates for the month. We CAN add
    # another arg with NSD or GR:grade for partial.  We don't want any
    # partial issues. If away in AM, but partial closed in PM, then we
    # give hime/her benefit of the doubt and they get 1/2 day credit.
    
    my $daysopen = calcDaysOpen($startdate, $enddate, $dbh);
    print qq{<div>Days Open $daysopen</div>\n};

    
    # find grades / homeroom
    my @groups;
    
    my $sth = $dbh->prepare("select distinct $group from student where $group is not NULL and $group != ''");
    $sth->execute;
    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
    while ( my $gr = $sth->fetchrow ) {
	if ( $skip{$gr} ) { next; } # skip over some member groups
	push @groups, $gr;
    }
    
    @groups = sort { $a<=>$b } @groups;
#    print qq{Groups:@groups<br>\n};
    
    
    my $sth = $dbh->prepare("select * from student where $group = ? order by lastname, firstname");

    # Get attitude,academic marks
    my $sth1 = $dbh->prepare("select score from atp_academic where studnum = ? and yrmo = ?");
    my $sth2 = $dbh->prepare("select score from atp_attitude where studnum = ? and yrmo = ?");
    my $sth3 = $dbh->prepare("select balfwd from atp_balfwd where studnum = ? and yrmo = ?");


    # Loop over group
    my ($count, $tcount);
    foreach my $grp ( @groups ) {

	my $first = 1;

	# get students
	$sth->execute($grp);
	if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}    
	while ( my $ref = $sth->fetchrow_hashref ) {
	    my %r = %$ref;
	    my $studnum = $r{studnum}; # needed in several placed

	    my $ppd = $g_ppd{ $r{grade} };
	    if ( not $ppd ) {
		print qq{<h3>No Attendance Periods per Day (PPD) for $r{firstname} $r{lastname} (${studnum}) };
		print qq{with grade  $r{grade}. Skipping!</h3>\n};
		next;
	    }


	    # if first, start table.
	    if ( $first ) {
		my $temp = ucfirst($group); # uppercase leading homeroom or grade
		print qq{<table border="1" cellpadding ="3" cellspacing="0" style="margin:1em;float:left;">\n};
		print qq{<caption style="font-weight:bold;font-size;120%;">$temp $grp</caption>\n};
		print qq{<tr><th>Name</th><th title="Previous month - Balance Forward">Prev<br>Bal</th>};
		print qq{<th title="Attendance">Attend</th><th title="Academic">Acad</th>};
		print qq{<th title="Attitude">Attd</th><th>Total</th></tr>\n};
#		print qq{<th title="Balance Forward">Bal<br>Fwd</th></tr>\n};
		$first = 0;
	    }

	    #  Academic score
	    $sth1->execute($studnum, $yrmo);
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}    
	    my $acscore = $sth1->fetchrow;

	    # Attitude
	    $sth2->execute($studnum, $yrmo);
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}    
	    my $atscore = $sth2->fetchrow;

	    # Balance Forward
	    $sth3->execute($studnum, $prevyrmo);  # Note Previous yrmo.
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}    
	    my $balfwd = $sth3->fetchrow;

	    
	    # Attendance Score
	    my $attendscore = calcMyAttendance($studnum, $yrmo, $ppd, $startdate, $enddate);
	    if ( not $attendscore ) { # not enrolled yet
		next;
	    }

	    my $total = $acscore + $atscore + $attendscore + $balfwd;

	    print qq{<tr><td><b>$r{lastname}</b>, $r{firstname}</td><td>$balfwd</td><td>$attendscore</td>};
	    print qq{<td>$acscore</td><td>$atscore</td><td>$total</td></tr>\n};
	    
	} # done all students in this group

	if ( $first ) {
	    print qq{<h3>No Students Found for group $group</h3>\n};
	} else {
	    print qq{</table>\n};
	}
	$tcount++;
	if ( $tcount % 3 == 0 ) {
	    print qq{<div style="clear:left;"></div>\n};
	}
	
	$count++;
	
	if ( $count % 1 == 0 ) {
	    print qq{<div style="page-break-after:always;"></div>\n};
	}
	

    } # end of groups

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

    exit;

} # end of showReport


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

   
    # Get the Year-Month for entry.
    my ($y,$m,$d) = split('-', $schoolstart); # loaded from admin.conf file
    my @yrmo; # ordered by year-month
    foreach my $m (9..12) { # do fall
	push @yrmo, qq{$y-$m};
    }
    $y++; # increment year
   
    foreach my $m (1..6) { # do fall
	push @yrmo, qq{$y-$m};
    }


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

    
    print qq{<table cellpadding="3" cellspacing="0" border="0" style="border:1px solid gray;padding:0.5em;">\n};
    print qq{<caption style="font-weight:bold;text-align:left;">Please Select Month</caption>\n};

    # Year-Month Select
    print qq{<tr>};
    print qq{<td class="la">};
    foreach my $yrmo ( @yrmo ) {
	my ($y,$m) = split('-', $yrmo);
	print qq{<input type="radio" name="yrmo" value="$yrmo"> $month[$m], $y<br>\n};
    }
    print qq{</td></tr>\n};

    print qq{<tr><td><hr></td></tr>\n};

    
    # Group by Homeroom or Grade.
    print qq{<tr><td class="bla">};
    print qq{Group by \n};
    print qq{<select name="group"><option value="homeroom">Homeroom</option>\n};
    print qq{<option value="grade">Grade</option>\n};
    print qq{</select></td></tr>\n};


    # Groups to skip
    print qq{<tr><td class="bla">};
    print qq{Skip these Groups <input type="text" name="skip" style="width:30ch;"></td></tr>\n};
    print qq{<tr><td class="ra">Separate with Spaces</td></tr>\n};


    
    print qq{</table>\n};

    # Continue
    print qq{<div style="margin:0.5em;"><input style="margin:0 2em;" type="submit" value="$lex{Continue}"></div>\n};

    print qq{</form>\n};

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

    exit;
}


#-----------------
sub calcMyAttendance { # monthly attendance
#-----------------

    # granularity is just the nearest 1/2 day for being present.
    
    my ($studnum, $yrmo, $ppd, $startdate, $enddate ) = @_;
#    print "SN:$studnum YRMO:$yrmo PPD:$ppd<br>\n";


    # find enrollment blocks, in this month. Adjust start,end dates, if so.
    my @enrolblock = findEnrollmentBlocks($studnum, $startdate, $enddate, $dbh);
    if ( not $enrolblock[0] ) { return; }

    my $present; # number of days present, calc'd in loop below
    my $sth = $dbh->prepare("select count(*) from attend where studentid = ? and absdate = ? and
       reason like '%Absent%'");
    
    my $sth1 = $dbh->prepare("select dayfraction from dates where date = ?");


    # We now have updated start/end dates based on enrollment; perhaps more than one enrollment block.
    foreach my $ref ( @enrolblock ) {
	my $start = $ref->{start};
	my $end = $ref->{end};
	
	my $sjd = julian_day(split('-',$start));
	my $ejd = julian_day(split('-',$end));

	# Loop over this enrollment block.
	foreach my $jd ( $sjd..$ejd ) { # loop over the julian days.
	    # skip any weekends.
	    my $dow = day_of_week($jd);
	    if ( $dow == 0 or $dow == 6 ) { next; }
	    my $date = join('-', inverse_julian_day($jd));

	    # Check for School Closed (all day).
	    $sth1->execute($date);
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	    my $dayfraction = $sth1->fetchrow; # closed all day?
	    if ( $dayfraction > 0.99 ) { next; }

	    
	    # Check for any absences.
	    $sth->execute($studnum, $date);
	    if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
	    my $percount = $sth->fetchrow; # count of periods absent.
	    my $attend;
	    if ( not $percount ) {
		$attend = 1;
	    } else { # partial day/ all day
		my $fraction = $percount / $ppd; # fraction absent
		if ( $fraction > 0.6 ) {
		    $attend = 0;
		} elsif ( $fraction > 0.3 ) {
		    $attend = 0.5;
		} else {
		    $attend = 0;
		}
	    }

#	    my $temp = join('-', inverse_julian_day($jd));
#	    print "Day:$temp Present:$present Attend:$attend<br>\n";
	    
	    $present += $attend;
	}


    } # end of enrollment blocks.
	
    return $present;
    
}
    
