# Lib Schedule
# Functions:
# findDayInCycle - IN: date OUT: an integer for DayInCycle
# fillDate - IN: isodate(1-1-2005) OUT: full isodate (01-01-2005)
# findFutureClass - find a future class (subjsec)
# IN - date, subjsec, classtimes,
# RETURN - period, date.
# prTeacherTimetable - IN: term,subjectref(ref to subjsec array)
# - prints timetable.
# mkTimetable
#-----------------
sub findDayInCycle {
#-----------------
use Date::Business;
use Time::JulianDay;
my $givendate = fillDate( shift ); # Passed a date to find day in cycle.
# If database handle not available, look for passed value...
if (not $dbh) {
$dbh = shift;
}
# Check if given date is a non cycle day. If so return 0.
my $sth = $dbh->prepare("select count(id) from dates where
dayincycle = 'N' and to_days(date) = to_days('$givendate')");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
if (my $count = $sth->fetchrow){
return 0;
}
# Check for Resets
my ($resetdate, $resetvalue);
# Check for starting value... first day of classes.
my $startdate = fillDate($schoolstart);
my $continueFlag = 1;
while ($continueFlag) {
# Check if given date is a non cycle day. If so return 0.
my $sth = $dbh->prepare("select count(id) from dates where
dayincycle = 'N' and to_days(date) = to_days('$startdate')");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
if (my $count = $sth->fetchrow){
# bump the date and try again...
my ($yr, $mo, $da) = split /-/,$startdate;
my $jd = julian_day($yr, $mo,$da);
$jd++;
($yr, $mo, $da) = inverse_julian_day($jd);
$startdate = fillDate("$yr-$mo-$da");
} else {
$continueFlag = 0;
}
}
#print "Start Date: $startdate
\n";
# Now use the $startdate value as Day 1
$resetdate = $startdate;
$resetvalue = 1;
$resetdatejd = julian_day(split /-/,$resetdate);
$givendatejd = julian_day( split /-/,$givendate);
foreach my $rdate (keys %resetDate){
$rdatejd = julian_day(split /-/,$rdate);
if ($rdatejd > $resetdatejd and $rdatejd <= $givendatejd){
$resetdate = $rdate;
$resetvalue = $resetDate{$resetdate};
}
}
#print "
Reset Date: $resetdate Reset Value: $resetvalue
\n";
my $tmpgivendate = $givendate;
my $tmpresetdate = $resetdate;
$tmpgivendate =~ s/-//g;
$tmpresetdate =~ s/-//g;
my $givendateobj = new Date::Business(DATE => $tmpgivendate);
my $resetdateobj = new Date::Business(DATE => $tmpresetdate);
$givenoffset = $givendateobj->diffb($resetdateobj,'prev','next');
#print "GivenOffset: $givenoffset\n";
my $count;
# remove any non DayInCycle days
$sth = $dbh->prepare("select count(id) from dates where
dayincycle = 'N' and
to_days(date) > to_days('$resetdate') and
to_days(date) <= to_days('$givendate')");
$sth->execute;
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr; }
$count = $sth->fetchrow;
my $daysBetween = $givenoffset - $count;
#print "Count: $count daysBetween: $daysBetween\n";
# Now use mod function to get remainder.
if (not $daysPerCycle){
print "daysPerCycle variable not defined in admin.conf!";
die;
}
my $remainder = $daysBetween % $daysPerCycle;
#print "Days Between: $daysBetween Remainder: $remainder ";
#print "daysPerCycle: $daysPerCycle
\n";
$remainder += $resetvalue;
if ($remainder > $daysPerCycle){
$remainder = $remainder % $daysPerCycle;
}
return $remainder;
} # End of findDayInCycle
#-----------
sub fillDate { # Fill in date values of form: 2006-1-1 into 2006-01-01
#-----------
my $fulldate = shift;
my ($year, $month, $day) = split /-/,$fulldate;
if (length($month) == 1){ $month = '0'.$month;}
if (length($day) == 1){ $day = '0'.$day;}
return "$year-$month-$day";
}
#------------------
sub findFutureClass {
#------------------
# passed startdate, startperiod, userid, term, subjsec, $skipclasses
# return futuredate (fdate), fperiod(fperiod)
my ($startdate, $startperiod, $userid, $term, $subjsec, $skipclasses) = @_;
my $subjref = &mkTimetable($userid, $term);
my $days = $#{$subjref};
my $periods = $#{$subjref->[1]};
my $day = &findDayInCycle($startdate);
# Loops to construct array of periods, @slots
for my $d (1..$days) {
for my $p (1..$periods){
#print "Sub: ${$subjref}[$p][$d]Subjsec: $subjsec\n";
if (${$subjref}[$p][$d] eq $subjsec){
push @slots, "$d:$p";
}
#print "$d:$p ${$subjref}[$p][$d] ";
}
}
# test @slots
# foreach my $slot (@slots){ print "$slot\n"; }
# Find starting point in array
for (0..$#slots){
if ($slots[$_] eq "$day:$startperiod"){
# print "Match for $slots[$_]\n";
$currindex = $_;
last;
}
}
if (not defined $currindex){
print "No match for Day $day Period $startperiod";
die;
}
my $cyclesize = $#slots + 1;
my $nextindex = $currindex + 1;
my $totaldays;
#print "DpC: $daysPerCycle Classes per Cycle: $cyclesize\n";
# print "SkipClasses: $skipclasses\n";
# Loop through to calc the number of days to skip.
for (1..$skipclasses){ # how many jumps
my ($currday,$cp) = split /:/,$slots[$currindex];
my ($nextday,$np) = split /:/,$slots[$nextindex];
my $jumps = $nextday - $currday;
if ($jumps < 0){ $jumps += $daysPerCycle;}
$totaldays += $jumps;
$currindex++;
if ($currindex > $cyclesize){ $currindex = 0;}
$nextindex++;
if ($nextindex > $cyclesize){ $nextindex = 0;}
}
$startdate =~ s/-//g;
my $startdateobj = new Date::Business(DATE => $startdate);
my $sth = $dbh->prepare("select count(id) from dates
where date = ? and dayincycle = 'N'");
my ($nd,$i);
while ($i < $totaldays){
$startdateobj->nextb;
$nd = $startdateobj->image();
# print "ND: $nd\n";
$sth->execute($nd);
$count = $sth->fetchrow;
if (not $count){ $i++;}
}
#print "Final: $nd\n";
return $nd;
}
#--------------
sub prTeacherTimetable { # print timetable for 1 teacher for 1 term.
#--------------
my ($term, $subjref) = @_; # passed term and ref to subjects.
# Prep for loop finding the subjects
my $sth = $dbh->prepare("select day, period from schedat
where term = '$term' and subjsec = ? ");
my @subject;
#loop through all subject-sections
foreach my $subjsec (@{$subjref}){
$sth->execute($subjsec);
if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;}
# Create 2D subject array (of [period][day] indexes)
while (my ($day, $period) = $sth->fetchrow){
if ($subject[$period][$day] != $subjsec){
$subject[$period][$day] .= "$subjsec ";
}
}
}
my $tblrows = $#subject;
my $tblcols;
for $i (1..$tblrows){
if ($#{$subject[$i]} > $tblcols){ $tblcols = $#{$subject[$i]};}
}
$sth = $dbh->prepare("select description,smdesc from subject
where subjsec = ?");
print "
| "; for (1..$tblcols){ print " | Day $_ | "; } print "|
|---|---|---|
| Period $i | "; for (1..$tblcols){ if ($subject[$i][$_]){ # if we have a subjsec value; my $firstflag = 1; @subjval = split /\s/,$subject[$i][$_]; print "";
foreach my $sv (@subjval){
if (not $firstflag){ print " ";} else { $firstflag = 0;} $sth->execute($sv); if ($DBI::errstr){ print $DBI::errstr; die $DBI::errstr;} my ($description,$smdesc) = $sth->fetchrow; if (not $smdesc){ $smdesc = substr($description,0,8);} print "$smdesc ($sv)"; } print " | ";
} else {
print "No Value | "; } } print "