Subversion Repositories ORC

Compare Revisions

No changes between revisions

Ignore whitespace Rev 48 → Rev 49

/tags/2022.final/RCUtil/activate_classes.pl
0,0 → 1,11
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use DBI;
use WebDB;
 
my $dbh = WebDB::connect;
 
$dbh->do ("update setting set value = ? where setting.key = ?", undef, 0, "MAX_CLASS_SIGNUP");
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/RCUtil/annual_volhours_confirmation_email.pl
0,0 → 1,96
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use tableViewer;
use DateTime;
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
 
my $dt = DateTime->today;
my $day = $dt->day_name;
my $date = $dt->date;
 
my $dbh = getDBConnection ();
my $DEPT = getDepartments ();
 
my $RCidListQuery=<<endRCidListQuery;
select distinct RCid from (
select distinct RCid from v_shift where year(date) = year(curdate()) and dept <> "PER" and dept <> "CLA" union
select distinct RCid from v_shift_announcer where year(date) = year(curdate()) union
select distinct RCid from v_shift_officiating where year(date) = year(curdate())
) t1
where RCid <> ''
order by cast(RCid as unsigned)
endRCidListQuery
my $sth1 = $dbh->prepare($RCidListQuery);
 
my $SchedQuery=<<endSchedQuery;
select * from (
select id, date, dayofweek, location, time, volhours, dept, role, '' as teams from v_shift where year(date) = year(curdate()) and RCid = ? and dept <> "PER" and dept <> "CLA" union
select id, date, dayofweek, track as location, time, volhours, "ANN" as dept, role, teams from v_shift_announcer where year(date) = year(curdate()) and RCid = ? union
select id, date, dayofweek, track as location, time, volhours, "OFF" as dept, role, teams from v_shift_officiating where year(date) = year(curdate()) and RCid = ?
) temp
order by date, time
endSchedQuery
my $sth2 = $dbh->prepare($SchedQuery);
 
$sth1->execute();
while (my ($RCid) = $sth1->fetchrow_array()) {
my $email = getUserEmail($RCid);
my $dname = getUserDerbyName($RCid);
my @shifts = ();
my $hours;
$sth2->execute($RCid, $RCid, $RCid);
while (my $S = $sth2->fetchrow_hashref()) {
push @shifts, $S;
$hours += $S->{volhours};
}
my $message = $h->p ("Greetings $dname,", "Thanks for all your hard work at RollerCon. Here are the volunteer hours we captured for you:");
 
$message .= $h->table ([
map { $h->tr ([ $h->td ( $_->{date},
$_->{dayofweek},
$_->{time},
$_->{volhours}." hr(s)",
$DEPT->{$_->{dept}},
$_->{role},
$_->{teams} ) ]) } @shifts
]);
$message .= $h->b ($hours." TOTAL HOURS");
# foreach (@shifts) {
# $message .= join " ", $_->{date}, sprintf ("%-9s", $_->{dayofweek}), $_->{time}, sprintf ("%-12s", $_->{volhours}." hr(s)"), $DEPT->{$_->{dept}}, $_->{role}, $_->{teams}."\n";
# $message .= "$_->{date} $_->{dayofweek} $_->{time} $_->{volhours} hr(s) $DEPT->{$_->{dept}} $_->{role} $_->{teams}\n";
# }
$message .= $h->p (
"Do you see any discrepancies? If so, please report them ".$h->a ({ href=>"https://docs.google.com/forms/d/e/1FAIpQLSdbzcuEz2k_6ycf826-R3lGc3L37mfENUm7pQXxlFPb2LlvWA/viewform"}, "HERE")." before August 31st. We'll update our records based on your form entries, and you will see the updates on your home page in VORC. Entries made after August can't be updated in VORC. So maybe you should update it now - it's a short form!",
"Then in October, we'll send out free / discounted info for RollerCon 2023 to the email you listed in your profile in ".$h->a ({ href=>"https://volunteers.rollercon.com/schedule/" }, "VORC").". Thanks again. You're the one who keeps RollerCon rolling!!!!",
$h->a ({ href=>"https://rollercon.com/help-wanted/" }, "More about freebies & discounts"),
$h->hr.$h->p ({ style=>"text-align:center" }, $h->b ("Volunteer Compensation")).$h->hr,
"All RollerCon volunteers get cool stuff at RollerCon, including a raffle ticket, limited-edition volunteer-only tee (while they last), and other schwag, snacks, goodwill and more every year, plus cool stuff from our sponsors.",
$h->ul ([
$h->li (
$h->b ("10-25 hours")." qualifies you for a discounted pass that can be redeemed at a lower price than we ever sell until June.",
$h->b ("Over 25 hours")." gets you a free pass plus all the other stuff above."
)
]),
$h->br,
"--RollerCon HQ".$h->br.'rollercon@gmail.com'.$h->br."rollercon.com"
);
 
 
# $message .= "\n$hours TOTAL HOURS\n\nAgain, thank you for volunteering at RollerCon.\n\n-RollerCon Leadership Team";
my $subject = $dname."'s RollerCon Volunteer Hours Summary";
print "Emailing $dname ($email)...\n";
use RCMailer;
EmailUser($email, $subject, $message);
sleep (15);
}
 
print "\ndone.\n\n";
/tags/2022.final/RCUtil/emailDailySchedules.pl
0,0 → 1,50
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use tableViewer;
use DateTime;
 
my $dt = DateTime->today;
my $day = $dt->day_name;
my $date = $dt->date;
 
my $dbh = getDBConnection();
my $sth1 = $dbh->prepare("select distinct RCid from (select distinct RCId from v_shift where date = date(now()) union select distinct RCid from v_shift_announcer where date = date(now()) union select distinct RCid from v_shift_officiating where date = date(now())) t1 where RCid != '' order by RCid");
my $sth2 = $dbh->prepare("select * from (select id, date, dayofweek, location, time, role, '' as teams, type from v_shift where RCid = ? union select id, date, dayofweek, track as location, time, role, teams, gtype as type from v_shift_announcer where RCid = ? union select id, date, dayofweek, track as location, time, role, teams, gtype as type from v_shift_officiating where RCid = ?) temp where date = date(now()) order by date, time");
 
$sth1->execute();
while (my ($RCid) = $sth1->fetchrow_array()) {
my $email = getUserEmail($RCid);
my $dname = getUserDerbyName($RCid);
my @shifts = ();
$sth2->execute($RCid, $RCid, $RCid);
while (my $S = $sth2->fetchrow_hashref()) {
push @shifts, $S;
}
my $message=<<term1;
Greetings $dname,
 
Here is your RollerCon Volunteer (and MVP Class) schedule for today, $day, $date.
 
Please note that it is very important to fulfill your assigned shifts. It is too late to drop today's shifts in the scheduling tool. If you find you are unable to work a shift, please notify an On Duty Lead from the department you are scheduled to work (or VCI) at least 30 minutes before your shift. Anyone who "No Show; No Calls" is at risk of losing the rest of their assigned shifts, being barred from volunteering for the rest of this year and/or beyond, and even possibly losing their badge. (That's how big of a deal it is!) But of course we know a lovely person such as yourself would never do that. Right?
 
Well, here's what you've got:
 
term1
 
foreach (@shifts) {
$message .= "$_->{date} $_->{dayofweek} $_->{location} $_->{time} $_->{role} $_->{teams}\n";
}
 
$message .= "\n\nAgain, thank you for volunteering at RollerCon.\n\n-RollerCon Leadership Team";
my $subject = "$dname's RollerCon $day Volunteer (or MVP Class) Schedule";
use RCMailer;
EmailUser($email, $subject, $message);
# print "DEBUG: Emailing $email here...\n";
}
/tags/2022.final/docker/Dockerfile
0,0 → 1,50
FROM ubuntu:16.04
 
RUN \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y \
build-essential \
apt-utils \
ssl-cert \
apache2 \
apache2-utils \
apache2-dev \
libapache2-mod-perl2 \
libapache2-mod-perl2-dev \
libcgi-pm-perl \
liblocal-lib-perl \
cpanminus \
libexpat1-dev \
libssl-dev \
mysql-client \
libmysqlclient-dev \
libapreq2-dev \
zip && \
cpanm DBD::mysql \
DateTime \
Data::ICal::Entry::Event \
Data::ICal \
Data::ICal::Entry::Event \
Date::Calc \
# Date::ICal \
Email::Sender::Simple \
Email::Sender::Transport::SMTPS \
Email::Simple \
Email::Simple::Creator \
Email::Valid \
Spreadsheet::WriteExcel \
HTML::Tiny && \
a2enmod cgid && \
a2enmod rewrite && \
a2dissite 000-default && \
apt-get update -y && \
apt-get upgrade -y && \
apt-get -y clean
 
COPY localhost.conf /etc/apache2/sites-enabled/localhost.conf
 
VOLUME ["/var/www/html"]
VOLUME ["/usr/local/lib/site_perl"]
 
EXPOSE 80
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/docker/localhost.conf
0,0 → 1,12
ServerName localhost
AddHandler cgi-script .cgi .pl
 
<Directory /var/www/html>
Options All
AllowOverride All
</Directory>
 
<VirtualHost *:80>
DocumentRoot /var/www/html
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/perl/RCMailer.pm
0,0 → 1,86
use Net::SMTPS;
use Email::Simple;
use strict;
 
my $server = "smtp.gmail.com";
my $port = 587;
my $user = 'officials.rollercon.schedule@gmail.com';
my $password = 'qdxnqqygcwnixrlq';
 
warn "loaded RCMailer...";
 
sub EmailUser {
my $email = shift;
my $subject = shift;
my $body = shift;
warn "DEBUG: Emailing $email...";
my $smtp = Net::SMTPS->new(
$server,
Hello => 'gmail.com',
Port => $port,
doSSL => 'starttls',
Timeout => 15,
# Debug => 1
);
die "Could not connect to GMAIL SMTP server!" unless $smtp;
my $msg = Email::Simple->create(
header => [
To => $email,
From => $user,
Subject => $subject,
'Content-type' => 'text/html',
],
body => $body,
);
 
$smtp->auth ($user, $password);
$smtp->mail ($user);
$smtp->to ($email);
$smtp->data ();
$smtp->datasend ($msg->as_string);
$smtp->quit;
}
 
 
#------------------------------------------------------------------------
#
#use Email::Sender::Simple qw(sendmail);
#use Email::Sender::Transport::SMTPS;
#use Email::Simple ();
#use Email::Simple::Creator ();
#
#my $smtpserver = 'smtp.gmail.com';
#my $smtpport = 587;
#my $smtpuser = 'officials.rollercon.schedule@gmail.com';
#my $smtppassword = '0rc_T00l';
#
#my $transport = Email::Sender::Transport::SMTPS->new({
# host => $smtpserver,
# ssl => 'starttls',
# port => $smtpport,
# sasl_username => $smtpuser,
# sasl_password => $smtppassword,
# debug => 1,
# });
#
#sub EmailUser {
# my $email = shift;
# my $subject = shift;
# my $body = shift;
#
# my $msg = Email::Simple->create(
# header => [
# To => $email,
# From => $smtpuser,
# Subject => $subject,
# ],
# body => $body,
# );
#
# sendmail($msg, { transport => $transport });
#}
 
 
1;
/tags/2022.final/perl/RollerCon.pm
0,0 → 1,735
## RollerCon support functions...
 
use strict;
use cPanelUserConfig;
use Exporter;
use CGI qw/:standard :netscape/;
use CGI::Cookie;
use DBI;
use WebDB;
 
 
my $dbh = WebDB->connect ();
sub getRCDBH {
return $dbh;
}
our $ORCUSER;
use constant {
USER => 1,
LEAD => 2,
MANAGER => 3,
DIRECTOR => 4,
ADMIN => 5
};
 
sub getAccessLevels {
my %AccessLevels = (
-1 => "Locked",
0 => "Pending",
1 => "Volunteer",
2 => "Lead",
3 => "Manager",
4 => "Director",
5 => "SysAdmin"
);
return \%AccessLevels;
}
 
sub authDB {
my $src = shift;
my $id = shift;
my $pass = shift;
my $level = shift;
my ($result, $encpass);
my $sth = $dbh->prepare("select * from official where email = ?");
$sth->execute($id);
my $RCDBIDHASH = $sth->fetchrow_hashref();
if ($src eq "form") {
my $pwdhan = $dbh->prepare("select password(?)");
$pwdhan->execute($pass);
($encpass) = $pwdhan->fetchrow();
} else {
$encpass = $pass;
}
my $tempDepartments = convertDepartments ($RCDBIDHASH->{department});
my $MAXACCESS = scalar keys %{ $tempDepartments } ? max ($RCDBIDHASH->{'access'}, values %{ $tempDepartments }) : $RCDBIDHASH->{'access'};
if (!$RCDBIDHASH->{'RCid'}) {
$result->{ERRMSG} = "Email Address not found!";
$result->{cookie_string} = '';
$result->{RCid} = '';
logit(0, "Account not found: $id");
$result->{authenticated} = 'false';
} elsif ($RCDBIDHASH->{'password'} ne $encpass) {
$result->{ERRMSG} = "Incorrect Password!";
$result->{cookie_string} = '';
$result->{RCid} = $RCDBIDHASH->{'RCid'};
logit($RCDBIDHASH->{'RCid'}, "Incorrect Password");
$result->{authenticated} = 'false';
} elsif ($MAXACCESS < $level) {
if (getSetting ("MAINTENANCE")) {
$result->{ERRMSG} = "MAINTENANCE MODE: Logins are temporarily disabled.";
} else {
$result->{ERRMSG} = "Your account either needs to be activated, or doesn't have access to this page!";
logit($RCDBIDHASH->{'RCid'}, "Insufficient Privileges");
}
$result->{cookie_string} = "${id}&${encpass}&$RCDBIDHASH->{'access'}";
$result->{RCid} = $RCDBIDHASH->{'RCid'};
$result->{authenticated} = 'false';
} else {
$result->{ERRMSG} = '';
$RCDBIDHASH->{department} = convertDepartments ($RCDBIDHASH->{department});
$RCDBIDHASH->{'access'} = max ($RCDBIDHASH->{'access'}, values %{$RCDBIDHASH->{department}});
$result->{cookie_string} = "${id}&${encpass}&$RCDBIDHASH->{'access'}";
$result->{RCid} = $RCDBIDHASH->{'RCid'};
logit($RCDBIDHASH->{'RCid'}, "Logged In") if $src eq "form";
$dbh->do ("update official set last_login = CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles') where RCid = ?", undef, $RCDBIDHASH->{'RCid'}) if $src eq "form";
$result->{authenticated} = 'true';
# my @depts = map { s/-\d// } split /:/, $RCDBIDHASH->{department};
# my @depts = split /:/, $RCDBIDHASH->{department};
$ORCUSER=$RCDBIDHASH;
}
return $result;
}
 
sub max {
my ($max, $next, @vars) = @_;
return $max if not $next;
return max( $max > $next ? $max : $next, @vars );
}
 
sub authenticate { # Verifies the user has logged in or puts up a log in screen
my $MAINTMODE = getSetting ("MAINTENANCE");
my $MINLEVEL = $MAINTMODE ? $MAINTMODE : shift // 1;
my ($ERRMSG, $authenticated, %FORM);
my $sth = $dbh->prepare("select * from official where email = '?'");
my $query = new CGI;
# Check to see if the user has already logged in (there should be cookies with their authentication)?
my $RCAUTH = $query->cookie('RCAUTH');
$FORM{'ID'} = WebDB::trim $query->param('id') || '';
$FORM{'PASS'} = WebDB::trim $query->param('pass') || '';
$FORM{'SUB'} = $query->param('login') || '';
if ($FORM{'SUB'}) {
#a log in form was submited
if ($FORM{'SUB'} eq "Submit") {
$authenticated = authDB('form', $FORM{'ID'}, $FORM{'PASS'}, $MINLEVEL);
} elsif ($FORM{'SUB'} eq "New User") {
# Print the new user form and exit
}
} elsif ($RCAUTH) {
#We have an authenication cookie. Double-check it
my ($RCID, $RCPASS, $RCLVL) = split /&/, $RCAUTH;
$authenticated = authDB('cookie', $RCID, $RCPASS, $MINLEVEL);
} else {
$authenticated->{authenticated} = 'false';
}
if ($authenticated->{authenticated} eq 'true') {
return $authenticated->{cookie_string};
}
 
# If we get here, the user has failed authentication; throw up the log-in screen and die.
 
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"",-expires=>"now");
 
if ($authenticated->{ERRMSG}) {
$authenticated->{ERRMSG} = "<TR><TD colspan=2 align=center><font color=red><b>".$authenticated->{ERRMSG}."</b></font>&nbsp</TD></TR>";
# Log the failed access attempt
} else {
$authenticated->{ERRMSG} = "";
# Since there was no ERRMSG, no need to log anything.
}
 
print header(-cookie=>$RCAUTH_cookie);
printRCHeader("Please Sign In");
print<<authpage;
<form action="$ENV{REQUEST_URI}" method=POST name=Req id=Req>
<TR><TD colspan=2 align=center><b><font size=+2>Please Sign In</font>
<TABLE>
</TD></TR>
<TR><TD colspan=2>&nbsp</TD></TR>
$authenticated->{ERRMSG}
<TR>
<TD align=right><B>Email Address:</TD><TD><INPUT type=text id=login name=id></TD>
</TR>
<TR>
<TD align=right><B>Password:</TD><TD><INPUT type=password name=pass></TD>
</TR>
<TR><TD></TD><TD><INPUT type=submit name=login value=Submit></TD></TR>
<TR><TD colspan=2 align=center>&nbsp;</TD></TR>
<TR><TD colspan=2 align=center><A HREF="/schedule/manage_user.pl?submit=New%20User">[register as a new user]</A></TD></TR>
<TR><TD colspan=2 align=center><A HREF="/schedule/password_reset.pl">[reset your password]</A></TD></TR>
</TABLE>
</FORM>
 
<SCRIPT language="JavaScript">
<!--
document.getElementById("login").focus();
function Login () {
document.getElementById('Req').action = "$ENV{SCRIPT_NAME}";
document.getElementById('Req').submit.click();
return true;
}
 
 
//-->
</SCRIPT>
 
authpage
 
#foreach (keys %ENV) {
# print "$_: $ENV{$_}<br>";
#}
# &JScript;
exit;
}
 
sub getShiftDepartment {
my $shiftID = shift // "";
my $dept;
if ($shiftID =~ /^\d+$/) {
($dept) = $dbh->selectrow_array ("select dept from shift where id = ?", undef, $shiftID);
} else {
my ($id, $role) = split /-/, $shiftID;
($dept) = $dbh->selectrow_array ("select distinct department from staff_template where role like ?", undef, $role.'%');
}
# } elsif ($shiftID =~ /^\d+-ANN/) {
# $dept = "ANN";
# } else {
# $dept = "OFF";
# }
return $dept;
}
 
sub getDepartments {
my $RCid = shift // "";
# If we get an RCid, return the list of departments and levels for that user.
# Otherwise (no parameter), return the list of departments with their display names.
if ($RCid) {
my $sth = $dbh->prepare("select department from official where RCid = ?");
$sth->execute($RCid);
my ($dlist) = $sth->fetchrow;
return convertDepartments ($dlist);
} else {
my %HASH;
my $sth = $dbh->prepare("select TLA, name from department");
$sth->execute();
while (my ($tla, $name) = $sth->fetchrow) {
$HASH{$tla} = $name;
}
return \%HASH;
}
}
 
sub convertDepartments {
# For the department membership, converts the DB string back and forth to a hashref...
my $input = shift // "";
my $output;
 
if (ref $input eq "HASH") {
$output = join ":", map { $_."-".$input->{$_} } sort keys %{$input};
} else {
foreach (split /:/, $input) {
my ($tla, $level) = split /-/;
$output->{$tla} = $level;
}
}
return $output;
}
 
sub getSchedule {
my $RCid = shift // return "ERROR: No RCid provided to getSchedule";
my $filter = shift // "";
my @whereclause;
if ($filter eq "all") {
push @whereclause, "date >= '2022-01-01'";
} else {
push @whereclause, "date >= date(now())";
}
# if ($RCid ne $ORCUSER->{RCid}) {
# push @whereclause, "dept != 'PER'";
# }
use DateTime;
my $dt = DateTime->today (time_zone => 'America/Los_Angeles');
$dt =~ s/T00\:00\:00$//;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
 
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
my $where = scalar @whereclause ? "where ".join " and ", @whereclause : "";
my @shifts;
my $sth = $dbh->prepare("select * from (select id, date, dayofweek, track as location, time, role, teams, signup, 'OFF' as dept, volhours from v_shift_officiating where RCid = ? union
select id, date, dayofweek, track as location, time, role, teams, signup, 'ANN' as dept, volhours from v_shift_announcer where RCid = ? union
select id, date, dayofweek, location, time, role, '' as teams, type as signup, dept, volhours from v_shift where RCid = ?) temp
$where order by date, time");
$sth->execute($RCid, $RCid, $RCid);
my $hours = 0;
while (my $s = $sth->fetchrow_hashref) {
my ($yyyy, $mm, $dd) = split /\-/, $s->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
if (!$s->{teams}) {
# it's a time-based shift
if ($s->{dept} eq "PER") {
if ($RCid eq $ORCUSER->{RCid}) {
# DROP
$s->{buttons} = $h->button ({ onClick=>"if (confirm('Really? You want to delete this personal time?')==true) { window.open('manage_personal_time.pl?choice=Delete&id=$s->{id}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "DEL")."&nbsp;".$h->button ({ onClick=>"location.href='manage_personal_time.pl?choice=Update&id=$s->{id}'" }, "EDIT");
} else {
$s->{location} = "";
$s->{role} = "";
}
} elsif (($RCid == $ORCUSER->{RCid} and $s->{signup} !~ /^selected/ and $now < $cutoff) or ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5)) {
# DROP
$s->{buttons} = $h->button ({ onClick=>"if (confirm('Really? You want to drop this shift?')==true) { window.open('make_shift_change.pl?change=del&id=$s->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP");
if ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5) {
# NO SHOW
$s->{buttons} .= "&nbsp;".$h->button ({ onClick=>"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$RCid&id=$s->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "NO SHOW");
}
$hours += $s->{volhours} unless $s->{dept} eq "CLA";
}
 
} elsif (($RCid == $ORCUSER->{RCid} and $s->{signup} !~ /^selected/ and $now < $cutoff) or ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5)) {
# it's a game shift
#DROP
$s->{buttons} = $h->button ({ onClick=>"if (confirm('Really? You want to drop this shift?')==true) { window.open('make_shift_change.pl?change=del&RCid=$RCid&id=$s->{id}&role=$s->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "DROP");
if ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5) {
# NO SHOW
$s->{buttons} .= "&nbsp;".$h->button ({ onClick=>"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$RCid&id=$s->{id}&role=$s->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "NO SHOW");
}
$hours += $s->{volhours};
}
$s->{role} =~ s/\-\d$//;
# push @shifts, $h->li ({ class=> $s->{date} eq $dt ? "nowrap highlighted" : "nowrap shaded" }, join '&nbsp;&nbsp;', $s->{date}, $s->{dayofweek}, $s->{time}, $s->{location}, getDepartments()->{$s->{dept}}, $s->{role}, $s->{teams}, $s->{buttons});
# push @shifts, $h->li ({ class=> $s->{date} eq $dt ? "highlighted" : "shaded" }, join '&nbsp;&nbsp;', $s->{date}, $s->{dayofweek}, $s->{time}, $s->{location}, getDepartments()->{$s->{dept}}, $s->{role}, $s->{teams}, $s->{buttons});
push @shifts, $h->li ({ class=> $s->{date} eq $dt ? "highlighted" : "shaded" }, $h->div ({ class=>"lisp0" }, [ $h->div ({ class=>"liLeft" }, join '&nbsp;&nbsp;', ($s->{date}, $s->{dayofweek}, $s->{time}, $s->{location}, getDepartments()->{$s->{dept}}, $s->{role}, $s->{teams})), $h->div ({ class=>"liRight" }, $s->{buttons}) ]));
}
if (scalar @shifts) {
return $h->ul ([ @shifts, $h->h5 ("Currently showing $hours hours of Volunteer Time.") ]);
} else {
return $h->p ({ class=>"hint" }, "[nothing scheduled at the moment]");
}
}
 
sub getRCid {
my $derbyname = shift;
($derbyname) = $dbh->selectrow_array ("select RCid from official where derby_name = ?", undef, $derbyname);
return $derbyname;
}
 
sub getSetting {
my $k = shift;
my ($value) = $dbh->selectrow_array ("select setting.value from setting where setting.key = ?", undef, $k);
return defined $value ? $value : undef;
}
 
sub getUser {
my $ID = shift;
my $sth;
if ($ID =~ /^\d+$/) {
$sth = $dbh->prepare("select * from official where RCid = ?");
} else {
$sth = $dbh->prepare("select * from official where email = ?");
}
$sth->execute($ID);
return $sth->fetchrow_hashref;
}
 
sub getUserEmail {
my $RCid = shift;
my $sth = $dbh->prepare("select email from official where RCid = ?");
$sth->execute($RCid);
my ($email) = $sth->fetchrow_array();
return $email;
}
 
sub getUserDerbyName {
my $RCid = shift;
my $sth = $dbh->prepare("select derby_name from official where RCid = ?");
$sth->execute($RCid);
my ($dname) = $sth->fetchrow_array();
return $dname;
}
 
sub getYears {
# my $sth = $dbh->prepare("select distinct year(date) from v_shift_admin_view union select year(now())");
my $sth = $dbh->prepare("select distinct year(date) from v_shift_admin_view");
$sth->execute();
my @years;
while (my ($y) =$sth->fetchrow_array()) { push @years, $y; }
return \@years;
}
 
sub printRCHeader {
my $PAGE_TITLE = shift;
use CGI qw/start_html/;
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
# my $logout = $h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]");
my $referrer = param ("referrer") ? param ("referrer") : $ENV{HTTP_REFERER};
my $logout = (!$referrer or $referrer eq url) ? "" : $h->button ({ onClick=>"window.location.href='$referrer';" }, "Back")."&nbsp;";
$logout .= url =~ /\/(index.pl)?$/ ? "" : $h->button ({ onClick=>"window.location.href='/schedule/';" }, "Home")."&nbsp;";
$logout .= $h->button ({ onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'; location.href='/';" }, "Log Out");
my $loggedinas = $ORCUSER ? "Currently logged in as: ".$h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$ORCUSER->{RCid}" }, $ORCUSER->{derby_name}).$h->br.$logout : "";
print start_html (-title=>"vORC - $PAGE_TITLE", -style => {'src' => "/style.css"} );
#<html><head><title>Officials' RollerCon Schedule Manager - $PAGE_TITLE</title>
#<link rel="stylesheet" type="text/css" href="/style.css">
#</head>
#<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
print $h->div ({ class=>"sp0" }, [ $h->div ({ class=>"spLeft" }, $h->a ({ href=>"/schedule/" }, $h->img ({ src=>"/logo.jpg", width=>"75", height=>"75" }))),
$h->div ({ class=>"spRight" }, [ $h->h1 (["vORC $PAGE_TITLE", $h->br]),
$loggedinas,
])
]);
#print<<rcheader;
# <TABLE>
# <TR class="nostripe">
# <TD align=right><img SRC="/logo.jpg"></TD>
# <TD align=center valign=middle><b><font size=+3>Officials' RollerCon<br>Schedule Manager<br>$PAGE_TITLE</FONT></b>
# <p align=right><font size=-2>$loggedinas <a href='index.pl' onClick="document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;">[Log Out]</a></font></TD>
# </TR>
 
#rcheader
}
 
sub changeShift {
my ($change, $shift_id, $role, $user_id) = @_;
my $leadership_change = 0;
# my $department = getShiftDepartment ($role ? $shift_id."-".$role : $shift_id);
my $department;
if ($shift_id =~ /^\d+$/) {
$department = getShiftDepartment ($role ? $shift_id."-".$role : $shift_id);
} else {
$department = "CLA";
($shift_id) = $dbh->selectrow_array ("select min(id) from v_shift where date = ? and start_time = ? and location = ? and isnull(RCid) = 1", undef, split /\|/, $shift_id);
}
my $game_based = $role ? "game" : "shift";
my $sth;
if ($change eq "add" or $change eq "override") {
my $taken;
if ($game_based eq "game") {
($taken) = $dbh->selectrow_array ("select count(*) from assignment where Gid = ? and role = ?", undef, $shift_id, $role);
} elsif ($department eq "CLA") {
($taken) = $shift_id ? 0 : 1;
} else {
($taken) = $dbh->selectrow_array ("select count(*) from shift where id = ? and isnull(assignee_id) = 0", undef, $shift_id);
}
if ($taken) {
return ($department eq "CLA") ? "<br>Denied! This class is already full ($shift_id).<br>\n" : "<br>Denied! This shift is already taken ($shift_id).<br>\n";
}
}
if (lc ($user_id) ne lc ($ORCUSER->{RCid})) { # they're changing someone else's schedule...
if ($ORCUSER->{department}->{$department} >= 2 or $ORCUSER->{access} >= 5 or $ORCUSER->{department}->{VCI} >= 2) {
# the user making the change is either a lead in the dept, a sysadmin, or a VCI lead
logit ($ORCUSER->{RCid}, "$ORCUSER->{derby_name} changed someone else's schedule. ($change, $shift_id, $role, $user_id)");
logit ($user_id, "Schedule was changed by $ORCUSER->{derby_name}. ($change, $shift_id, $role, $user_id)");
$leadership_change = 1;
} else {
logit ($ORCUSER->{RCid}, "Unauthorized attempt to change someone else's schedule. ($change, $shift_id, $role, $user_id)");
return "<br>Denied! You are not authorized to change someone else's schedule in this department ($department).<br>\n";
}
} elsif ($ORCUSER->{department}->{$department} >= 3) {
# Managers can sign up for as many shifts within their own department as they like...
$leadership_change = 1;
}
if ($change eq "add" and convertDepartments(getUser($user_id)->{department})->{$department} < 1) {
return "<br>Denied! User ($user_id) is not a member of Department ($department)!<br>\n" unless $department eq "CMP";
}
my $conflict = findConflict ($user_id, $shift_id, $game_based);
if ($change eq "add" and $conflict) {
return "<br>Denied! There is a conflict ($conflict) with that shift's time!<br>\n";
}
my ($game_type) = $dbh->selectrow_array ("select type from ".$game_based." where id = ?", undef, $shift_id);
if ($game_type =~ /^selected/ and !$leadership_change) {
return "<br>Denied! Only leadership can make changes to 'selected staffing' shifts!<br>\n" unless $department eq "CMP";
}
if ($change eq "add" and $game_type eq "lead" and convertDepartments(getUser($user_id)->{department})->{$department} < 2 and $ORCUSER->{access} < 3) {
return "<br>Denied! Shift reserved for leadership staff!<br>\n";
}
 
# my $MAXSHIFTS = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY");
my $MAXSHIFTS = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY_".$department);
$MAXSHIFTS = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY") unless defined $MAXSHIFTS;
if ($game_type eq "lead" and $department eq "OFF") { $MAXSHIFTS = 99; }
 
my $daily_count;
if ($department eq "CLA") {
# MVP Class Sign-up
$MAXSHIFTS = getSetting ("MAX_CLASS_SIGNUP");
($daily_count) = $dbh->selectrow_array ("select count(*) from v_shift where RCid = ? and dept = 'CLA'", undef, $user_id);
if ($change eq "add" and $daily_count >= $MAXSHIFTS and !$leadership_change) {
return "<br>Denied! You may only sign up for $MAXSHIFTS Classes!<br>\n";
}
} else {
$daily_count = signUpCount ('get', $user_id, $department);
if ($change eq "add" and $daily_count >= $MAXSHIFTS and !$leadership_change) {
return "<br>Denied! You may only sign up for $MAXSHIFTS $game_type shifts in one day!<br>\n";
}
# if ($change eq "add" and $game_based eq "game" and $department eq "OFF" and $game_type eq "full length") {
# my ($full_length_count) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where RCid = ? and gtype = 'full length' and date > '2022-01-01'", undef, $user_id);
# if ($full_length_count >= 3) {
# return "<br>Denied! You may only sign up to officiate 3 $game_type games (total)!<br>\n";
# }
# }
}
my @DBARGS;
if ($game_based eq "game") {
if ($change eq "add" or $change eq "override") {
$sth = $dbh->prepare("insert into assignment (Gid, role, RCid) values (?, ?, ?)");
} elsif ($change eq "del") {
$sth = $dbh->prepare("delete from assignment where Gid = ? and role = ? and RCid= ?");
}
@DBARGS = ($shift_id, $role, $user_id);
} else {
if ($change eq "add" or $change eq "override") {
$sth = $dbh->prepare("update shift set assignee_id = ? where id = ? and isnull(assignee_id) = 1");
@DBARGS = ($user_id, $shift_id);
} elsif ($change eq "del") {
$sth = $dbh->prepare("update shift set assignee_id = null where id = ?");
@DBARGS = ($shift_id);
}
}
print "<br>attempting to make DB changes...<br>";
if ($sth->execute (@DBARGS)) {
$daily_count = signUpCount ($change, $user_id, $department) unless $leadership_change;
logit ($user_id, "Shift ".ucfirst($change).": $shift_id -> $role");
logit ($ORCUSER->{RCid}, "OVERRIDE: Shift ".ucfirst($change).": $shift_id -> $role") if $change eq "override";
print "Success!...<br>You've signed up for $daily_count shifts today (you're currently allowed to sign up for $MAXSHIFTS per day).<br>\n";
return;
} else {
return "<br><b>You did not get the shift</b>, most likely because someone else took it while you were looking.<br>\nERROR: ", $sth->errstr();
}
}
 
sub modShiftTime {
my ($shift_id, $user_id, $diff) = @_;
my $ORCUSER = getUser (1);
use Scalar::Util qw(looks_like_number);
if (!looks_like_number ($diff)) {
print "<br>ERROR! The time adjustment ($diff) doesn't look like a number.<br>\n";
return;
}
my ($validate_assignee) = $dbh->selectrow_array ("select count(*) from v_shift where id = ? and RCid = ?", undef, $shift_id, $user_id);
if (!$validate_assignee) {
print "<br>ERROR! This shift is assigned to someone else.<br>\n";
return;
}
 
my $department = getShiftDepartment ($shift_id);
if (convertDepartments ($ORCUSER->{department})->{$department} < 2 and $ORCUSER->{access} < 5) {
print "<br>ERROR! You're not authorized to modify this shift's time.<br>\n";
logit ($ORCUSER->{RCid}, "Unauthorized attempt to modify shift time. ($department, $shift_id)");
return;
}
my $rows_changed;
print "<br>attempting to make DB changes...<br>";
if ($diff == 0) {
$rows_changed = $dbh->do ("update shift set mod_time = null where id = ? and assignee_id = ?", undef, $shift_id, $user_id);
} else {
$rows_changed = $dbh->do ("update shift set mod_time = ? where id = ? and assignee_id = ?", undef, $diff, $shift_id, $user_id);
}
if (!$rows_changed or $dbh->errstr) {
print "ERROR: Nothing got updated".$dbh->errstr;
logit (0, "ERROR modifying a shift time ($diff, $shift_id, $user_id):".$dbh->errstr);
} else {
print "SUCCESS: Shift $shift_id succesfully modified by $diff hour(s)";
logit ($ORCUSER->{RCid}, "SUCCESS: Shift $shift_id succesfully modified by $diff hour(s)");
}
return;
}
 
sub signUpCount {
my $action = shift;
my $id = shift;
my $dept = shift // "";
if ($id eq $ORCUSER->{RCid}) {
if ($action eq 'add') {
if (signUpCount ('get', $id, $dept)) {
$dbh->do("update sign_up_count set sign_ups = sign_ups + 1 where date = curdate() and RCid = ? and department = ?", undef, $id, $dept);
} else {
$dbh->do("replace into sign_up_count (date, RCid, department, sign_ups) values (curdate(), ?, ?, 1)", undef, $id, $dept);
}
} elsif ($action eq 'del') {
if (signUpCount ('get', $id, $dept)) {
$dbh->do("update sign_up_count set sign_ups = sign_ups - 1 where date = curdate() and RCid = ? and department = ?", undef, $id, $dept);
}
}
}
my ($R) = $dbh->selectrow_array ("select sign_ups from sign_up_count where RCid = ? and department = ? and date = curdate()", undef, $id, $dept);
 
return $R ? $R : '0';
}
 
sub signUpEligible {
my $user = shift;
my $t = shift;
my $shifttype = shift // "game";
my $dept = $t->{dept} // "";
my $limit = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY_".$dept);
$limit = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY") unless defined $limit;
if ($t->{type} eq "lead" and $dept eq "OFF") { $limit = 99; }
return 0 unless $limit > 0;
my $limitkey = $dept ? "sign_ups_today_".$dept : "sign_ups_today";
if ($shifttype eq "class") {
($t->{id}) = $dbh->selectrow_array ("select min(id) from v_shift where isnull(RCid) = 1 and dept = ? and date = ? and location = ? and start_time = ?", undef, "CLA", $t->{date}, $t->{location}, $t->{start_time});
$t->{dept} = "CLA";
$t->{type} = "open";
}
if (findConflict ($user->{RCid}, $t->{id}, $shifttype)) { return 0; }
 
if (!exists $user->{$limitkey}) {
$user->{$limitkey} = signUpCount('get', $user->{RCid}, $dept);
}
if ($shifttype eq "game") {
# if ($t->{gtype} !~ /^selected/ and $t->{gtype} ne "short track" and $user->{$limitkey} < $limit) {
# if ($t->{gtype} eq "full length" and $dept eq "OFF") {
# my ($full_length_count) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where RCid = ? and gtype = 'full length' and date > '2022-01-01'", undef, $user->{RCid});
# if ($full_length_count >= 3) {
# return 0;
# }
# }
if ($t->{signup} ne "selected" and $user->{$limitkey} < $limit) {
return 1;
} else {
return 0;
}
} else {
if ($dept eq "CLA") {
# MVP Class Sign-up
my $class_limit = getSetting ("MAX_CLASS_SIGNUP");
my ($class_count) = $dbh->selectrow_array ("select count(*) from v_shift where RCid = ? and dept = 'CLA'", undef, $user->{RCid});
return 0 unless $class_count < $class_limit;
}
if ($user->{department}->{$t->{dept}} < 1) { return 0; }
if ($t->{type} eq "lead" and $user->{department}->{$t->{dept}} < 2) { return 0; }
if ($t->{type} eq "manager" and $user->{department}->{$t->{dept}} < 3) { return 0; }
if ($t->{type} !~ /^selected/ and $user->{$limitkey} < $limit) {
return 1;
} else {
return 0;
}
}
}
 
sub findConflict {
my $rcid = shift;
my $gid = shift;
my $type = shift // "";
my ($date, $start, $end, $conflicts);
if ($type eq "game") {
# Are they already signed up for this game? (It's faster to check the two views one at a time...)
# ($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where substring_index(id, '-', 1) = ? and RCid = ?", undef, $gid, $rcid);
($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where id = ? and RCid = ?", undef, $gid, $rcid);
if ($conflicts) { return "OFF-".$gid; } # no need to keep looking...
($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_announcer where id = ? and RCid = ?", undef, $gid, $rcid);
if ($conflicts) { return "ANN-".$gid; } # no need to keep looking...
($date, $start, $end) = $dbh->selectrow_array ("select distinct date, time, end_time from game where id = ?", undef, $gid);
} elsif ($type eq "personal") {
($date, $start, $end) = @{ $gid };
} else {
($date, $start, $end) = $dbh->selectrow_array ("select distinct date, start_time, end_time from shift where id = ?", undef, $gid);
}
# Are they signed up for any games that would conflict with this one?
# my $sth = $dbh->prepare("select count(*) from v_shift_admin_view where id in (select id from game where date = (select date from game where id = ?) and ((time <= (select time from game where id = ?) and end_time > (select time from game where id = ?)) or (time > (select time from game where id = ?) and time < (select end_time from game where id = ?)))) and RCid = ?");
# my $sth = $dbh->prepare("select count(*) from v_shift_all where id in (select id from v_shift_all where date = (select date from v_shift_all where id = ?) and ((start_time <= (select start_time from v_shift_all where id = ?) and end_time > (select start_time from v_shift_all where id = ?)) or (start_time > (select start_time from v_shift_all where id = ?) and start_time < (select end_time from v_shift_all where id = ?)))) and RCid = ?");
($conflicts) = $dbh->selectrow_array ("select * from (
select concat(dept, '-', id) from v_shift where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? union
select concat('ANN-', id) from v_shift_announcer where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? union
select concat('OFF-', id) from v_shift_officiating where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? ) alltables",
undef, $date, $start, $start, $start, $end, $rcid, $date, $start, $start, $start, $end, $rcid, $date, $start, $start, $start, $end, $rcid
);
return $conflicts;
}
 
sub changeLeadShift {
my ($change, $lshift, $user_id) = @_;
my $ERRMSG;
 
my $sth = $dbh->prepare("update lead_shift set assignee_id = ? where id = ?");
print "<br>attempting to make DB changes...<br>";
if ($change eq "add") {
$sth->execute($user_id, $lshift)
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
} elsif ($change eq "del") {
$sth->execute('', $lshift)
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
}
if ($ERRMSG) {
print $ERRMSG;
} else {
logit($user_id, "Lead Shift ".ucfirst($change).": $lshift");
print "Success.<br>";
}
}
 
sub logit {
my $RCid = shift;
my $msg = shift;
my $sth = $dbh->prepare("insert into log (RCid, event) values (?, ?)");
$sth->execute($RCid, $msg);
}
 
1;
/tags/2022.final/perl/WebDB.pm
0,0 → 1,31
package WebDB;
use strict;
use DBI;
my $host_name = "192.168.1.5";
my $db_name = "rollerco_vorc";
my $dsn = "DBI:mysql:host=$host_name;database=$db_name";
# Connect to MySQL server, using hardwired name and password
sub connect {
return (DBI->connect ($dsn, "root", "Jopy666!",
{PrintError => 0, RaiseError => 1}));
}
# Connect to MySQL server, using name and password from the current
# user's ~/.my.cnf option file. The mysql_read_default_file option,
# when added to the DSN, specifies which option file to read.
sub connect_with_option_file {
$dsn .= ";mysql_read_default_file=$ENV{HOME}/.my.cnf";
return (DBI->connect ($dsn, undef, undef,
{PrintError => 0, RaiseError => 1}));
}
sub trim {
my $str = shift;
 
return "" if !defined $str;
$str =~ s/^\s+//;
$str =~ s/\s+$//;
return ($str);
}
1; # return true
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/perl/scanFunctions.pm
0,0 → 1,199
#######################################################################
# A set of functions to assist the scan data display tool.
# Kept here to unclutter the main script.
#######################################################################
#
#
# $Log: scanFunctions.pm,v $
#
 
use DBI ();
 
my $internalDBH = &getDBConnection || die "Unable to connect to Database\n\n";
my $nowhan = $internalDBH->prepare("select now()");
$nowhan->execute();
our ($now) = $nowhan->fetchrow;
$now =~ s/ / at /;
 
 
sub byfield { $colOrderHash{$a} <=> $colOrderHash{$b}; }
 
 
sub fetchColEntries {
my $colName = shift;
my $selection = shift;
my $table = $DBTABLE;
my $optionList = "";
# project table in new DB?
# my $cathan = $internalDBH->prepare("select distinct $colName from $table where $colName <> '' and isNull($colName) = 0 order by $colName");
my $cathan = $internalDBH->prepare("select distinct $colName from $table order by $colName");
 
$cathan->execute();
while (my ($cat) = $cathan->fetchrow) {
if ($cat eq "") { $cat = "-blank-"; }
if ($cat eq $selection) {
$optionList .= "<OPTION selected>$cat</OPTION>";
} else {
$optionList .= "<OPTION>$cat</OPTION>";
}
}
 
return $optionList;
}
 
sub fetchDerbyNameWithRCid {
my $optionList = "";
my $cathan = $internalDBH->prepare("select RCid, derby_name from official order by derby_name");
 
$cathan->execute();
while (my ($id, $cat) = $cathan->fetchrow) {
$optionList .= "<OPTION value=$id>$cat</OPTION>";
}
 
return $optionList;
}
 
 
sub generica {
my $colName = shift;
my $filter = shift;
 
if ($colFilterTypeHash{$colName} eq 'select')
{
if (defined $filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
# $filter = s/'/\'/g;
return "$colName = \"$filter\"";
}
else
{
my $thing = "filter-${colName}";
my $categories = &fetchColEntries($colName, $FORM{$thing});
my $Options = "<OPTION></OPTION>".$categories;
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $auto2>$Options</SELECT>";
}
} elsif ($colFilterTypeHash{$colName} eq 'text') {
if (defined $filter)
{
if ($filter =~ s/^=\s*//) { return "$colName = \"$filter\""; }
if ($filter !~ s/^\^\s*//) { $filter = "\%$filter"; }
if ($filter !~ s/\s*\$$//) { $filter = "$filter\%"; }
$filter =~ s/\*/%/g;
return "$colName like \"$filter\"";
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $auto2>";
}
} elsif ($colFilterTypeHash{$colName} eq 'number') {
if (defined $filter)
{
if ($filter =~ /^[>=<]\s*/) { return "$colName $filter"; }
else { return "$colName = $filter"; }
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $auto2>";
}
} elsif ($colFilterTypeHash{$colName} eq 'date') {
if (defined $filter)
{
if ($filter =~ s/^<\s*//) { return "$colName < '$filter'"; }
if ($filter =~ s/^>\s*//) { return "$colName > '$filter'"; }
return "$colName = '$filter'";
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $auto2>";
}
} elsif ($colFilterTypeHash{$colName} eq 'ERROR') {
return "<center><strong><font color=red>ERROR!</font>";
}
}
 
 
sub getData {
my $fields = shift;
my $whereClause = shift;
my $table = shift;
my $orderby = shift;
# my $RCid = shift;
# my $SecLvl = shift;
# my $selected = join ", ", @{$fields};
my $selected = '*';
$whereClause = scalar @{$whereClause} > 0 ? "where ".join " and ", @{$whereClause} : '';
# project in new DB?
# my $getMe = "select distinct $selected from HOST left join PRODUCT_INSTANCE on HOST.server = PRODUCT_INSTANCE.server left join project on hostID = projectHostID $whereClause";
#my $getMe = "select distinct $selected from HOST left join PRODUCT_INSTANCE on HOST.server=PRODUCT_INSTANCE.server $whereClause and HOST.page=HOST.maxPage and PRODUCT_INSTANCE.page = PRODUCT_INSTANCE.maxPage";
 
$orderby = $orderby eq "" ? "" : "order by $orderby";
# my $getMe = "select distinct $selected from $table $whereClause $orderby";
my $getMe = "select distinct * from $table $whereClause $orderby";
#warn($getMe);
 
my $limhan = $internalDBH->prepare($getMe); # Get the tickets from the DB
$limhan->execute();
my @results = ();
while (my $P = $limhan->fetchrow_hashref)
{
# if ($P->{assignee_id} == $RCid or ($SecLvl >= 3 and $P->{derby_name})) {
# $P->{derby_name} = "$P->{derby_name} <A HREF='#' onClick=\"window.open('make_lead_shift_change.pl?change=del&shift=$P->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
# } elsif (!$P->{derby_name}) {
# $P->{derby_name} = "<A HREF='#' onClick=\"window.open('make_lead_shift_change.pl?change=add&shift=$P->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[SIGN UP]</a>";
# }
push @results, $P;
}
return \@results;
}
 
 
 
sub getDBConnection {
$dbh = DBI->connect('DBI:mysql:database=rollerco_data;host=qnap.home.lan;port=3306', 'root', 'Jopy666!'
) || die "Could not connect to database: $DBI::errstr";
return $dbh;
}
 
 
sub inArray {
my $item = shift;
my $array = shift;
foreach (@{$array})
{
return 1 if $item eq $_;
}
return 0;
}
 
sub whereInArray {
my $item = shift;
my $array = shift;
my $i = 0;
foreach (@{$array})
{
return $i if $item eq $_;
$i++;
}
return -1;
}
 
 
 
# Leave this alone, it's needed to compile correctly
return 1;
/tags/2022.final/perl/tableViewer.pm
0,0 → 1,295
#######################################################################
# A set of functions to assist the scan data display tool.
# Kept here to unclutter the main script.
#######################################################################
#
#
# $Log: scanFunctions.pm,v $
#
 
use cPanelUserConfig;
use DBI ();
use WebDB;
 
#my $internalDBH = &getDBConnection || die "Unable to connect to Database\n\n";
my $internalDBH = WebDB->connect () || die "Unable to connect to Database\n\n";
 
sub currentTime {
use DateTime;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
$now =~ s/T/ at /;
return $now." US/Pacific";
}
 
sub byfield { $colOrderHash{$a} <=> $colOrderHash{$b}; }
 
sub exportExcel {
my $listref = shift;
my $FN_Prefix = shift // "ORC_Export";
use Spreadsheet::WriteExcel;
 
my $date = `date +"%m%d%y%H%M%S"`; chomp $date;
my $filename = "${FN_Prefix}_${date}_$$.xls";
print "Content-type: application/vnd.ms-excel\n";
# The Content-Disposition will generate a prompt to save the file. If you want
# to stream the file to the browser, comment out the following line.
print "Content-Disposition: attachment; filename=$filename\n";
print "\n";
# Create a new workbook and add a worksheet. The special Perl filehandle - will
# redirect the output to STDOUT
#
my $workbook = Spreadsheet::WriteExcel->new(\*STDOUT);
my $worksheet = $workbook->add_worksheet();
my $format = $workbook->add_format();
$format->set_bold();
my $col = $row = 0;
foreach $f (@displayFields)
{ $worksheet->write($row, $col++, "$NAME{$f}", $format); }
foreach $t (sort @{ $listref }) # Unt now we print the tickets!
{
$col = 0;
$row++;
foreach $f (@displayFields) {
if ($f eq "derby_name") {
if ($user->{department}->{"OFF"} < 2 and $t->{derby_name} and $t->{RCid} != $RCid and $LVL < 5) {
$t->{derby_name} = "FILLED";
}
}
$t->{$f} =~ s/<br>/\n/ig; $worksheet->write($row, $col++, "$t->{$f}");
}
}
$workbook->close();
return;
}
 
 
sub fetchColEntries {
my $colName = shift;
my $selection = shift;
my $table = $DBTABLE;
my $optionList = "";
if ($colName eq "derby_name" and $LVL < 2) {
# special case to anonymize assignees...
# my @opts = ("-blank-", $ORCUSER->{derby_name});
$optionList = join "", map { $selection eq $_ ? "<OPTION selected>$_</OPTION>" : "<OPTION>$_</OPTION>" } ("-blank-", $ORCUSER->{derby_name});
} else {
my $dept_where = $table eq "v_shift" ? "where dept != 'PER'" : "";
my $orderby = $colName eq "dayofweek" ? "field(dayofweek, 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')" : $colName;
my $cathan = $internalDBH->prepare("select distinct $colName from $table $dept_where order by $orderby");
 
$cathan->execute();
while (my ($cat) = $cathan->fetchrow) {
if ($cat eq "") { $cat = "-blank-"; }
if ($cat eq $selection) {
$optionList .= "<OPTION selected>$cat</OPTION>";
} else {
$optionList .= "<OPTION>$cat</OPTION>";
}
}
}
return $optionList;
}
 
sub fetchDerbyNameWithRCid {
my $DEPT = shift // "";
my $optionList = "";
my $cathan;
if (!$DEPT or $DEPT eq "CMP") {
$cathan = $internalDBH->prepare("select RCid, derby_name from official where level > 0 order by derby_name");
$cathan->execute();
} else {
$cathan = $internalDBH->prepare("select RCid, derby_name from official where level > 0 and (department like ? and department not like ?) order by derby_name");
$cathan->execute("%".$DEPT."%", "%".$DEPT."-0%");
}
 
while (my ($id, $cat) = $cathan->fetchrow) {
$optionList .= "<OPTION value=$id>$cat</OPTION>";
}
 
return $optionList;
}
 
 
sub filter {
my $colName = shift;
my $filter = shift;
if (exists &{"filter_".$colName}) { return &{"filter_".$colName} ($colName, $filter); }
 
if ($colFilterTypeHash{$colName} eq 'select')
{
if (defined $filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
# $filter = s/'/\'/g;
return "$colName = \"$filter\"";
}
else
{
my $thing = "filter-${colName}";
my $categories = &fetchColEntries($colName, $FORM{$thing});
my $Options = "<OPTION></OPTION>".$categories;
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
} elsif ($colFilterTypeHash{$colName} eq 'text') {
if (defined $filter)
{
if ($filter =~ s/^=\s*//) { return "$colName = \"$filter\""; }
if ($filter !~ s/^\^\s*//) { $filter = "\%$filter"; }
if ($filter !~ s/\s*\$$//) { $filter = "$filter\%"; }
$filter =~ s/\*/%/g;
return "$colName like \"$filter\"";
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $onChange>";
}
} elsif ($colFilterTypeHash{$colName} eq 'number') {
if (defined $filter)
{
if ($filter =~ /^[>=<]\s*/) { return "$colName $filter"; }
else { return "$colName = $filter"; }
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=2 $onChange>";
}
} elsif ($colFilterTypeHash{$colName} eq 'date') {
if (defined $filter)
{
if ($filter =~ s/^<\s*//) { return "$colName < '$filter'"; }
if ($filter =~ s/^>\s*//) { return "$colName > '$filter'"; }
return "$colName = '$filter'";
}
else
{
my $thing = "filter-${colName}";
return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $onChange>";
}
} elsif ($colFilterTypeHash{$colName} eq 'boolean') {
if (defined $filter)
{
return "$colName = $filter";
}
else
{
my $thing = "filter-${colName}";
my $Options = "<OPTION></OPTION><OPTION>True</OPTION><OPTION>False</OPTION>";
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
} elsif ($colFilterTypeHash{$colName} eq 'ERROR') {
return "<center><strong><font color=red>ERROR!</font>";
} elsif ($colFilterTypeHash{$colName} eq 'none') {
return;
}
}
 
 
sub getData {
my $fields = shift;
my $whereClause = shift;
my $table = shift;
my $orderby = shift;
my $curpage = shift; $curpage = 1 unless $curpage;
my $pagelimit = shift // "All";
my $selected = '*';
$whereClause = scalar @{$whereClause} > 0 ? "where ".join " and ", @{$whereClause} : '';
if ($orderby eq "dayofweek") {
$orderby = "order by date, time";
} elsif ($orderby eq "eventid") { # only applicable to the log viewer...
$orderby = "order by eventid desc";
} else {
$orderby = $orderby eq "" ? "" : "order by $orderby";
}
my $getMe;
if ($pagelimit eq "All") {
$getMe = "select distinct * from $table $whereClause $orderby";
} else {
$curpage = ($curpage - 1) * $pagelimit;
$getMe = "select distinct * from $table $whereClause $orderby limit $curpage, $pagelimit";
}
my ($totalcount) = $internalDBH->selectrow_array ("select distinct count(*) from $table $whereClause");
 
my $limhan = $internalDBH->prepare($getMe); # Get the tickets from the DB
$limhan->execute();
my @results = ();
while (my $P = $limhan->fetchrow_hashref)
{
push @results, $P;
}
return (\@results, $totalcount);
}
 
 
sub getDBConnection {
use WebDB;
$dbh = WebDB::connect ();
return $dbh;
}
 
 
sub inArray {
my $item = shift;
my $array = shift;
foreach (@{$array})
{
return 1 if $item eq $_;
}
return 0;
}
 
sub notInArray {
return ! inArray (@_);
}
 
 
sub uniq (@) {
# From CPAN List::MoreUtils, version 0.22
my %h;
map { $h{$_}++ == 0 ? $_ : () } @_;
}
 
 
sub whereInArray {
my $item = shift;
my $array = shift;
my $i = 0;
foreach (@{$array})
{
return $i if $item eq $_;
$i++;
}
return -1;
}
 
 
 
# Leave this alone, it's needed to compile correctly
return 1;
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/images/headerblank.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/2022.final/site/images/headerblank.gif
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/2022.final/site/images/refresh.button.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/2022.final/site/images/refresh.button.gif
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/2022.final/site/schedule/activate_user.pl
0,0 → 1,140
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use CGI;
use CGI::Cookie;
use DBI;
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
use WebDB;
my $dbh = WebDB->connect ();
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments ($user->{department});
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $DEPT = getDepartments ();
 
my $targetRCid = param ("RCid") // "";
my $targetDept = param ("department") // "";
my $confirmed = param ("confirmed") // 0;
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
printRCHeader("");
 
# Are they a lead for the Department in question?
printError ("You're not authorized to activate users in that department.") unless $user->{department}->{$targetDept} > 1 or $LVL > 4;
 
# Does the user exist in the DB?
my $targetuser = getUser ($targetRCid);
printError ("That user doesn't exist.") unless $targetuser->{RCid} eq $targetRCid;
 
# Is the user in a pending state for the Department in question?
$targetuser->{department} = convertDepartments ($targetuser->{department});
printError ("That user can't be activated for this department.") unless exists $targetuser->{department}->{$targetDept} and $targetuser->{department}->{$targetDept} eq "0";
 
# Has the form been re-submitted with a confirmation?
if ($confirmed eq "YES") {
print $h->p ("Very well. Activating $targetuser->{derby_name} (RCid: $targetRCid)...");
ACTIVATE ($targetuser, $targetDept, $user);
print $h->p ("Done. Now emailing the user to let them know...");
sendEmail ($targetuser);
print $h->p ("Done. You can close this window now (if it doesn't close automatically). Nothing else is going to happen here.");
print<<tail;
<SCRIPT language="JavaScript">
<!--
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function reloadParent() {
window.opener.document.Req.submit();
sleep(5000);
window.close();
}
reloadParent();
//-->
</SCRIPT>
tail
print $h->close ("body"), $h->close ("html");
 
} else {
print $h->p ("Do you really want to activate $targetuser->{derby_name} (RCid: $targetRCid) to work in the $DEPT->{$targetDept} Department?");
print $h->form ({ action=>url, method=>"POST" }, [
$h->input ({ type=>"hidden", name=>"RCid", value=>$targetRCid }),
$h->input ({ type=>"hidden", name=>"department", value=>$targetDept }),
$h->input ({ type=>"submit", name=>"confirmed", value=>"YES" }), "&nbsp;",
$h->button ({ onClick=>"window.close();" }, "Cancel")
]);
print $h->close ("body"), $h->close ("html");
}
 
sub ACTIVATE {
my $U = shift;
my $D = shift;
my $OU = shift;
$U->{department}->{$D} = 1;
$U->{department} = convertDepartments ($U->{department});
$dbh->do ("update official set access = 1, department = ? where RCid = ?", undef, $U->{department}, $U->{RCid}) or printError ("Something 'bad' happened when saving to the database.".$dbh->errstr);
logit ($OU->{RCid}, "Activated $U->{derby_name} ($U->{RCid}) to work in $DEPT->{$D} Department");
logit ($U->{RCid}, "Activated to work in $DEPT->{$D} Department");
}
 
sub printError {
my $message = shift // "";
print $h->div ({ class=>"error" }, "ERROR! ".$message);
$h->button ({ onClick=>"window.close();" }, "Close");
print $h->close ("body"), $h->close ("html");
die;
}
 
sub sendEmail {
use RCMailer;
my $data = shift;
 
my $email = $data->{email};
my $subject = "RollerCon Volunteer Schedule Manager - Added to $DEPT->{$targetDept} Department";
my $body = "Greetings,
 
This should hopefully not be the first automated message you've received from us. Your account to volunteer in the $DEPT->{$targetDept} Department at RollerCon with the following information:
 
Derby Name: $data->{derby_name}
Real Name: $data->{real_name}
Email Address: $data->{email}
Phone: $data->{phone}
 
Has been activated!
 
You are now able to log in to view and sign up for shifts! YAAAAAYYYY!!!!! (Imagine Kermit the Frog doing muppet hands here.)
 
https://volunteers.rollercon.com/schedule/
 
Please note that you are limited to signing up to a limnited number of shifts per day. (Meaning, once you sign up for X shifts, you'll have to wait until tomorrow to sign up for more.) Please understand, while you are a nice, concientious, and good-looking person yourself, who knows how to share, there are others out there that will hogger up all of the shifts. As time goes by and we get closer to the event, we may lift the limit. Who knows?
 
If you've already signed up for your daily limit of shifts, and another shift REALLY strikes your fancy, try dropping one of your shifts. That should allow you to pick up a different one.
 
We'll be adding shifts over time, again to throttle how fast some people (not you, mind you) gobble up the shifts. Check back, maybe even daily.
 
If you're new to using vORC, you may want to read this:
 
https://volunteers.rollercon.com/info.html
 
If you didn't make this request, well, you're still the only one who received this email, and you now have an active account. You should probably let us know that someone is messing with you, or just sign up for shifts (if you're actually coming to RollerCon, that is).
 
-RollerCon Management
";
 
# send the message
EmailUser($email, $subject, $body);
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/activate_users.pl
0,0 → 1,80
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use CGI;
use CGI::Cookie;
use DBI;
use WebDB;
 
my $dbh = WebDB->connect ();
my $act_han = $dbh->prepare("update official set access = 1 where RCid = ?");
my $users = $dbh->prepare("select * from official where access = 0 order by RCid");
 
my $cookie_string = authenticate(5) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
logit($user->{RCid}, "Activated All Accounts");
 
printRCHeader("");
print<<page1;
<TR><TD colspan=2>
Activating registered users without access...<br>
Retrieving list of users who need to be activated...<br>
page1
 
$users->execute() || print $dbh->errstr && die("Failed to get users from database.");
while (my $U = $users->fetchrow_hashref()) {
print "&nbsp;&nbsp;&nbsp;&nbsp;Activating $U->{derby_name}...";
$act_han->execute($U->{RCid}) || print $dbh->errstr;
logit($U->{RCid}, "Account Activated (by ".getUser($EML)->{derby_name}.")");
logit($user->{RCid}, "Activated ".$U->{derby_name}." (".$U->{RCid}.")");
sendEmail($U);
print "Done.<br>\n";
}
 
print "<br><br><a href='/schedule/'>[Home]</a>";
 
 
sub sendEmail {
use RCMailer;
my $data = shift;
 
my $email = $data->{email};
my $subject = 'Officiating RollerCon Schedule Manager - User Activated';
my $body = "Greetings,
 
This should hopefully be the second automated message you've received from us. Your new account to Volunteer at RollerCon with the following information:
 
Derby Name: $data->{derby_name}
Real Name: $data->{real_name}
Email Address: $data->{email}
Phone: $data->{phone}
Type: $data->{type}
Level: $data->{level}
 
Has been activated!
 
You are now able to log in to view and sign up for shifts! YAAAAAYYYY!!!!! (Imagine Kermit the Frog doing muppet hands here.)
 
https://volunteers.rollercon.com/schedule/
 
Please note that for now, you are limited to signing up to two shifts per day. (Meaning, once you sign up for two shifts, you'll have to wait until tomorrow to sign up for two more.) Please understand, while you are a nice, concientious, and good-looking person yourself, who knows how to share, there are others out there that will hogger up all of the shifts. As time goes by and we get closer to the event, we may lift the limit. Who knows?
 
If you've already signed up for two, and another shift REALLY strikes your fancy, try dropping one of your shifts. That should allow you to pick up a different one.
 
We'll be adding shifts over time, again to throttle how fast some people (not you, mind you) gobble up the shifts. Check back, maybe even daily.
 
If you didn't make this request, well, you're still the only one who received this email, and you now have an active account. You should probably let us know that someone is messing with you, or just sign up for shifts (if you're actually coming to RollerCon, that is).
 
-RollerCon Officiating Management
";
 
# send the message
EmailUser($email, $subject, $body);
}
/tags/2022.final/site/schedule/announcer_shifts.pl
0,0 → 1,453
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
use DateTime;
use DateTime::Duration;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
 
my $cookie_string = authenticate (1) || die;
# Add checking to make sure they're in this department
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
 
if ($user->{department}->{"ANN"} < 1 and $LVL < 4) {
print header(-cookie=>$RCAUTH_cookie);
printRCHeader("Unauthorized Page");
print $h->div ({ class=>"error" }, "You're not an Announcer");
print $h->div ("Your user account is not registered as an Announcer, so you can't see these shifts. It's possible that your access is still being reviewed. Please be patient.");
print $h->a ({ href=>"/schedule/" }, "[Go Home]");
print $h->close ("html");
exit;
}
 
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
#my $YEAR = 1900 + (localtime)[5]; #which year of data to display, default to current
my $YEAR = "2022";
 
#$LVL = 1;
 
my $pageTitle = "Announcer Shifts";
my $prefscookie = "ashiftscookie";
our $DBTABLE = 'v_shift_announcer';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
id => [qw(ID 5 number )],
date => [qw(Date 10 date default )],
dayofweek => [qw(Day 15 select )],
time => [qw(Time 20 text default )],
volhours => [qw(VolHours 23 number )],
track => [qw(Track 25 select default )],
teams => [qw(Teams 30 text default )],
level => [qw(Level 35 select default )],
restrictions => [qw(Rs 40 select )],
gtype => [qw(Type 45 select default )],
signup => [qw(SignUp 46 select )],
notes => [qw(Notes 50 text )],
role => [qw(Role 55 select )],
tla => [qw(TLA 60 select default )],
name => [qw(Position 65 text )],
type => [qw(Class 70 select default )],
RCid => [qw(RCid 75 number )],
derby_name => [qw(Assignee 80 select default )]
);
 
if ($user->{department}->{"ANN"} > 1) {
# Add:
# real_name RealName
# email Email
$COLUMNS{'real_name'} = [qw(RealName 85 text)];
$COLUMNS{'email'} = [qw(Email 90 text)];
}
 
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem (RETURN the modified field at the end of the function!)
 
sub modify_derby_name {
my $t = shift;
 
if ($user->{department}->{"ANN"} < 2 and $t->{derby_name} and $t->{RCid} != $RCid and $LVL < 5) {
$t->{derby_name} = "FILLED";
}
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
 
if (($t->{RCid} == $RCid and $t->{signup} ne "selected" and $now < $cutoff) or ($t->{derby_name} and ($user->{department}->{"ANN"} >= 2 or $LVL >= 5))) {
# DROP
$t->{derby_name} = "$t->{derby_name} <A HREF='#' onClick=\"window.open('make_shift_change.pl?change=del&RCid=$t->{RCid}&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
if ($user->{department}->{"ANN"} >= 2 or $LVL > 4) {
# NO SHOW
$t->{derby_name} .= " | <A HREF='#' onClick=\"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$t->{RCid}&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[NO SHOW]</a>";
}
} elsif (!$t->{derby_name}) {
$t->{dept} = "ANN";
if ($t->{track} eq "C2") {
return $t->{derby_name};
}
if (signUpEligible ($ORCUSER, $t) and $now < $cutoff) {
# SIGN UP
$t->{derby_name} = "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[SIGN UP]</a>";
}
if ($user->{department}->{"ANN"} >= 2 or $LVL > 4) {
# ADD USER
$t->{derby_name} ? $t->{derby_name} .= " | " : {};
$t->{derby_name} .= "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[ADD USER]</a>";
}
}
return $t->{derby_name};
}
 
 
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") { # Compile list of fields to display
if ($_ ne "shiftinclude") {
push @displayFields, $_;
}
}
}
 
my @addToWhereClause = ("year(date) = '$YEAR'", "type = 'announcer'");
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al, $si) = split /&/, $prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$FORM{shiftinclude} = $si;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
my @whereClause = map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
push @whereClause, @addToWhereClause;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my @shifts;
if ($FORM{shiftinclude} eq "true") {
my @SIWhere = ("year(date) = '$YEAR'");
push @SIWhere, "RCid = $ORCUSER->{RCid}";
my ($d, $c) = getData (\@displayFields, \@SIWhere, $DBTABLE, $FORM{sortby});
@shifts = @{ $d };
}
 
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({ name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
my $SIChecked;
if ($FORM{shiftinclude}) {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
} else {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
my @yearoptions;
foreach (@{&getYears()}) {
push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
}
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs, $h->br,
"Show my shifts: ", $SIChecked, $h->br,
$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='manage_personal_time.pl'" }),
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
 
if ($FORM{shiftinclude}) { # Include all of the user's shifts at the top
foreach my $t (@shifts) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
print $h->hr ({ width=>"500%" });
}
 
 
# Print the things
foreach my $t (@ProductList) {
if ($t->{RCid} eq $ORCUSER->{RCid}) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
} else {
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
}
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com",
$h->br,
"Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/bulk_upload.pl
0,0 → 1,142
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use HTML::Tiny;
use CGI qw/param header start_html url uploadInfo/;
my $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (5) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $ID = getUser ($EML);
my $RCAUTH_cookie = cookie (-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $tmpdir = "/tmp/";
 
 
print header (-cookie=>$RCAUTH_cookie),
start_html (-title => "Bulk Upload vORC Data", -style => {'src' => "/style.css"} );
 
if (defined (param ("uploadedfile"))) {
process_form ();
} else {
display_upload_form ();
}
 
print end_html ();
 
use CGI qw(:standard escape escapeHTML);
 
sub display_upload_form {
print $h->div ("Upload a CSV File of department shifts...");
print $h->div ("These should be the columns: (dept, role, type, date, location, start_time, end_time, doubletime, note)");
print start_multipart_form (-action => url ()),
# "Upload File: ", br (),
$h->input ({
name => "uploadedfile",
class => "inputfile",
type => "file",
id => "file",
size => 60
}) . $h->label ({ for=>"file", class=>"top" }, $h->span ("Choose File...")),
br (), br (),
submit (-name => "choice", -value => "Submit"), $h->input ({ type=>"button", value => "Cancel" , onClick=>"history.back(); return false;" }),
end_form ();
printJavascript ();
}
 
sub printJavascript {
print<<JSCRIPT;
<SCRIPT language="JavaScript">
<!--
 
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
 
input.addEventListener( 'change', function( e )
{
var fileName = e.target.value.split( '\\\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
 
//-->
</SCRIPT>
 
 
JSCRIPT
}
 
sub process_form {
use WebDB;
my $dbh = WebDB::connect ();
my $uploadedfile = param ("uploadedfile");
my @errors = ();
my $mime_type;
my $serve_url;
logit ($ID->{RCid}, "Bulk Uploaded shifts from file $uploadedfile");
 
push (@errors, "Please specify a file") if $uploadedfile eq "";
$mime_type = uploadInfo ($uploadedfile)->{'Content-Type'};
if ($mime_type ne "text/csv") {
push @errors, "Expecting a CSV file, but received a '$mime_type'.";
}
if (@errors) {
print p ("The following errors occurred:");
print ul (li (\@errors));
print p ("Please click your Browser's Back button to\n"
. "return to the previous page and correct the problem.");
return;
} # Form was okay;
print $h->div ("Processing file...");
my $fh = upload ('uploadedfile');
 
my @columnlabels = split /,/, <$fh>;
@columnlabels = map { s/[^\x00-\x7f]//g; WebDB::trim ($_) } @columnlabels;
my $idtrue = 0;
if ($columnlabels[0] eq "id") {
$idtrue = 1;
shift @columnlabels;
}
my @AcceptableColumns = qw(dept, role, type, date, location, start_time, end_time, doubletime, note);
 
my $fields = join ", ", @columnlabels;
my $values = join ", ", map { '?' } 0..$#columnlabels;
my $sth = $dbh->prepare ("insert into shift ($fields) values ($values)");
while (<$fh>) {
chomp;
my @R = map { s/[^\x00-\x7f]//g; WebDB::trim ($_) } split /,/;
shift @R if $idtrue;
push @R, "" if (scalar @R < scalar @columnlabels and eof);
print "inserting: ", join (" ", @R), $h->br;
$sth->execute (map { defined $_ ? $_ : undef } @R) or print $sth->errstr;
}
print "DONE!", $h->br, $h->br;
$dbh->disconnect (); # Image was stored into database successfully. Present confirmation
# Display link to main page so user can upload another image
print $h->hr, $h->a ({ href => url }, "[Upload another file]"), $h->a ({ href => "/schedule/" }, "[Home]");
}
 
 
sub error {
my $msg = shift;
print p (escapeHTML ("Error: $msg")), end_html ();
exit (0);
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/daily_print.pl
0,0 → 1,171
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use WebDB;
use tableViewer;
use CGI;
use CGI::Cookie;
use DateTime;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $date = param ("date");
my $dt;
if ($date =~ /^\d{4}-\d{2}-\d{2}$/) {
my ($YYYY, $MM, $DD) = split /-/, $date;
$dt = DateTime->new(
year => $YYYY,
month => $MM,
day => $DD
);
} else {
$dt = DateTime->today;
$date = $dt->date;
}
my $day = $dt->day_name;
 
my %class = qw(
U Unrestricted
M Mens
W Womens
SS Single-Gender
);
 
my $dbh = WebDB::connect ();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
 
 
 
print<<output;
<html><head><title>RollerCon VORC - Daily Officiating Schedule - $day ($date)</title>
<link rel="stylesheet" type="text/css" href="/rollercon.css">
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
output
 
my $gcount = 1; my $tcount = '';
my $sth = $dbh->prepare("select distinct teams, track, level, time, gtype, restrictions from v_shift_officiating where date = ? order by track, time");
my $crewhan = $dbh->prepare("select role, derby_name from v_shift_officiating where date = ? and track = ? and time = ?");
my $leadhan = $dbh->prepare("select location, time, derby_name from v_shift where dept = 'OFF' and date = ? order by location, time");
my $openshifthan = $dbh->prepare("select time, level, restrictions, gtype, teams, tla, name from v_shift_officiating where tla <> 'ALT' and isNull(derby_name) = 1 and date = ? and track = ? order by time");
 
my @leads = ("<table>\n", "<tr><td colspan=5><b>Lead Shifts</b></td></tr>\n");
$leadhan->execute($date);
my $tc = 'C1';
while (my $lshift = $leadhan->fetchrow_hashref()) {
if ($tc ne $lshift->{location}) {
push @leads, "<tr><td colspan=5>&nbsp;</td></tr>\n";
$tc = $lshift->{location};
}
push @leads, "<tr><td>$lshift->{location}</td><td>&nbsp;</td><td>$lshift->{time}</td><td>&nbsp;</td><td>$lshift->{derby_name}</td></tr>\n";
}
push @leads, "</table>\n";
 
$sth->execute($date);
while (my $g = $sth->fetchrow_hashref()) {
if ($tcount ne $g->{track}) { #pagebreak whenever we change tracks
print "<div class='pagebreak'><hr></div>\n" unless !$tcount;
print @leads;
my @openshifts = ("<table>\n", "<tr><td colspan=5><b>Open Shifts on $g->{track}</b></td></tr>\n");
$openshifthan->execute($date, $g->{track});
while (my @oshift = $openshifthan->fetchrow_array()) {
my $sh = join "</td><td>&nbsp;</td><td>", @oshift;
push @openshifts, "<tr><td>$sh</td></tr>\n";
}
push @openshifts, "</table>\n";
print "<br><br><br><br>";
print @openshifts;
print "<div class='pagebreak'><hr></div>\n";
$gcount = 1;
$tcount = $g->{track};
}
$g->{gtype} = join '', map { ucfirst lc } split /(\s+)/, $g->{gtype}; # Capitalize the game time to look nicer
 
my %crew;
$crewhan->execute($date, $g->{track}, $g->{time});
while (my ($k, $v) = $crewhan->fetchrow_array()) {
$crew{$k} = $v;
}
my $P1 = "PLT-1";
my $P2 = "PLT-2";
my $PH = "PLT";
my $OPR1 = "OPR-1";
if ($g->{gtype} eq "Full Length" or $g->{gtype} eq "Selected Staffing") {
$P1 = 'PLT/H';
$P2 = 'PLT';
$PH = $P1;
} elsif ($g->{gtype} eq "Challenge-rs1") {
$crew{'OPR-1'} = "<i>-not staffed-</i>";
$crew{'OPR-2'} = "<i>-not staffed-</i>";
$crew{'OPR-3'} = "<i>-not staffed-</i>";
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
} elsif ($g->{gtype} eq "Challenge-rs2") {
$OPR1 = "OPR";
 
$crew{'IPR'} = "<i>-not staffed-</i>";
$crew{'OPR-2'} = "<i>-not staffed-</i>";
$crew{'OPR-3'} = "<i>-not staffed-</i>";
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
} elsif ($g->{gtype} eq "Scrimmage") {
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
$crew{'PBT-1'} = "<i>-not staffed-</i>";
$crew{'PBT-2'} = "<i>-not staffed-</i>";
$crew{'SO'} = "<i>-not staffed-</i>";
}
my $A = '';
if (defined $crew{'ALT'}) {
$A = "ALT:";
} else {
$crew{'ALT'} = '';
}
print<<game;
<table>
<tr><td>Date:</td><td>$day ($date)</td><td>&nbsp;</td><td>Track:</td><td>$g->{track}</td></tr>
<tr><td>Time:</td><td>$g->{time}</td><td>&nbsp;</td><td>Class:</td><td>$class{$g->{restrictions}} $g->{level} $g->{gtype}</td></tr>
<tr><td>Game:</td><td colspan=4>$g->{teams}</td></tr>
<tr><td colspan=5>&nbsp;</td></tr>
<tr><td>HR:</td><td>$crew{'HR'}</td><td>&nbsp;</td><td>$PH:</td><td>$crew{$P1}</td></tr>
<tr><td>IPR:</td><td>$crew{'IPR'}</td><td>&nbsp;</td><td>PLT:</td><td>$crew{$P2}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-1'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-1'}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-2'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-2'}</td></tr>
<tr><td>OPR:</td><td>$crew{$OPR1}</td><td>&nbsp;</td><td>PBM:</td><td>$crew{'PBM'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-2'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-1'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-3'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-2'}</td></tr>
<tr><td>$A</td><td>$crew{'ALT'}</td><td>&nbsp;</td><td>JT:</td><td>$crew{'JT'}</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>SO:</td><td>$crew{'SO'}</td></tr>
</table><br><br><br><br><br><br><br><br><br><br><br><br>
game
 
$gcount++ % 2 == 0 ? print "<div class='pagebreak'><hr></div>\n" : { };
}
 
 
 
print<<tail;
</BODY>
</HTML>
tail
/tags/2022.final/site/schedule/daily_print_announcers.pl
0,0 → 1,127
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use WebDB;
use tableViewer;
use CGI;
use CGI::Cookie;
use DateTime;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $date = param ("date");
my $dt;
if ($date =~ /^\d{4}-\d{2}-\d{2}$/) {
my ($YYYY, $MM, $DD) = split /-/, $date;
$dt = DateTime->new(
year => $YYYY,
month => $MM,
day => $DD
);
} else {
$dt = DateTime->today;
$date = $dt->date;
}
my $day = $dt->day_name;
 
my %class = qw(
U Unrestricted
M Mens
W Womens
SS Single-Gender
);
 
my $dbh = WebDB::connect ();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
 
 
 
print<<output;
<html><head><title>RollerCon VORC - Daily Announcer Schedule - $day ($date)</title>
<link rel="stylesheet" type="text/css" href="/rollercon.css">
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
output
 
my $gcount = 1; my $tcount = '';
my $sth = $dbh->prepare("select distinct teams, track, level, time, gtype, restrictions from v_shift_announcer where date = ? order by track, time");
my $crewhan = $dbh->prepare("select role, derby_name from v_shift_announcer where date = ? and track = ? and time = ?");
my $leadhan = $dbh->prepare("select location, time, derby_name from v_shift where dept = 'ANN' and date = ? order by location, time");
my $openshifthan = $dbh->prepare("select time, level, restrictions, gtype, teams, tla, name from v_shift_announcer where tla <> 'ALT' and isNull(derby_name) = 1 and date = ? and track = ? order by time");
 
my @leads = ("<table>\n", "<tr><td colspan=5><b>Lead Shifts</b></td></tr>\n");
$leadhan->execute($date);
my $tc = 'C1';
while (my $lshift = $leadhan->fetchrow_hashref()) {
if ($tc ne $lshift->{location}) {
push @leads, "<tr><td colspan=5>&nbsp;</td></tr>\n";
$tc = $lshift->{location};
}
push @leads, "<tr><td>$lshift->{location}</td><td>&nbsp;</td><td>$lshift->{time}</td><td>&nbsp;</td><td>$lshift->{derby_name}</td></tr>\n";
}
push @leads, "</table>\n";
 
$sth->execute($date);
while (my $g = $sth->fetchrow_hashref()) {
if ($tcount ne $g->{track}) { #pagebreak whenever we change tracks
print "<div class='pagebreak'><hr></div>\n" unless !$tcount;
print @leads;
my @openshifts = ("<table>\n", "<tr><td colspan=5><b>Open Shifts on $g->{track}</b></td></tr>\n");
$openshifthan->execute($date, $g->{track});
while (my @oshift = $openshifthan->fetchrow_array()) {
my $sh = join "</td><td>&nbsp;</td><td>", @oshift;
push @openshifts, "<tr><td>$sh</td></tr>\n";
}
push @openshifts, "</table>\n";
print "<br><br><br><br>";
print @openshifts;
print "<div class='pagebreak'><hr></div>\n";
$gcount = 1;
$tcount = $g->{track};
}
$g->{gtype} = join '', map { ucfirst lc } split /(\s+)/, $g->{gtype}; # Capitalize the game time to look nicer
 
my %crew;
$crewhan->execute($date, $g->{track}, $g->{time});
while (my ($k, $v) = $crewhan->fetchrow_array()) {
$crew{$k} = $v;
}
my $A = '';
if (defined $crew{'ALT'}) {
$A = "ALT:";
} else {
$crew{'ALT'} = '';
}
print<<game;
<table>
<tr><td>Date:</td><td>$day ($date)</td><td>&nbsp;</td><td>Track:</td><td>$g->{track}</td></tr>
<tr><td>Time:</td><td>$g->{time}</td><td>&nbsp;</td><td>Class:</td><td>$class{$g->{restrictions}} $g->{level} $g->{gtype}</td></tr>
<tr><td>Game:</td><td colspan=4>$g->{teams}</td></tr>
<tr><td colspan=5>&nbsp;</td></tr>
<tr><td>Color:</td><td colspan=4>$crew{'COL'}</td></tr>
<tr><td>Play-by-play:</td><td colspan=4>$crew{'PBP'}</td></tr>
<tr><td>Sponsorship:</td><td colspan=4>$crew{'SPO'}</td></tr>
</table><br><br><br><br><br><br><br><br><br><br><br><br>
game
 
$gcount++ % 4 == 0 ? print "<div class='pagebreak'><hr></div>\n" : { };
}
 
 
 
print<<tail;
</BODY>
</HTML>
tail
/tags/2022.final/site/schedule/export_ics.pl
0,0 → 1,98
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use Data::ICal;
use Data::ICal::Entry::Event;
use Date::ICal;
use DateTime;
use Date::Calc qw(Add_Delta_DHMS);
use Time::HiRes;
 
use CGI qw(:standard);
use DBI;
use tableViewer;
use WebDB;
 
 
my %games = ();
my @shifts = ();
 
my $query = new CGI;
my $RCid = $query->param('RCid');
if (!$RCid) { $RCid = '0'; }
 
my @stamp = localtime();
my $dstamp = sprintf("%d%02d%02dT%02d%02d%02dZ",
$stamp[5] + 1900,
$stamp[4] + 1,
$stamp[3],
$stamp[2],
$stamp[1],
$stamp[0]);
 
my $tz = DateTime::TimeZone->new(name => 'America/Los_Angeles');
 
my $dbh = WebDB::connect;
my $sth = $dbh->prepare("select * from (select id, date, dayofweek, track as 'location', time, role, teams from v_shift_officiating where RCid = ? union select id, date, dayofweek, track as 'location', time, role, teams from v_shift_announcer where RCid = ? union select id, date, dayofweek, location, time, role, '' as teams from v_shift where RCid = ?) temp order by date, time");
$sth->execute($RCid, $RCid, $RCid);
while (my $s = $sth->fetchrow_hashref) {
$s->{role} =~ s/\-\d$//;
push @shifts, $s;
}
 
my $calendar = Data::ICal->new();
my $count = 0;
 
for my $S (@shifts) {
my ($startyear, $startmonth, $startday) = split /\-/, $S->{date};
my ($endyear, $endmonth, $endday) = ($startyear, $startmonth, $startday);
my ($stime, $etime) = split / \- /, $S->{time};
my ($starthour, $startmin) = split /:/, $stime;
my ($endhour, $endmin) = split /:/, $etime;
my $event = Data::ICal::Entry::Event->new();
my @tm = localtime();
my $uid = sprintf("%d%02d%02d%02d%02d%02d%s%02d\@rollercon.com",
$tm[5] + 1900, $tm[4] + 1, $tm[3], $tm[2],
$tm[1], $tm[0], scalar(Time::HiRes::gettimeofday()), $count);
$event->add_properties(
uid => $uid,
summary => "vORC: $S->{role} on $S->{location} - $S->{teams}",
description => "" ,
categories => "RollerCon Officiating;RollerCon Schedule;RollerCon Volunteer",
location => "$S->{location}",
dtstamp => $dstamp,
dtstart => Date::ICal->new(
year => $startyear,
month => $startmonth,
day => $startday,
hour => $starthour,
min => $startmin,
sec => 0,
offset => "-0700")->ical,
dtend => Date::ICal->new(
year => $endyear,
month => $endmonth,
day => $endday,
hour => $endhour,
min => $endmin,
sec => 0,
offset => "-0700")->ical,
);
 
$calendar->add_entry($event);
$count++;
}
 
$calendar->add_properties(
# calscale => 'GREGORIAN',
# method => 'PUBLISH',
'X-WR-CALNAME' => 'RollerCon Volunteer Schedule'
);
 
print header('Content-type: text/calendar; charset=utf-8');
#print header('Content-Disposition: attachment; filename=export_ics.pl.ics');
print $calendar->as_string;
/tags/2022.final/site/schedule/index.pl
0,0 → 1,149
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use CGI;
use CGI::Cookie;
use WebDB;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate(1) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
$user->{department} = convertDepartments $user->{department};
my $activated = max (values %{ $user->{department} });
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $DEPTS = getDepartments;
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
#foreach (sort keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
 
#use DBI;
#my $dbh = WebDB->connect ();
my $dbh = getRCDBH;
 
use DateTime;
my $dt = DateTime->today;
$dt =~ s/T00\:00\:00$//;
 
my $schedule = getSchedule ($user->{RCid});
 
my @everyone;
my @printDEPTS = map { $DEPTS->{$_} } grep { $user->{department}->{$_} > 0 } grep { !/(ANN)|(OFF)/ } sort keys %{$user->{department}};
push @printDEPTS, "Officiating Lead" if $user->{department}->{"OFF"} > 1;
my $printDEPTS = join ", ", @printDEPTS;
push @everyone, $h->li ($h->a ({ href=>"/schedule/shifts.pl" }, "View and Sign Up for $printDEPTS Shifts")) if $printDEPTS;
push @everyone, $h->li ($h->a ({ href=>"/schedule/officiating_shifts.pl" }, "View and Sign Up for Officiating Shifts")) if $user->{department}->{OFF} > 0;
push @everyone, $h->li ($h->a ({ href=>"/schedule/announcer_shifts.pl" }, "View and Sign Up to Announce Games")) if $user->{department}->{ANN} > 0;
push @everyone, $h->li ($h->a ({ href=>"/schedule/manage_personal_time.pl" }, "Block Personal Time"));
push @everyone, $h->li ($h->a ({ href=>"/schedule/manage_user.pl?submit=Edit&RCid=$user->{RCid}" }, "Edit your profile"));
 
my @mvppass;
if ($user->{department}->{CLA} > 0) {
push @mvppass, $h->li ($h->a ({ href=>"/schedule/mvpclasses.pl" }, "View and Sign Up for MVP Classes"))
}
 
my @leads = ();
if ($LVL > 1) {
push @leads, $h->li ($h->a ({ href=>"/schedule/user_report.pl" }, "View Users in your Department(s)."));
push @leads, $h->li ($h->a ({ href=>"/schedule/password_reset.pl" }, "Reset a Password."));
 
# Officiating Leads:
if ($user->{department}->{OFF} > 1) {
unshift @leads, $h->li ($h->a ({ href=>"/schedule/scores.pl" }, "View / Update Game Scores"));
# push @leads, $h->li ($h->a ({ href=>"daily_print.pl" }, "Daily Print Report"));
push @leads, $h->li (["What's happening right now on...", $h->ul ([
$h->li ($h->a ({ href=>"right_now.pl?t=C1" }, "Track C1")),
$h->li ($h->a ({ href=>"right_now.pl?t=C2" }, "Track C2")),
$h->li ($h->a ({ href=>"right_now.pl?t=C3" }, "Track C3")),
$h->li ($h->a ({ href=>"right_now.pl?t=C4" }, "Track C4")),
# $h->li ($h->a ({ href=>"right_now.pl?t=B" }, "Track B")),
])]);
}
}
my @managers;
if ($LVL >= 3) {
my $manager_departments = join " or ", map { "department like '%$_-0%'" } grep { $user->{department}->{$_} > 2 } keys %{$user->{department}};
if ($manager_departments) {
my ($count) = $dbh->selectrow_array ("select count(*) from official where $manager_departments");
my $counttxt = $count == 1 ? "is 1 user" : "are $count users";
push @managers, $h->li ($h->a ({ href=>"user_report.pl?autoload=1&RCid=true&derby_name=true&email=true&real_name=true&access=true&department=true&added=true&filter-RCid=&filter-derby_name=&filter-email=&filter-real_name=&filter-access=0&filter-department=&filter-added=&sortby=derby_name&limit=25&page=1" }, "There $counttxt waiting to be activated")) if $count;
}
push @managers, $h->li ($h->a ({ href=>"/schedule/log.pl" }, "Activity Log"));
push @managers, $h->li ($h->a ({ href=>"/schedule/volhours.pl" }, "View Volunteer Hours by Department"));
foreach (grep { $user->{department}->{$_} > 2 } keys %{$user->{department}}) {
push @managers, $h->li ($h->a ({ href=>"/schedule/shifts.pl?autoload=1&dept=true&role=true&dayofweek=true&location=true&time=true&note=true&derby_name=true&filter-dept=$_&sortby=dayofweek&limit=All&page=1" }, "$DEPTS->{$_} Staff Schedule"));
}
if ($user->{department}->{VCI} > 2 or $user->{department}->{MVP} > 2 or $LVL > 4) {
push @managers, $h->li ($h->a ({ href=>"/schedule/mvp_class_report.pl", target=>"_new" }, "Daily MVP Class Report (for print)"));
push @managers, $h->li ($h->a ({ href=>"/schedule/daily_print.pl", target=>"_new" }, "Daily Officiating Report (for print)"));
push @managers, $h->li ($h->a ({ href=>"/schedule/daily_print_announcers.pl", target=>"_new" }, "Daily Announcers Report (for print)"));
push @managers, $h->li ($h->a ({ href=>"/schedule/print_dept_by_day.pl", target=>"_new" }, "BETA: Daily Shift Report (for print)"));
}
# Shift Report: select dayofweek, count(RCid) as filled_shifts, count(*) - count(RCid) as open_shifts, count(*) as total_shifts from v_shift group by date order by date
}
 
my @sysadmins;
if ($LVL >= 5) {
push @sysadmins, $h->li ($h->a ({ href=>"/schedule/bulk_upload.pl" }, "Upload a CSV of Department Shifts"));
push @sysadmins, $h->li ($h->a ({ href=>"/schedule/manage_shifts.pl" }, "Update department shift schedule"));
my ($signupcount) = $dbh->selectrow_array ("select count(*) from v_shift where dept = ? and RCid <> ''", undef, "CLA");
my ($mvpcount) = $dbh->selectrow_array ("select count(*) from official where department REGEXP ?", undef, "CLA-1");
$mvpcount = 265 unless $mvpcount;
push @sysadmins, $h->li ($mvpcount." MVP Passholders have signed up for ".$signupcount." spots (".sprintf("%.2f", ($signupcount / ($mvpcount*6)) * 100)."\%).");
my ($active) = $dbh->selectrow_array ("select count(distinct RCid) as users from log where timestamp > (now() - interval 30 minute) and event not like 'Updated User Details%' and event not like 'Activated to work%'");
#my ($active) = $dbh->selectrow_array ("select * from official where last_login > (now() - interval 150 minute) order by last_login desc");
push @sysadmins, $h->li ("There seem to be about $active user session(s) right now.");
# push @sysadmins, $h->li ($h->a ({ href=>"/schedule/volhours.pl" }, "View Volunteer Hours by Department"));
}
 
my @activity_log;
my $alog = $dbh->prepare("select timestamp, event from v_log where RCid = ? limit 10");
$alog->execute($user->{RCid});
while (my @logs = $alog->fetchrow_array) {
my ($d, $t) = split /\s+/, $logs[0];
push @activity_log, $h->li ({ class=>"shaded" }, join " ", @logs);
}
 
my @reference;
push @reference, $h->li ($h->a ({ href=>"/info.html" }, "Information about using this tool"));
push @reference, $h->li ($h->a ({ href=>"http://rollercon.com/help-wanted/officiating/" }, "RollerCon Officiating Details"));
 
printRCHeader("Home");
print $h->close ("table");
 
print $h->form ({ name=>"Req", action=>url });
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Note:"), "<b>Your account is being reviewed.</b>", $h->br, "You won't have access to view or sign-up for things until you've been approved / added to a department.", $h->br, "Please watch your email for notifications." ]) unless $activated;
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Your up-coming schedule (as of $dt):"), $schedule, $h->h5 ("[".$h->a ({ href=>"export_ics.pl?RCid=$user->{RCid}" }, "use this link for iCal")."]") ]) if $schedule;
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "MVP Pass Holders:"), $h->ul ([ @mvppass ]) ]) if (scalar @mvppass);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Things you can do:"), $h->ul ([ @everyone ]) ]);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Things you can do as a Lead:"), $h->ul ([ @leads ]) ]) if ($LVL > 1);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Things you can do as a Manager:"), $h->ul ([ @managers ]) ]) if ($LVL > 2);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Things you can do as a SysAdmin:"), $h->ul ([ @sysadmins ]) ]) if ($LVL >= 5);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Your Latest Activity:"), $h->ul ([ @activity_log ]), $h->h5 ($h->a ({ href=>"log.pl?excel=0&autoload=1&eventid=true&timestamp=true&event=true&RCid=true&derby_name=true&filter-timestamp=&filter-event=&filter-RCid=".$user->{RCid}."&filter-derby_name=&sortby=eventid&limit=25&page=1" }, "[Your entire log history]")) ]);
 
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Reference:"), $h->ul ([ @reference ]) ]);
 
print $h->close ("body"), $h->close ("html");
;
 
/tags/2022.final/site/schedule/lead_shifts.pl
0,0 → 1,406
#!/usr/bin/perl
 
######################################
#
#
# $Log: req.pl,v $
#
######################################
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
use CGI qw/:standard/;
use lib "/home/rollerco/perl5/lib/perl5";
use scanFunctions;
use RollerCon;
use Spreadsheet::WriteExcel;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $username = $user->{derby_name};
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR = 1900 + (localtime)[5]; #which year of data to display, default to current
 
our $DBTABLE = 'v_lead_shift';
our @allFields = (qw(id date dayofweek track time assignee_id derby_name));
our @defaultFields = (qw(date track time derby_name));
our @displayFields = ();
our @hideFields = ();
our %NAME = (
"id" => "ID",
"date" => "Date",
"dayofweek" => "Day",
"track" => "Track",
"time" => "Time",
"assignee_id" => "RCid",
"derby_name" => "Name"
);
our %colOrderHash = (
"id" => 5,
"date" => 10,
"dayofweek" => 12,
"track" => 15,
"time" => 25,
"assignee_id" => 30,
"derby_name" => 35
);
our %colFilterTypeHash = (
"id" => "number",
"date" => "date",
"dayofweek" => "select",
"track" => "select",
"time" => "text",
"assignee_id" => "number",
"derby_name" => "select"
);
my $orderby = "date, track, time";
 
 
foreach (param())
{
if (/^year$/) { #
$YEAR = param($_);
next;
}
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) # Build a set of filters to apply
{
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
}
elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; } # @displayFields is declared in scanFunctions.pm
}
 
 
if (exists $FORM{autoload}) # If the FORM was submitted (i.e. the page is being redisplayed),
{ # build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my @filters;
my @f = keys %{$FILTER};
foreach $key (@f)
{ push @filters, "$key=$FILTER->{$key}"; }
my $fils = join ":", @filters;
$QUERY_STRING = "$disFields\&$fils\&$FORM{autoload}";
}
 
 
if (!(exists $FORM{autoload})) # No FORM was submitted, suppply a default list of columns
{
if (my $prefs = cookie('RC_Lead_Shifts')) # Has this user been here before and saved a cookie?
{
my ($disF, $filts, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach $pair (split /:/, $filts)
{
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
}
else
{ @displayFields = @defaultFields; }
}
 
 
# Build the field lists to display and hide columns.
# If the field isn't in the displayFields list,
# then add it to the hideFields list.
#
@displayFields = sort byfield @displayFields;
foreach $field (@allFields) { if (! &inArray($field, \@displayFields)) { push @hideFields, $field; } }
 
 
my @whereClause = ("year(date) = '$YEAR'"); # Process the filters to build the components of the where clause
foreach $field (@allFields)
{
if (! &inArray($field, \@hideFields))
{
if ($FILTER->{$field})
{
push @whereClause, &generica($field, $FILTER->{$field});
delete $FILTER->{$field};
}
}
}
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my @ProductList = @{&getData(\@displayFields, \@whereClause, $DBTABLE, $orderby)};
my $x = scalar @ProductList;
 
 
if ($FORM{excel})
{
my $date = `date +"%m%d%y%H%M%S"`; chomp $date;
$filename = `dirname $ENV{REQUEST_URI}`; chomp $filename; $filename .= "/xls/${date}_$$.xls";
# Create a new Excel workbook
my $workbook = Spreadsheet::WriteExcel->new("/home/rollerco/officials.rollercon.com${filename}");
# Add a worksheet
my $worksheet = $workbook->add_worksheet();
# open my $fh, '>', \my $str or die "Failed to open filehandle: $!";
# my $workbook = Spreadsheet::WriteExcel->new($fh);
# my $worksheet = $workbook->add_worksheet();
 
my $format = $workbook->add_format();
$format->set_bold();
my $col = $row = 0;
foreach $f (@displayFields)
{ $worksheet->write($row, $col++, "$NAME{$f}", $format); }
foreach $t (sort @ProductList) # Unt now we print the tickets!
{
$col = 0;
$row++;
foreach $f (@displayFields)
{
$f =~ s/^HOST\.//;
$f =~ s/^FRAME\.//;
$t->{$f} =~ s/<br>/\n/ig; $worksheet->write($row, $col++, "$t->{$f}");
}
}
$workbook->close();
 
}
 
 
 
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/';
my $queryCookie = cookie(-NAME=>'RC_Lead_Shifts',
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
#my $Auth_Cook = cookie(-NAME=>'RequestToolAuthorized',
# -VALUE=>"$authCookie",
# -PATH=>'/cbrt/cgi-bin/');
 
print header(-cookie=>[$RCAUTH_cookie,$queryCookie]);
 
 
print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
print "I'm catching updates!!!\n\n";
foreach $key (sort (keys %FORM)) # Must be done after the header is written!
{ print "\t$key: $FORM{$key}\n"; }
print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
 
if ($FORM{autoload}) # Toggle the autoload fields within the table elements
{ $auto = "onClick='submit();'";
$auto2 = "onChange='submit();'"; }
else
{ $auto = "";
$auto2 = ""; }
 
 
my $signedOnAs = $username ? "You are currently signed in as $username. <font size=-2><a href='index.pl' onClick=\"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;\">[Log Out]</a></font>" : "You are not signed in.";
my $xlsLink = $filename ? "&nbsp; &nbsp; <A href='$filename'><FONT color='#0077BD'>Download Now.</FONT></a>" : "";
my $yearoptions;
foreach (@{&getYears()}) {
$yearoptions .= $YEAR eq $_ ? "<option selected>$_</option>" : "<option>$_</option>";
}
 
print<<header;
<html><head><title>RollerCon Officials Schedule Manager - $YEAR Track Leads</title></head>
<body text="#000000" bgcolor="#FFFFFF" link="#000000" vlink="#000000" alink="#FF0000">
<form action="lead_shifts.pl" method=POST name=Req>
<input type=hidden name=excel value=0>
<TABLE cellpadding=0 cellspacing=0 hspace=0 vspace=0 border=0>
<TR>
<TD>
<TABLE cellpadding=0 cellspacing=0 hspace=0 vspace=0 border=0>
<TR>
<TD width=720 bgcolor="#0077BD" height=60><FONT color=white face=verdana size=6><i><strong>&nbsp;Officiating Track Lead Schedule - $YEAR</strong></i></font></TD>
<TD><img SRC="/images/headerblank.gif" NOSAVE height=38 width=165></TD>
</TR>
</TABLE>
</TD>
<TR>
<TD>&nbsp</TD>
</TR>
<TR>
<TD>
<TABLE cellpadding=0 cellspacing=0 hspace=0 vspace=0 border=0>
<TR>
<TD rowspan=2 align=left width=610>
<TABLE border=0 cellspacing=0>
header
 
# Print the Hidden fields' check boxes
 
my $tc = 1;
foreach $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields)
{
if ($tc == 1)
{print "\t\t\t\t\t\t<TR>\n\t\t\t\t\t\t\t<TD width=25% nowrap><FONT face=verdana size=1><b><INPUT type=checkbox name=$field value=true $auto>$NAME{$field}</TD>\n"; $tc++;}
elsif ($tc == 4)
{print "\t\t\t\t\t\t\t<TD width=25% nowrap><FONT face=verdana size=1><b><INPUT type=checkbox name=$field value=true $auto>$NAME{$field}</TD>\n\t\t\t\t\t\t</TR>\n"; $tc=1;}
else
{print "\t\t\t\t\t\t\t<TD width=25% nowrap><FONT face=verdana size=1><b><INPUT type=checkbox name=$field value=true $auto>$NAME{$field}</TD>\n"; $tc++;}
}
 
if ($FORM{autoload})
{
$trueChecked = "checked";
$falseChecked = "";
}
else
{
$trueChecked = "";
$falseChecked = "checked";
}
 
print<<header3;
<TR>
<TD colspan=4 align=center><FONT face=verdana size=1 color=#0077BD><B>
Autoload: <INPUT type=radio name=autoload value=1 onClick='Req.submit();' $trueChecked>On <INPUT type=radio name=autoload value=0 onClick='Req.submit();' $falseChecked>Off
</TD>
</TR>
</TABLE>
</TD>
<TD nowrap>
<A HREF='' onClick="window.document.Req.submit(); return false;"><IMG SRC='/images/refresh.button.gif' border=0></A><br>
<strong><a href='' onClick="window.document.Req.excel.value=1; window.document.Req.submit(); return false;"><FONT face=verdana size=1>Export Displayed Data as Excel Document.</a>$xlsLink</font>
</TD>
</TR>
<TR>
<TD align=left><B><FONT face=verdana size=1>$signedOnAs<br>
Display <A HREF='' onClick="window.document.Req.method = 'GET'; window.document.Req.submit(); return false;">Full URL</a> : <select name=year onchange='Req.submit();'>$yearoptions</select> : <a href=/schedule/>[Go HOME]</a></TD>
</TR>
 
</TABLE>
</TD>
</TR>
<TR>
<TD>&nbsp</TD>
</TR>
<TR>
<TD>
<TABLE border=0 cellspacing=2 cellpadding=4 width=100\%>
<TR bgcolor=#0077BD>
header3
 
# Print the Column headings
foreach $f (@displayFields)
{ print "\t\t\t\t\t<TD align=left nowrap><FONT face=verdana color=white size=1><B><INPUT type=checkbox name=$f value=true checked $auto>$NAME{$f}</TD>\n"; }
 
print "\t\t\t\t</TR>\n\t\t\t\t<TR>\n";
# and now the filter boxes
foreach $f (@displayFields)
{
print "\t\t\t\t\t<TD align=left bgcolor=#E6E6E6><FONT size=1 face=verdana>";
print &generica($f);
# print "&nbsp;";
print "</TD>\n";
}
print "\t\t\t\t</TR></FORM>\n";
 
my $cw = scalar @displayFields;
 
print<<header2;
</TR>
<TR>
<TD colspan=$cw><P><P></TD>
</TR>
header2
 
 
my $co = '#FFFFFF';
 
foreach $t (@ProductList) # Unt now we print the tickets!
{
if ($t->{assignee_id} == $RCid or ($LVL >= 3 and $t->{derby_name})) {
$t->{derby_name} = "$t->{derby_name} <A HREF='#' onClick=\"window.open('make_lead_shift_change.pl?change=del&shift=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
} elsif (!$t->{derby_name}) {
$t->{derby_name} = "<A HREF='#' onClick=\"window.open('make_lead_shift_change.pl?change=add&shift=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[SIGN UP]</a>";
}
 
print "\t\t\t\t<TR>\n";
foreach $f (@displayFields)
{
$f =~ s/^HOST\.//;
$f =~ s/^FRAME\.//;
print "\t\t\t\t\t<TD align=left valign=top bgcolor='$co'><FONT face=verdana size=1>".$t->{$f}."&nbsp</TD>\n";
}
print "\t\t\t\t</TR>\n";
 
if ($co eq '#FFFFFF')
{ $co = '#F9F9F9'; }
else
{ $co = '#FFFFFF'; }
}
 
print<<tail;
</TABLE>
</TD>
</TR>
</TABLE>
<br><br>
<FONT face=verdana size=2><B>$x Record(s) Displayed</font>
<BR><BR>
<FONT face=verdana size=1><B>This page was displayed on $now<BR>
Please direct questions, problems, and concerns to <FONT face=verdana color=#0077BD>officials.rollercon.schedule\@gmail.com</FONT>
 
<SCRIPT language="JavaScript">
<!--
 
var ticket_window, severity_window, user_window;
function NewWindow () {
if ((ticket_window == null) || (ticket_window.closed == true))
ticket_window = open(\"\",\"Details\",\"width=650,height=650,menubar,scrollbars,resizable\");
ticket_window.focus();
return true;
}
 
function SevWindow () {
if ((severity_window == null) || (severity_window.closed == true))
severity_window = open(\"\",\"SevDetails\",\"width=500,height=300,menubar\");
severity_window.focus();
return true;
}
function UserWindow () {
if ((user_window == null) || (user_window.closed == true))
user_window = open(\"\",\"UserDetails\",\"width=310,height=115,menubar\");
user_window.focus();
return true;
}
 
//-->
</SCRIPT>
 
tail
 
/tags/2022.final/site/schedule/log.pl
0,0 → 1,342
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (1) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
 
 
my $pageTitle = "Log Viewer";
my $prefscookie = "logscookie";
our $DBTABLE = 'v_log';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
eventid => [qw(EventID 5 number default )],
timestamp => [qw(Timestamp 10 date default )],
event => [qw(Event 15 text default )],
RCid => [qw(RCID 20 number default )],
derby_name => [qw(DerbyName 25 select default )],
email => [qw(Email 30 text )],
real_name => [qw(RealName 35 text )],
access => [qw(Role 40 select )]
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
my @whereClause;
push @whereClause, "RCid = $RCid" unless $LVL > 2;
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_derby_name {
my $li = shift;
return $h->a ({ href=>"manage_user.pl?RCid=$li->{RCid}" }, $li->{derby_name});
}
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
@whereClause = map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download an excel export, create the file...
my $filename = $FORM{excel} ? exportExcel (\@ProductList) : "";
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
my $xlsLink = $filename ? "&nbsp; &nbsp; ".$h->a ({ href=>$filename }, "[Download Now]") : "";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
# Print the header
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
my @tmpfilters;
foreach my $f (@displayFields) { # and now the filter boxes
push @tmpfilters, $h->div ({ class=>'rTableCell filters' }, filter ($f) )
}
 
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ @tmpfilters ], $h->div ({ class=>"rTableCell" }));
 
foreach my $t (@ProductList) { # Unt now we print the things!
my @tmprow;
foreach my $f (@displayFields)
{
# Look to see if there's a function named modify_<fieldname>() defined for this field
no strict;
if (exists &{"modify_".$f}) {
$t->{$f} = &{"modify_".$f} ($t);
}
push @tmprow, $h->div ({ class=>'rTableCell' }, $t->{$f});
}
print $h->div ({ class=>'rTableRow shaded' }, [ @tmprow ]);
}
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); return false;" }, "[Export Displayed Data as an Excel Document.]")."&nbsp;&nbsp;".$xlsLink,
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
/tags/2022.final/site/schedule/make_lead_shift_change.pl
0,0 → 1,64
#!/usr/bin/perl -w
 
use strict;
use lib "/home/rollerco/perl5/lib/perl5";
use RollerCon;
use CGI;
use CGI::Cookie;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
#foreach (sort keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
my $query = new CGI;
my $change = $query->param('change');
my $shift = $query->param('shift');
 
 
print<<page1;
<html><head><title>RollerCon Officials Schedule Manager - Lead Shift Change</title>
<link rel="stylesheet" type="text/css" href="/rollercon.css">
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000" onload="reloadParent()">
<TABLE>
<TR>
<TD valign=top>Making a lead shift change...</td>
<TD valign=top></TD>
</TR>
</TABLE>
 
So, <b>$user->{derby_name}</b>, you\'d like to <b>$change</b> a lead shift where for <b>Shift $shift</b>...
page1
 
my $change_err = changeLeadShift($change, $shift, $user->{RCid});
 
print<<tail;
<SCRIPT language="JavaScript">
<!--
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function reloadParent() {
window.opener.document.Req.submit();
sleep(5000);
window.close();
}
//-->
</SCRIPT>
 
</body></html>
 
tail
/tags/2022.final/site/schedule/make_shift_change.pl
0,0 → 1,97
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use tableViewer;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate(1) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
print header (-cookie=>$RCAUTH_cookie);
 
#foreach (sort keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
my $change = param ('change');
my $RCid = param ('RCid') // $user->{RCid};
my $id = param ('id');
my $role = param ('role') // "";
my $noshow = param ('noshow');
my $department = ($id =~ /^\d+$/) ? getShiftDepartment ($role ? $id."-".$role : $id) : "CLA";
 
print start_html (-title => "vORC Make Shift Change", -style => {'src' => "/style.css"}), $h->open ("body");
 
 
if ($change eq "lookup") {
if (convertDepartments($user->{department})->{$department} < 2 and $LVL < 5 and convertDepartments($user->{department})->{VCI} < 2) {
print $h->div ({ class=>"error" }, "You're not allowed to change other people's schedules.");
print $h->close ("body"), $h->close ("html");
die;
}
my $options = fetchDerbyNameWithRCid ($department);
print $h->form ({ action=>url }, [
$h->input ({ type=>"hidden", name=>"change", value=>"add" }),
$h->input ({ type=>"hidden", name=>"id", value=>$id }),
$h->input ({ type=>"hidden", name=>"role", value=>$role }),
$department eq "CLA" ? $h->p ("Add User to Class ($id):") : $h->p ("Add User to Shift ($id):"),
$h->select ({ name=>"RCid", id=>"pickname" }, [ $h->option, $options ]),
$h->input ({ type=>"submit", value=>"Save", onClick=>"if (document.getElementById('pickname').selectedIndex === 0) { return false; }" }),
$h->button ({ onClick=>"window.close();" }, "Cancel")
]);
 
} else {
print $h->p ("Making a shift change...");
 
if ($noshow eq "true") {
logit ($RCid, "NO SHOW: $id");
logit ($user->{RCid}, "Logged a No Show for ($RCid): $id");
print $h->p ("Logged a No Show and removing the official from the shift...");
} elsif ($RCid eq $user->{RCid}) {
print $h->p ("So, <b>$user->{derby_name}</b>, you'd like to <b>$change</b> a shift: <b>$id</b>...");
} else {
my $target = getUserDerbyName ($RCid);
print $h->p ("So, <b>$user->{derby_name}</b>, you'd like to <b>$change</b> a shift for <b>$target</b>: <b>$id</b>...");
}
my $change_err = changeShift($change, $id, $role, $RCid);
my $closer;
if ($change_err) {
print $change_err;
if ($change_err =~ /conflict/ and (convertDepartments($user->{department})->{VCI} > 2 or $LVL > 4)) {
print $h->form ({ action=>url }, [
$h->input ({ type=>"hidden", name=>"change", value=>"override" }),
$h->input ({ type=>"hidden", name=>"id", value=>$id }),
$h->input ({ type=>"hidden", name=>"role", value=>$role }),
$h->input ({ type=>"hidden", name=>"RCid", value=>$RCid }),
$h->input ({ type=>"submit", value=>"OVERRIDE", onClick=>"if (confirm('Are you sure you want to override the conflict?')==true) { return true } else { return false }" }),
]);
}
print $h->br, $h->button ({ onClick=>"window.close();" }, "Close");
} else {
print "<br>This window will close automatically in 3 seconds.";
$closer = 'setTimeout(() => { window.close(); }, 3000);';
}
print<<tail;
<SCRIPT language="JavaScript">
<!--
function reloadParent() {
window.opener.location.reload();
$closer
}
reloadParent();
//-->
</SCRIPT>
tail
print $h->close ("body"), $h->close ("html");
}
/tags/2022.final/site/schedule/manage_personal_time.pl
0,0 → 1,332
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use WebDB;
use HTML::Tiny;
use RollerCon;
use CGI qw/param header start_html url/;
my $h = HTML::Tiny->new( mode => 'html' );
 
my %F;
 
my $cookie_string = authenticate (1) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
my $DepartmentNames = getDepartments ();
my $username = $user->{derby_name};
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR = "2022";
 
 
my $pageTitle = "Block Personal Time";
my $homeURL = "/schedule/";
my $DBTable = "shift";
my %FIELDS = (
id => [qw(ID 5 auto static )],
# dept => [qw(Department 10 select required )],
role => [qw(Brief 15 text required )],
# type => [qw(Type 20 select required )],
date => [qw(Date 25 date required )],
location => [qw(Location 30 text )],
start_time => [qw(Start 35 time required )],
end_time => [qw(End 40 time required )],
note => [qw(Notes 45 textarea )],
assignee_id => [qw(AssigneeID 50 readonly )],
);
 
 
my %fieldDisplayName = map { $_ => $FIELDS{$_}->[0] } keys %FIELDS;
my %fieldType = map { $_ => $FIELDS{$_}->[2] } keys %FIELDS;
my @requiredFields = sort fieldOrder grep { defined $FIELDS{$_}->[3] } keys %FIELDS;
my @DBFields = sort fieldOrder grep { $fieldType{$_} =~ /^(text|select|date|time|auto)/ } keys %FIELDS;
my $primary = $DBFields[0];
 
sub fieldOrder {
$FIELDS{$a}->[1] <=> $FIELDS{$b}->[1];
}
 
sub saveForm {
my $FTS = shift;
my $dbh = WebDB::connect ();
if (findConflict ($RCid, [$FTS->{date}, $FTS->{start_time}, $FTS->{end_time}], "personal")) {
my $samesame;
if ($FTS->{$DBFields[0]} ne "NEW") {
($samesame) = $dbh->selectrow_array ("select count(*) from shift where id = ? and date = ? and start_time = ? and end_time = ?", undef, $FTS->{id}, $FTS->{date}, $FTS->{start_time}, $FTS->{end_time});
}
if (!$samesame) {
error ("You already have a shift that conflicts with that time.");
return;
}
}
if ($FTS->{$DBFields[0]} eq "NEW") {
$dbh->do (
"INSERT INTO $DBTable
(dept,role,type,date,location,start_time,end_time,note,assignee_id)
VALUES(?,?,?,?,?,?,?,?,?)",
undef,
"PER", $FTS->{role}, "personal", $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{note}, $RCid);
($FTS->{id}) = $dbh->selectrow_array ("select max(id) from $DBTable where dept = ? and role = ? and type = ? and date = ? and location = ? and start_time = ? and end_time = ? and note = ? and assignee_id = ?", undef, "PER", $FTS->{role}, "personal", $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{note}, $RCid);
logit ($RCid, "$username created personal time ($FTS->{id}, $FTS->{date}, $FTS->{start_time}, $FTS->{end_time})");
} else {
$dbh->do (
"REPLACE INTO $DBTable
(id,dept,role,type,date,location,start_time,end_time,note,assignee_id)
VALUES(?,?,?,?,?,?,?,?,?,?)",
undef,
$FTS->{id}, "PER", $FTS->{role}, "personal", $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{note}, $RCid);
logit ($RCid, "$username updated personal time ($FTS->{id}, $FTS->{date}, $FTS->{start_time}, $FTS->{end_time})");
}
$dbh->disconnect (); # stored into database successfully.
return $FTS->{id};
}
 
sub delete_item {
my $X = shift;
my $dbh = WebDB::connect ();
$dbh->do ("delete from $DBTable where $primary = ? and assignee_id = ?", undef, $X->{$primary}, $RCid);
$dbh->disconnect ();
logit ($RCid, "$username deleted personal time ($X->{$primary})");
print "Shift Deleted: $X->{$primary}", $h->br;
print &formField ("Cancel", "Back", "POSTSAVE");
}
 
 
#sub select_dept {
# my $selection = shift;
# my @optionList;
#
# if ($LVL > 4) {
# @optionList = grep { !/^PER$/ } sort keys %{ $DepartmentNames };
# } else {
# @optionList = grep { $user->{department}->{$_} > 2 } keys %{ $user->{department} };
# }
#
# return $h->select ({ name=>"dept" },
# [ map { $selection eq $_ ?
# $h->option ({ value=>$_, selected=>[] }, $DepartmentNames->{$_}) :
# $h->option ({ value=>$_ }, $DepartmentNames->{$_})
# } "", @optionList ]);
#};
 
#sub select_type {
# my $value = shift // "";
#
# return $h->select ({ name=>"type" },
# [ map { $value eq $_ ?
# $h->option ({ value=>$_, selected=>[] }, $_) :
# $h->option ({ value=>$_ }, $_)
# } "", qw(open lead manager selected)]);
#};
 
 
 
 
 
print header (),
start_html (-title => $pageTitle, -style => {'src' => "/style.css"} );
 
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
]),
]),
]);
 
print $h->div (["Personal time isn't visible to other RollerCon Volunteers or most of leadership*,", $h->br,
"but it will block your schedule from signing up for conflicting shifts."]);
print $h->h5 (["* It is visible in the database..."]);
 
my $choice = param ("choice") // "";
if ($choice eq "Save") {
process_form ();
} elsif (defined (param ($primary))) {
my $thing = param ($primary);
if ($choice eq "Delete") {
delete_item ({ $primary => $thing });
} else {
display_form ({ $primary => $thing }, $choice);
}
} else {
display_form (); # blank form
}
 
print $h->close ("html");
 
sub display_form {
my $R = shift;
my $view = shift // "";
my $actionbutton;
if ($view eq "POSTSAVE" and $R->{$primary} eq "NEW") {
print &formField ("Cancel", "Back", "POSTSAVE");
return;
}
if ($R) {
# we're dealing with an existing thing. Get the current values out of the DB...
my $dbh = WebDB::connect ();
@F{@DBFields} = $dbh->selectrow_array (
"SELECT ". join (", ", @DBFields) ." FROM $DBTable WHERE $primary = ? and dept = 'PER' and assignee_id = ?",
undef, $R->{$primary}, $RCid);
$dbh->disconnect ();
# did we find a record?
error ("You don't seem to have Personal Time with that database ID ($R->{$primary}).") unless defined $F{$DBFields[0]};
if ($view eq "Update") {
# We'd like to update that thing, give the user a form...
print $h->p ("Updating Personal Time: $R->{$primary}...");
foreach (@DBFields) {
$F{$_} = formField ($_, $F{$_});
}
$F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
} elsif ($view eq "Copy") {
# We'd like to copy that thing, give the user a form...
print $h->p ("Copying Personal Time: $R->{$primary}...");
foreach (@DBFields) {
$F{$_} = formField ($_, $F{$_});
}
$F{$DBFields[0]} = "COPY".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
} else {
# We're just looking at it...
print $h->p ("Viewing Personal Time: $R->{$primary}...");
$F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
$actionbutton = formField ("choice", "Update");
if ($view eq "POSTSAVE") {
$actionbutton .= formField ("Cancel", "Back", "POSTSAVE");
} else {
$actionbutton .= formField ("Cancel", "Back");
}
}
} else {
print $h->p ("Adding new Personal Time...");
 
foreach (@DBFields) {
$F{$_} = formField ($_);
}
$F{$DBFields[0]} = "NEW".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
}
print $h->open ("form", { action => url (), method=>"POST" });
print $h->div ({ class=>"sp0" },
$h->div ({ class=>"rTable" }, [ map ({
$h->div ({ class=>"rTableRow" }, [
$h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{$_}: "),
$h->div ({ class=>"rTableCell" }, $F{$_})
])
} @DBFields),
])
);
 
print $actionbutton;
print $h->close ("form");
 
}
 
sub process_form {
my %FORM;
foreach (keys %FIELDS) {
if ($fieldType{$_} =~ /^text/) {
$FORM{$_} = WebDB::trim param ($_) // "";
} else {
$FORM{$_} = param ($_) // "";
}
}
# check for required fields
my @errors = ();
foreach (@requiredFields) {
push @errors, "$fieldDisplayName{$_} is missing." if $FORM{$_} eq "";
}
if (@errors) {
print $h->div ({ class=>"error" }, [
$h->p ("The following errors occurred:"),
$h->ul ($h->li (@errors)),
$h->p ("Please click your Browser's Back button to\n"
. "return to the previous page and correct the problem.")
]);
return;
} # Form was okay.
 
$FORM{id} = saveForm (\%FORM);
print $h->p ({ class=>"success" }, "Shift successfully saved.");
 
display_form ({ $primary=>$FORM{id} }, "POSTSAVE");
}
 
sub error {
my $msg = shift;
print $h->p ({ class=>"error" }, "Error: $msg");
print $h->close("html");
exit (0);
}
 
sub formField {
my $name = shift;
my $value = shift // '';
my $context = shift // '';
my $type = $fieldType{$name} // "button";
if ($type eq "button") {
if ($name eq "Cancel") {
if ($context eq "POSTSAVE") {
return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"window.location.href = '$homeURL'; return false;" });
} else {
return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"history.back(); return false;" })
}
} else {
return $h->input ({ type=>"submit", value => $value, name=>$name })
}
 
} elsif ($type eq "textarea") {
return $h->tag ("textarea", {
name => $name,
override => 1,
cols => 30,
rows => 4
}, $value);
} elsif ($type eq "select") {
no strict;
return &{"select_".$name} ($value);
} elsif ($type eq "auto") {
return $value;
} else {
return $h->input ({
name => $name,
type => $type,
value => $value,
required => [],
override => 1,
size => 30
});
}
}
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/manage_shift.pl
0,0 → 1,382
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use WebDB;
use HTML::Tiny;
use RollerCon;
use CGI qw/param header start_html url/;
my $h = HTML::Tiny->new( mode => 'html' );
 
my %F;
 
my $cookie_string = authenticate (5) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
my $DepartmentNames = getDepartments ();
my $username = $user->{derby_name};
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR = "2022";
 
 
my $pageTitle = "Manage Shift";
my $homeURL = "/schedule/";
my $DBTable = "shift";
my %FIELDS = (
id => [qw(ShiftID 5 auto static )],
dept => [qw(Department 10 select required )],
role => [qw(Role 15 text required )],
type => [qw(Type 20 select required )],
date => [qw(Date 25 date required )],
location => [qw(Location 30 text required )],
start_time => [qw(Start 35 time required )],
end_time => [qw(End 40 time required )],
doubletime => [qw(DoubleHours 42 switch )],
assignee_id => [qw(Assignee 50 auto )],
mod_time => [qw(ModTime 45 number )],
note => [qw(Notes 55 textarea )],
);
 
 
my %fieldDisplayName = map { $_ => $FIELDS{$_}->[0] } keys %FIELDS;
my %fieldType = map { $_ => $FIELDS{$_}->[2] } keys %FIELDS;
my @requiredFields = sort fieldOrder grep { defined $FIELDS{$_}->[3] } keys %FIELDS;
my @DBFields = sort fieldOrder grep { $fieldType{$_} =~ /^(text|select|number|switch|date|time|auto)/ } keys %FIELDS;
my @ROFields = sort fieldOrder grep { $fieldType{$_} =~ /^(readonly)/ } keys %FIELDS;
my $primary = $DBFields[0];
 
sub fieldOrder {
$FIELDS{$a}->[1] <=> $FIELDS{$b}->[1];
}
 
sub saveForm {
my $FTS = shift;
my $dbh = WebDB::connect ();
if ($FTS->{$DBFields[0]} eq "NEW") {
if ($FTS->{mod_time}) {
$dbh->do (
"INSERT INTO $DBTable
(dept,role,type,date,location,start_time,end_time,mod_time,doubletime,note)
VALUES(?,?,?,?,?,?,?,?,?,?)",
undef,
$FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{mod_time}, $FTS->{doubletime}, $FTS->{note}
);
} else {
$dbh->do (
"INSERT INTO $DBTable
(dept,role,type,date,location,start_time,end_time,doubletime,note)
VALUES(?,?,?,?,?,?,?,?,?)",
undef,
$FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{doubletime}, $FTS->{note}
);
}
($FTS->{id}) = $dbh-> selectrow_array ("select max(id) from $DBTable where dept = ? and role = ? and type = ? and date = ? and location = ? and start_time = ? and end_time = ? and note = ?", undef, $FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{note});
logit ($RCid, "$username created new shift ($FTS->{id}, $FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{mod_time}, $FTS->{doubletime})");
} else {
if ($FTS->{mod_time}) {
$dbh->do (
"UPDATE $DBTable
SET dept=?, role=?, type=?, date=?, location=?, start_time=?, end_time=?, mod_time=?, doubletime=?, note=?
WHERE id = ?",
undef,
$FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{mod_time}, $FTS->{doubletime}, $FTS->{note}, $FTS->{id}
);
} else {
$dbh->do (
"UPDATE $DBTable
SET dept=?, role=?, type=?, date=?, location=?, start_time=?, end_time=?, mod_time=null, doubletime=?, note=?
WHERE id = ?",
undef,
$FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time}, $FTS->{doubletime}, $FTS->{note}, $FTS->{id}
);
}
logit ($RCid, "$username updated shift ($FTS->{id}, $FTS->{dept}, $FTS->{role}, $FTS->{type}, $FTS->{date}, $FTS->{location}, $FTS->{start_time}, $FTS->{end_time})");
}
$dbh->disconnect (); # stored into database successfully.
return $FTS->{id};
}
 
sub delete_item {
my $X = shift;
my $dbh = WebDB::connect ();
$dbh->do ("delete from $DBTable where $primary = ?", undef, $X->{$primary});
$dbh->disconnect ();
logit ($RCid, "$username deleted shift ($X->{$primary})");
print "Shift Deleted: $X->{$primary}", $h->br;
print &formField ("Cancel", "Back", "POSTSAVE");
}
 
 
sub select_dept {
my $selection = shift;
my @optionList;
 
if ($LVL > 4) {
@optionList = grep { !/^PER$/ } sort keys %{ $DepartmentNames };
} else {
@optionList = grep { $user->{department}->{$_} > 2 } keys %{ $user->{department} };
}
return $h->select ({ name=>"dept" },
[ map { $selection eq $_ ?
$h->option ({ value=>$_, selected=>[] }, $DepartmentNames->{$_}) :
$h->option ({ value=>$_ }, $DepartmentNames->{$_})
} "", @optionList ]);
};
 
sub select_type {
my $value = shift // "";
return $h->select ({ name=>"type" },
[ map { $value eq $_ ?
$h->option ({ value=>$_, selected=>[] }, $_) :
$h->option ({ value=>$_ }, $_)
} "", qw(open lead manager selected)]);
};
 
print header (),
start_html (-title => $pageTitle, -style => {'src' => "/style.css"} );
 
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
]),
]),
]);
 
my $choice = param ("choice") // "";
if ($choice eq "Save") {
process_form ();
} elsif (defined (param ($primary))) {
my $thing = param ($primary);
if ($choice eq "Delete") {
delete_item ({ $primary => $thing });
} else {
display_form ({ $primary => $thing }, $choice);
}
} else {
display_form (); # blank form
}
 
print $h->close ("html");
 
sub display_form {
my $R = shift;
my $view = shift // "";
my $actionbutton;
if ($view eq "POSTSAVE" and $R->{$primary} eq "NEW") {
print &formField ("Cancel", "Back", "POSTSAVE");
return;
}
if ($R) {
# we're dealing with an existing thing. Get the current values out of the DB...
my $dbh = WebDB::connect ();
@F{@DBFields} = $dbh->selectrow_array (
"SELECT ". join (", ", @DBFields) ." FROM $DBTable WHERE $primary = ?",
undef, $R->{$primary});
$dbh->disconnect ();
# did we find a record?
error ("Cannot find a database entry for '$R->{$primary}'") unless defined $F{$DBFields[0]};
if ($user->{dept}->{$F{dept}} < 3 and $LVL < 5) {
error ("You're not a $DepartmentNames->{$F{dept}} Manager!");
}
if ($view eq "Update") {
# We'd like to update that thing, give the user a form...
print $h->p ("Updating Shift: $R->{$primary}...");
foreach (@DBFields) {
$F{$_} = formField ($_, $F{$_});
}
$F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
} elsif ($view eq "Copy") {
# We'd like to copy that thing, give the user a form...
print $h->p ("Copying Shift: $R->{$primary}...");
foreach (@DBFields) {
$F{$_} = formField ($_, $F{$_});
}
$F{$DBFields[0]} = "COPY".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
} else {
# We're just looking at it...
print $h->p ("Viewing Shift: $R->{$primary}...");
$F{$DBFields[0]} .= $h->input ({ type=>"hidden", name=>$DBFields[0], value=> $F{$DBFields[0]} });
$F{dept} = $DepartmentNames->{$F{dept}};
if ($F{assignee_id}) {
my $temp;
$temp = getUserDerbyName ($F{assignee_id});
$temp .= "&nbsp;".$h->a ({ onClick=>"if (confirm('Really? You want to drop this person from the shift?')==true) { window.open('make_shift_change.pl?change=del&RCid=$F{assignee_id}&id=$R->{$primary}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");
$F{assignee_id} = $temp;
} else {
$F{assignee_id} = $h->a ({ onClick=>"window.open('make_shift_change.pl?change=lookup&id=$R->{$primary}','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");
}
$F{doubletime} = $F{doubletime} ? "TRUE" : "FALSE";
$actionbutton = formField ("choice", "Update");
if ($view eq "POSTSAVE") {
$actionbutton .= formField ("Cancel", "Back", "POSTSAVE");
} else {
$actionbutton .= formField ("Cancel", "Back");
}
}
} else {
print $h->p ("Adding a new Shift...");
 
foreach (@DBFields) {
$F{$_} = formField ($_);
}
$F{$DBFields[0]} = "NEW".$h->input ({ type=>"hidden", name=>$DBFields[0], value=> "NEW" });
$actionbutton = formField ("choice", "Save");
$actionbutton .= formField ("Cancel");
}
print $h->open ("form", { action => url (), name=>"Req", method=>"POST" });
print $h->div ({ class=>"sp0" },
$h->div ({ class=>"rTable" }, [ map ({
$h->div ({ class=>"rTableRow" }, [
$h->div ({ class=>"rTableCell right top" }, "$fieldDisplayName{$_}: "),
$h->div ({ class=>"rTableCell" }, $F{$_})
])
# } @DBFields),
} sort fieldOrder keys %FIELDS),
])
);
 
print $actionbutton;
print $h->close ("form");
 
}
 
sub process_form {
my %FORM;
foreach (keys %FIELDS) {
if ($fieldType{$_} =~ /^text/) {
$FORM{$_} = WebDB::trim param ($_) // "";
} else {
$FORM{$_} = param ($_) // "";
}
}
# check for required fields
my @errors = ();
foreach (@requiredFields) {
push @errors, "$fieldDisplayName{$_} is missing." if $FORM{$_} eq "";
}
if (@errors) {
print $h->div ({ class=>"error" }, [
$h->p ("The following errors occurred:"),
$h->ul ($h->li (@errors)),
$h->p ("Please click your Browser's Back button to\n"
. "return to the previous page and correct the problem.")
]);
return;
} # Form was okay.
 
$FORM{id} = saveForm (\%FORM);
print $h->p ({ class=>"success" }, "Shift successfully saved.");
 
display_form ({ $primary=>$FORM{id} }, "POSTSAVE");
}
 
sub error {
my $msg = shift;
print $h->p ({ class=>"error" }, "Error: $msg");
print $h->close("html");
exit (0);
}
 
sub formField {
my $name = shift;
my $value = shift // '';
my $context = shift // '';
my $type = $fieldType{$name} // "button";
if ($type eq "button") {
if ($name eq "Cancel") {
if ($context eq "POSTSAVE") {
return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"window.location.href = \"manage_shifts.pl\"; return false;" });
} else {
return $h->input ({ type=>"button", value => $value ne '' ? $value : "Cancel" , onClick=>"history.back(); return false;" });
}
} else {
return $h->input ({ type=>"submit", value => $value, name=>$name })
}
 
} elsif ($type eq "textarea") {
return $h->tag ("textarea", {
name => $name,
override => 1,
cols => 30,
rows => 4
}, $value);
} elsif ($type eq "select") {
no strict;
return &{"select_".$name} ($value);
} elsif ($type eq "auto") {
return $name eq "assignee_id" ? getUserDerbyName ($value) : $value;
} elsif ($type eq "time") {
return $h->input ({
name => $name,
type => $type,
value => $value,
step => 900,
required => [],
override => 1,
size => 30
});
} elsif ($type eq "number") {
return $h->input ({ name=>$name, type=>"number", value=>$value, step=>.25 });
} elsif ($type eq "switch") {
if ($value) {
return $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>$name, value=>1, checked=>[] }), $h->span ({ class=>"slider round" })]);
} else {
return $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>$name, value=>1 }), $h->span ({ class=>"slider round" })]);
}
# $F->{department}->{$_} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$_", value=>0, checked=>[] }), $h->span ({ class=>"slider round" })]);
} else {
use tableViewer;
if (inArray ($name, \@requiredFields)) {
return $h->input ({
name => $name,
type => $type,
value => $value,
required => [],
override => 1,
size => 30
});
} else {
return $h->input ({
name => $name,
type => $type,
value => $value,
override => 1,
size => 30
});
}
}
}
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/manage_shifts.pl
0,0 → 1,423
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (RollerCon::ADMIN) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR = "2022";
 
 
my $pageTitle = "Shift Management";
my $prefscookie = "shiftmanager";
our $DBTABLE = 'v_shift';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
id => [qw(Change 5 none static )],
dept => [qw(Department 10 select )],
date => [qw(Date 15 date default )],
dayofweek => [qw(Day 17 select )],
time => [qw(Time 20 text default )],
start_time => [qw(Start 25 text )],
end_time => [qw(End 30 text )],
mod_time => [qw(ModTime 35 number )],
doubletime => [qw(DoubleTime 37 boolean )],
volhours => [qw(VolHours 40 number )],
role => [qw(Role 45 text default )],
type => [qw(Type 50 select default )],
location => [qw(Location 55 select default )],
note => [qw(Notes 60 text default )],
RCid => [qw(RCID 65 text )],
derby_name => [qw(Assignee 70 select default )],
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
my @whereClause;
if ($LVL < 5) {
my $string = "dept in (".join ",", map { '"'.$_.'"' } grep { $ORCUSER->{department}->{$_} >= 3 } keys %{$ORCUSER->{department}};
$string .= ")";
push @whereClause, $string;
}
push @whereClause, "dept != 'PER'";
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_doubletime {
my $thing = shift;
return $thing->{doubletime} ? "True" : "False";
}
 
sub modify_id {
my $hr = shift;
my $clicky = $hr->{RCid} ? "event.stopPropagation(); if (confirm('WARNING!\\nYou are modifying a shift that someone has signed up for.')==true) {return true;} else {return false;}" : "return true;";
my $extrawarning = $hr->{RCid} ? "\\nWARNING! It appears someone is signed up for it." : "";
return join "&nbsp;", #$hr->{id},
$h->a ({ href=>"manage_shift.pl?id=$hr->{id}&choice=Update", onClick=>$clicky }, "[Edit]"),
$h->a ({ href=>"manage_shift.pl?id=$hr->{id}&choice=Copy" }, "[Copy]"),
$h->a ({ href=>"manage_shift.pl?id=$hr->{id}&choice=Delete", onClick=>"event.stopPropagation(); if (confirm('Are you sure you want to DELETE this shift?$extrawarning')==true) {return true;} else {return false;}" }, "[Delete]")
;
};
 
my $DEPTS = getDepartments;
sub modify_dept {
my $hr = shift;
$hr->{dept} = $DEPTS->{$hr->{dept}};
}
 
sub filter_dept {
my $colName = shift;
my $filter = shift;
if (defined $filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
return "$colName = \"$filter\"";
} else {
my $thing = "filter-${colName}";
my $categories = join "", map { $FORM{$thing} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $DEPTS->{$_}) : $h->option ({ value=>$_ }, $DEPTS->{$_}) } grep { $LVL > 4 or exists $user->{department}->{$_} } grep { !/^PER$/ } sort keys %{$DEPTS};
my $Options = "<OPTION></OPTION>".$categories;
 
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
}
 
use DateTime;
use DateTime::Duration;
sub modify_derby_name {
my $t = shift;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
if (($t->{assignee_id} == $RCid and $t->{type} ne "selected" and $now < $cutoff) or ($t->{derby_name} and ($user->{department}->{$t->{dept}} >= 2 or $LVL >= 5))) {
# DROP
$t->{derby_name} = "$t->{derby_name} <A HREF='#' onClick=\"event.stopPropagation(); if (confirm('Really? You want to drop this person from the shift?')==true) { window.open('make_shift_change.pl?change=del&RCid=$t->{assignee_id}&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[DROP]</a>";
if ($user->{department}->{$t->{dept}} >= 2 or $LVL > 4) {
# NO SHOW
$t->{derby_name} .= " | <A HREF='#' onClick=\"event.stopPropagation(); if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$t->{assignee_id}&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[NO SHOW]</a>";
}
} elsif (!$t->{derby_name}) {
if (signUpEligible ($ORCUSER, $t, "vol") and $now < $cutoff) {
# SIGN UP
$t->{derby_name} = "<A HREF='#' onClick=\"event.stopPropagation(); window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[SIGN UP]</a>";
}
if ($user->{department}->{$t->{dept}} >= 2 or $LVL > 4) {
# ADD USER
$t->{derby_name} ? $t->{derby_name} .= " | " : {};
$t->{derby_name} .= "<A HREF='#' onClick=\"event.stopPropagation(); window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[ADD USER]</a>";
}
}
return $t->{derby_name};
}
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{sortby} = $displayFields[1];
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } grep { $_ ne "id" } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f}, "&nbsp;", $h->input ({ type=>"button", value=>"Add", onClick=>"window.location.href='manage_shift.pl'" }) ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
print $h->div ({ class=>'rTableRow shaded', onclick=>"location.href='manage_shift.pl?id=$t->{id}&choice=View'" }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/manage_user.pl
0,0 → 1,521
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use CGI qw/param cookie header start_html url/;
use Email::Valid;
use WebDB;
use HTML::Tiny;
our $h = HTML::Tiny->new( mode => 'html' );
 
my ($FORM, $cookie_string, $ERRMSG);
my @ERRORS;
my $dbh = WebDB->connect ();
my $depts = getDepartments (); # HashRef of the department TLAs -> Display Names...
my $AccessLevel = getAccessLevels;
my @tshirtOptions = ("", "MS", "MM", "ML", "MXL", "M2X", "M3X");
 
# The page's form might be submitted as a POST or a GET (or both?)
# The initial _view_ likely comes as a GET request (making it easier to embed in an HREF as a URL)
# Unpack any values sent in the GET and add them to the FORM hash
$FORM->{'SUB'} = param ('submit') // '';
$FORM->{'RCid'} = param ('RCid') // '';
$FORM->{referer} = param ("referer") // "";
if ($FORM->{'SUB'} eq '') {
if ($ENV{'REQUEST_URI'}) {
my ($g, $keep) = split /\?/, $ENV{'REQUEST_URI'};
if ($keep) {
foreach (split /&/, $keep) {
my ($k, $v) = split /=/;
$k =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$k eq "submit" ? $FORM->{'SUB'} = $v : $FORM->{$k} = $v;
}
}
}
}
 
# Keep track of the original referrer for the 'back' link/button
my $goback;
if ($FORM->{referer}) {
$goback = $FORM->{referer};
} else {
$goback = $ENV{HTTP_REFERER};
}
 
 
if ($FORM->{'SUB'} eq "Save") {
process_form ($FORM);
} elsif ($FORM->{'SUB'} eq "New User") {
display_form ("New", "New User"); # blank form
} elsif ($FORM->{'RCid'}) {
display_form ($FORM->{'RCid'}, $FORM->{'SUB'});
} else {
$cookie_string = authenticate (1);
my ($EM, $PWD, $AL) = split /&/, $cookie_string;
display_form (getUser ($EM)->{'RCid'}, "View");
}
 
 
sub process_form {
my $F = shift // "";
push @ERRORS, "Tried to save an empty form." and return unless $F;
 
$F->{email} = lc WebDB::trim param ('email') // '';
$F->{password} = WebDB::trim param ('password') // '';
$F->{derby_name} = WebDB::trim param ('derby_name') // '';
$F->{real_name} = WebDB::trim param ('real_name') // '';
$F->{pronouns} = WebDB::trim param ('pronouns') // '';
$F->{tshirt} = WebDB::trim param ('tshirt') // '';
$F->{phone} = WebDB::trim param ('phone') // '';
# $F->{level} = param ('level') // '';
# $F->{type} = param ('type') // '';
$F->{RCid} = param ('RCid') // '';
$F->{access} = param ('access') // 0;
# $F->{clinic_pass} = defined param ('clinic_pass') ? 1 : 0;
$F->{department} = join ":", map { "$_-".param ("DEPT-".$_) } map { s/^DEPT-//; $_ } grep { param ($_) ne "" } grep { /^DEPT-/ } param ;
if ($F->{RCid} eq "New") {
# Saving a new User...
# But first let's do some error checking...0
if (!$F->{password}) { push @ERRORS, "Blank Password!"; }
if (!$F->{real_name}) { push @ERRORS, "Blank Real Name!"; }
if (!$F->{derby_name}) { $F->{derby_name} = $F->{real_name}; } # If they leave derby_name blank, use their real_name
if (checkDupes ('derby_name', $F->{derby_name})) { push @ERRORS, "Derby Name already in use. Pick a different one."; $F->{derby_name} = ""; }
# if (!$F->{level}) { $F->{level} = "B"; } # People keep leaving level blank. Default 'em if they do.
# if (!$F->{type}) { $F->{type} = "official"; } # and now they left the other drop-down blank!!!
if (!$F->{email}) { push @ERRORS, "Blank Email (User-ID)!"; } else {
$F->{email} =~ s/\s+//g; # make sure people aren't accidentally including spaces
$F->{email} = lc $F->{email}; # sometimes people capitalize their email addresses and that's annoying...
if (! Email::Valid->address (-address => $F->{email}, -mxcheck => 1, -tldcheck => 1)) { push @ERRORS, "Mal-formatted (or fake) Email Address!"; $F->{email} = ""; }
}
if (checkDupes ('email', $F->{email})) { push @ERRORS, "Email Address already in use. Pick a different one."; $F->{email} = ""; }
if (!$F->{department}) { push @ERRORS, "You need to request at least one Department!"; }
if (scalar @ERRORS) {
$ERRMSG = join $h->br, @ERRORS;
display_form ("New", "New User", $ERRMSG);
return;
} else {
# We have a correctly formatted email address with a mail host record, go ahead and add the user
# my $sth = $dbh->prepare ("insert into official (email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
my $sth = $dbh->prepare ("insert into official (email, password, derby_name, real_name, pronouns, tshirt, phone, access, department, added) values (?, password(?), ?, ?, ?, ?, ?, ?, ?, CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles'))");
 
# $sth->execute ($F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, 0, $F->{department}, 0);
$sth->execute ($F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, 1, $F->{department});
 
$sth = $dbh->prepare ("select RCid from official where email = ?");
$sth->execute ($F->{email});
($F->{RCid}) = $sth->fetchrow_array;
logit ($F->{RCid}, "New User Registration");
sendEMail ("New User", $F);
$cookie_string = authenticate (1);
}
} else {
$cookie_string = authenticate (1);
my ($EM, $PWD, $AL) = split /&/, $cookie_string;
if (lc $EM eq lc $F->{email} and $AL < 5) { # They're editing their own record (and not a sysadmin).
# Don't let users change their own clinic_pass setting...
# $F->{clinic_pass} = getUser($EM)->{clinic_pass};
my $DBDepts = getUser($EM)->{department};
if ($F->{department} ne $DBDepts) {
# They're trying to change one of their own departments.
my $FORMDepts = convertDepartments $F->{department};
$DBDepts = convertDepartments $DBDepts;
map { $FORMDepts->{$_} = 0 } keys %{$FORMDepts}; # the only change to a dept should be a request to be added
map { do { delete $DBDepts->{$_} } if $DBDepts->{$_} == 0 and !defined $FORMDepts->{$_} } keys %{$DBDepts}; # or they can retract their request
map { $FORMDepts->{$_} = $DBDepts->{$_} } keys %{$DBDepts}; # otherwise, keep the same depts as are in the DB
$F->{department} = convertDepartments $FORMDepts;
}
 
if ($F->{password}) { # They've possibly included an updated password.
# my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
# $sth->execute ($F->{RCid}, $EM, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, access, department, added, last_login) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$sth->execute ($F->{RCid}, lc $EM, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{access}, $F->{department}, getUser($EM)->{added}, getUser($EM)->{last_login})
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
} else { # No password was included, just keep the existing one.
# my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
# $sth->execute($F->{RCid}, $EM, $PWD, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
my $sth = $dbh->prepare("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, access, department, added, last_login) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$sth->execute($F->{RCid}, lc $EM, $PWD, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{access}, $F->{department}, getUser($EM)->{added}, getUser($EM)->{last_login})
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
}
 
if ($ERRMSG) {
logit ($F->{RCid}, "DB ERROR: Updating Self Details: $ERRMSG");
} else {
logit ($F->{RCid}, "Updated User Details");
}
} elsif ($AL > 1) { # A lead or higher is updating someone else's record
use List::Util qw/sum/;
# if (sum (values %{ convertDepartments ($F->{department}) }) > 0 and $F->{access} == 0) {
if (sum (values %{ convertDepartments ($F->{department}) }) > 0 and $F->{access} == 1) {
# activating a user for the first time...
$F->{access} = 1;
sendEMail ("Activate", $F);
}
if ($FORM->{password}) {
# my $sth = $dbh->prepare ("replace into official (RCid, email, password, derby_name, real_name, phone, level, type, access, department, clinic_pass) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?)");
# $sth->execute ($F->{RCid}, $F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass})
my $sth = $dbh->prepare ("replace into official (RCid, email, password, derby_name, real_name, pronouns, tshirt, phone, access, department, added, last_login) values (?, ?, password(?), ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$sth->execute ($F->{RCid}, $F->{email}, $F->{password}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{access}, $F->{department}, getUser($F->{email})->{added}, getUser($F->{email})->{last_login})
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
} else {
# my $sth = $dbh->prepare ("update official set email = ?, derby_name = ?, real_name = ?, phone = ?, level = ?, type = ?, access = ?, department = ?, clinic_pass = ? where RCid = ?");
# $sth->execute ($F->{email}, $F->{derby_name}, $F->{real_name}, $F->{phone}, $F->{level}, $F->{type}, $F->{access}, $F->{department}, $F->{clinic_pass}, $F->{RCid})
my $sth = $dbh->prepare ("update official set email = ?, derby_name = ?, real_name = ?, pronouns = ?, tshirt = ?, phone = ?, access = ?, department = ? where RCid = ?");
$sth->execute ($F->{email}, $F->{derby_name}, $F->{real_name}, $F->{pronouns}, $F->{tshirt}, $F->{phone}, $F->{access}, $F->{department}, $F->{RCid})
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
}
if ($ERRMSG) {
logit ($F->{RCid}, "DB ERROR: Updating Someone Else: $ERRMSG");
} else {
logit ($F->{RCid}, "Updated User Details (by ".getUser($EM)->{derby_name}.")");
logit (getUser($EM)->{RCid}, "Updated User Details: ".$F->{derby_name}." (".$F->{RCid}.")");
}
} else {
$ERRMSG = "Attempting to update someone else's record, and you don't have permission to do that.";
logit ($F->{RCid}, "FAIL: ($EM) doesn't have access to update ($F->{email})'s record");
}
}
$F->{password} = "*******";
$F->{buttons} = $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{RCid} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
# my $checked = $F->{clinic_pass} ? "checked" : "";
# $F->{clinic_pass} = "<INPUT type='checkbox' name='clinic_pass' $checked disabled readonly>";
$F->{department} = convertDepartments ($F->{department});
 
display_form ($F->{RCid}, "View");
}
 
sub display_form {
my $RCID = shift // "";
my $view = shift; # // "New User";
my $errors = shift // "";
my $F;
if ($view eq 'Edit') {
$cookie_string = authenticate (1);
my ($EM, $PWD, $AL) = split /&/, $cookie_string;
$F = getUser ($RCID);
my $currentuser = getUser ($EM);
# $currentuser->{department} = convertDepartments ($currentuser->{department});
# if (lc $EM eq lc $F->{email} or $AL > 1) {
if (canView ($currentuser, $F)) {
# Editing your own record OR you're a lead/higher
if (lc $EM eq lc $F->{email} or $currentuser->{access} < $F->{access}) {
# If you're editing your own record, or someone who has higher access than you, make access level read-only
$F->{access} = $h->input ({ type=>"hidden", name=>"access", value=>$F->{access} }).$AccessLevel->{$F->{access}};
} else {
$F->{access} = $h->select ({ name=>"access" }, [map { $F->{access} == $_ ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (-1..$currentuser->{access})]);
}
# my $checked = $F->{clinic_pass} ? "checked" : "";
# if ($currentuser->{access} > 2) {
# $F->{clinic_pass} = "<INPUT type='checkbox' name='clinic_pass' value=$F->{clinic_pass} $checked>";
# } else {
# $F->{clinic_pass} = "<INPUT type='checkbox' name='clinic_pass' $checked disabled readonly>";
# }
if ($AL == 5) {
$F->{email} = $h->input ({ type=>"text", name=>"email", value=>$F->{email} });
} else {
$F->{email} = $F->{email}.$h->input ({ type=>"hidden", name=>"email", value=>$F->{email} });
}
if ($currentuser->{RCid} eq $F->{RCid} or $currentuser->{access} > 4) {
$F->{password} = $h->input ({ type=>"password", name=>"password" });
$F->{derby_name} = $h->input ({ type=>"text", name=>"derby_name", value=>$F->{derby_name} });
$F->{real_name} = $h->input ({ type=>"text", name=>"real_name", value=>$F->{real_name} });
$F->{pronouns} = $h->input ({ type=>"text", name=>"pronouns", value=>$F->{pronouns} });
$F->{tshirt} = $h->select ({ name=>"tshirt" }, [map { $F->{tshirt} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @tshirtOptions] );
$F->{phone} = $h->input ({ type=>"text", name=>"phone", value=>$F->{phone} });
} else {
$F->{password} = '*******';
}
# $F->{level} = "<SELECT NAME=level>".selectOptions ($F->{level}, [qw(AA A B C)])."</SELECT>";
# $F->{type} = "<SELECT NAME=type>".selectOptions ($F->{type}, [qw(official nso referee)])."</SELECT>";
$F->{RCid} = $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{RCid} })."$F->{RCid}&nbsp;";
$F->{buttons} = join " ", $h->input ({ type=>"submit", name=>"submit", value=>"Save" }), $h->input ({ type=>"reset", value=>"Reset" }), $h->input ({ type=>"submit", name=>"submit", value=>"Cancel" });
$F->{department} = convertDepartments ($F->{department});
$currentuser->{department} = convertDepartments ($currentuser->{department});
foreach my $k (keys %{$depts}) {
next if $k eq "CMP";
if ($currentuser->{access} > 4) {
# SysAdmin can change anyone's department level
$F->{department}->{$k} = $h->select ({ name=>"DEPT-".$k }, [ $h->option ({ value=>"" }, ""), map { $_ eq $F->{department}->{$k} ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (0..4) ]);
} elsif ($currentuser->{department}->{$k} > 1 and $currentuser->{department}->{$k} > $F->{department}->{$k}) {
# Department Leads and above can change someone's level within the dept (up to their own level -1)
$F->{department}->{$k} = $h->select ({ name=>"DEPT-".$k }, [ $h->option ({ value=>"" }, ""), map { $_ eq $F->{department}->{$k} ? $h->option ({ value=>$_, selected=>[] }, $AccessLevel->{$_}) : $h->option ({ value=>$_ }, $AccessLevel->{$_}) } (0..$currentuser->{department}->{$k}-1) ]);
} else {
# Or it's your own record, you can still submit a request to be added to the dept.
if (!defined $F->{department}->{$k}) {
$F->{department}->{$k} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$k", value=>0 }), $h->span ({ class=>"slider round" })]);
} elsif ($F->{department}->{$k} == 0) {
$F->{department}->{$k} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$k", value=>0, checked=>[] }), $h->span ({ class=>"slider round" })]);
}
}
}
} else {
$ERRMSG = "Attempting to update someone else's record, and you don't have permission to do that.";
}
 
} elsif ($view eq 'New User') {
$errors .= $h->br."NOTE: You will not be able to sign-up for things until your account has been reviewed and approved. Watch your email for notification.";
# Skip authentication
$F->{email} = $h->input ({ type=>"text", name=>"email", value=>$F->{email} });
$F->{password} = $h->input ({ type=>"password", name=>"password" });
$F->{derby_name} = $h->input ({ type=>"text", name=>"derby_name", value=>$F->{derby_name} });
$F->{real_name} = $h->input ({ type=>"text", name=>"real_name", value=>$F->{real_name} });
$F->{pronouns} = $h->input ({ type=>"text", name=>"pronouns", value=>$F->{pronouns} });
$F->{tshirt} = $h->select ({ name=>"tshirt" }, [map { $F->{tshirt} eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @tshirtOptions] );
$F->{phone} = $h->input ({ type=>"text", name=>"phone", value=>$F->{phone} });
# $F->{level} = "<SELECT NAME=level>".selectOptions ($F->{level}, ["", qw(AA A B C)])."</SELECT>";
# $F->{type} = "<SELECT NAME=type>".selectOptions ($F->{type}, ["", qw(official nso referee)])."</SELECT>";
$F->{RCid} = $h->input ({ type=>"hidden", name=>"RCid", value=>"New" })."TBD&nbsp;";
$F->{access} = $h->input ({ type=>"hidden", name=>"access", value=>0 })."0";
# $F->{clinic_pass} = "<INPUT type='checkbox' name='clinic_pass' disabled readonly>";
foreach (keys %{$depts}) {
next if $_ eq "CMP";
if (defined param ("DEPT-$_")) {
$F->{department}->{$_} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$_", value=>0, checked=>[] }), $h->span ({ class=>"slider round" })]);
} else {
$F->{department}->{$_} = $h->label ({ class=>"switch" }, [$h->input ({ type=>"checkbox", name=>"DEPT-$_", value=>0 }), $h->span ({ class=>"slider round" })]);
}
}
$F->{buttons} = $h->input ({ type=>"submit", name=>"submit", value=>"Save" })." ".$h->input ({ type=>"reset", value=>"Reset" })." ".$h->input ({ type=>"submit", name=>"submit", value=>"Cancel" });
$cookie_string = '';
} elsif ($view eq 'View' or $view eq 'Cancel' or !$view) {
$cookie_string = authenticate (1);
my ($EM, $PWD, $AL) = split /&/, $cookie_string;
 
if (!$view) {
$F->{'RCid'} = getUser ($EM)->{'RCid'};
}
 
# Check to make sure they're only looking up their own ID unless they're a lead or higher
my $currentuser = getUser ($EM);
my $targetuser = getUser ($RCID);
 
if (canView ($currentuser, $targetuser)) {
$F = $targetuser;
$F->{department} = convertDepartments ($F->{department});
$F->{access} = $AccessLevel->{$F->{access}};
$F->{'password'} = "*******";
$F->{buttons} = $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{'RCid'} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
# my $checked = $F->{clinic_pass} ? "checked" : "";
# $F->{clinic_pass} = "<INPUT type='checkbox' name='clinic_pass' value=$F->{clinic_pass} $checked disabled readonly>";
} else {
logit ($currentuser->{RCid}, "SECURITY: $currentuser->{derby_name} attempted to view another user's ($RCID) info");
$errors = "Unauthorized attempt to view another user. This has been logged.";
$F->{email} = "&nbsp;";
$F->{password} = "&nbsp;";
$F->{derby_name} = "&nbsp;";
$F->{real_name} = "&nbsp;";
$F->{pronouns} = "&nbsp;";
$F->{tshirt} = "&nbsp;";
$F->{phone} = "&nbsp;";
# $F->{level} = "&nbsp;";
# $F->{type} = "&nbsp;";
$F->{RCid} = "&nbsp;";
$F->{access} = "&nbsp;";
# $F->{clinic_pass} = "&nbsp;";
$F->{buttons} = "&nbsp;";
}
 
# if (lc $EM eq lc $F->{email} or $AL > 1) {
# $F->{buttons} = $h->input ({ type=>"hidden", name=>"RCid", value=>$F->{'RCid'} }).$h->input ({ type=>"submit", name=>"submit", value=>"Edit" });
# } else {
# $F->{buttons} = "";
# }
} #else {
# $cookie_string = authenticate(1);
# $FORM->{email} = "&nbsp;";
# $FORM->{password} = "&nbsp;";
# $FORM->{derby_name} = "&nbsp;";
# $FORM->{real_name} = "&nbsp;";
# $FORM->{phone} = "&nbsp;";
# $FORM->{level} = "&nbsp;";
# $FORM->{type} = "&nbsp;";
# $FORM->{RCid} = "&nbsp;";
# $FORM->{access} = "&nbsp;";
# $FORM->{clinic_pass} = "&nbsp;";
# $FORM->{buttons} = "&nbsp;";
#}
 
#---------------START THE HTML--------------------
 
my $RCAUTH_cookie = cookie (-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
print header (-cookie=>$RCAUTH_cookie);
 
#foreach (keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
 
if ($errors) {
$errors = $h->div ({ class=>"error" }, $errors);
} else {
$errors = "";
}
my @printDepartments = ( $h->div ({ class=>"index", style=>"display: unset;" }, $h->p ({ class=>"heading" }, "Department Access:")) );
foreach (sort grep { !/^PER$/ } keys %{$F->{department}}) {
push @printDepartments, $h->div ({ class=>"rTableRow" }, [
$h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, $depts->{$_}.":", $F->{department}->{$_} =~ /^\d$/ ? $AccessLevel->{$F->{department}->{$_}} : $F->{department}->{$_}),
]);
}
 
printRCHeader ("User Manager");
print $errors;
print $h->form ({ action=>url, method=>'POST', name=>'Req' },[
$h->input ({ type=>"hidden", name=>"referer", value=>$goback }),
$h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "User Details:"),
$h->div ({ class=>"rTable", style=>"min-width: 0%;" },[
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "User-ID / Email Address: ", $F->{email}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Password: ", $F->{password}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Derby Name: ", $F->{derby_name}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Real Name: ", $F->{real_name}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Pronouns: ", $F->{pronouns}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "TShirt Size: ", $F->{tshirt}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Phone: ", $F->{phone}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Database ID: ", $F->{RCid}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "User Added: ", $F->{added}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "Last Login: ", $F->{last_login}) ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr", style=>"font-size: unset;" }, "vORC Access Level: ", $F->{access}) ]),
@printDepartments,
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCell" }, "&nbsp;") ]),
$h->div ({ class=>"rTableRow" },[ $h->div ({ class=>"rTableCellr" }, $h->a ({ href=>$goback }, "[go back]"), $F->{buttons}) ])
])
])
]); # print $h->close('form');
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Schedule:"), getSchedule ($RCID, "all")]) unless $RCID !~ /^\d+$/;
print $h->div ({ class=>"index" }, [$h->p ({ class=>"heading" }, "Recent Activity:"), getLog ($RCID)]) unless $RCID !~ /^\d+$/;
print $h->close ('html');
}
 
#sub selectOptions {
# my $selectedOption = shift;
# my $options = shift;
# return join " ", map { $selectedOption eq $_ ?
# $h->option ({ value=>$_, selected=>[] }, $_) :
# $h->option ({ value=>$_ }, $_)
# } @$options;
#}
 
sub sendEMail {
my $context = shift;
my $data = shift;
use RCMailer;
 
my $email = $data->{email};
my $subject = 'RollerCon Volunteer Schedule Manager - New User';
my $body;
if ($context eq "New User") {
$subject .= " Request";
$body = "Greetings,
 
It appears as though you've registered a new account to Volunteer at RollerCon with the following information:
 
Derby Name: $data->{derby_name}
Real Name: $data->{real_name}
Pronouns: $data->{pronouns}
TShirt Size: $data->{tshirt}
Email Address: $data->{email}
Phone: $data->{phone}
 
Please be patient while our Admins are reviewing your account request. Each user is manually approved to help ensure robots, spiders, and shift hoggers don't get in.
 
YOU WILL NOT BE ABLE TO LOG IN UNTIL YOU RECEIVE ANOTHER EMAIL STATING YOUR ACCOUNT REQUEST HAS BEEN APPROVED!
 
Once approved, you'll be able to log in and view the schedule and sign up for shifts. Please be considerate of others and don't hogger all of the shifts. If you do, we will find you and randomly drop your shifts.
 
If you're new to using vORC, you may want to read this:
 
https://volunteers.rollercon.com/info.html
 
If you didn't make this request, well, you're still the only one who received this email, and you now have an account request. You should probably let us know that someone is messing with you.
 
-RollerCon Management
";
} elsif ($context eq "Activate") {
$subject .= " Activated!";
my $tempDepartments = convertDepartments ($data->{department});
my $printableDepartments = join "\n", map { $depts->{$_}.": ".$AccessLevel->{$tempDepartments->{$_}} } sort keys %{$tempDepartments};
$body = "Greetings again,
 
You have been approved to volunteer at RollerCon in the following departments:
 
$printableDepartments
 
You may log into vORC and begin signing up for shifts. Please be considerate of others and don't hogger all of the shifts. If you do, we will find you and randomly drop your shifts.
 
https://volunteers.rollercon.com/schedule/
 
Please note that you are limited to signing up to a number of shifts per day. (Meaning, once you sign up for X shifts, you'll have to wait until tomorrow to sign up for more.) Please understand, while you are a nice, concientious, and good-looking person yourself, who knows how to share, there are others out there that will hogger up all of the shifts. As time goes by and we get closer to the event, we may lift the limit. Who knows?
 
If you've already signed up for your daily limit of shifts, and another shift REALLY strikes your fancy, try dropping one of your shifts. That should allow you to pick up a different one.
 
We'll be adding shifts over time, again to throttle how fast some people (not you, mind you) gobble up the shifts. Check back, maybe even daily.
 
If you're new to using vORC, you may want to read this:
 
https://volunteers.rollercon.com/info.html
 
If you didn't make this request, well, you're still the only one who received this email, and you now have an active account. You should probably let us know that someone is messing with you.
 
-RollerCon Management
";
} else {
return;
}
# send the message
EmailUser ($email, $subject, $body);
 
}
 
sub checkDupes {
my $field = shift;
my $nametocheck = shift;
my $han = $dbh->prepare("select RCid from official where $field = ?");
$han->execute($nametocheck);
my ($rcid) = $han->fetchrow();
return $rcid;
}
 
sub canView {
my $A = shift // "";
my $B = shift // "";
# Is A a lead or higher of one of B's Depts? (or they're looking at themselves)
# parameters should be a Hashref to the users' details
return 1 if $A->{access} > 4 or $A->{RCid} == $B->{RCid}; # viewer and target are the same person or it's a SysAdmin.
 
my $ADept = convertDepartments $A->{department};
my $BDept = convertDepartments $B->{department};
foreach (keys %{$BDept}) {
if ($ADept->{$_} > 1) { # A is a Lead or higher of one of B's departments
return 1;
}
}
return 0;
}
 
sub getLog {
my $RCID = shift;
my @activity_log;
my $alog = $dbh->prepare("select timestamp, event from v_log where RCid = ? limit 10");
$alog->execute($RCID);
while (my @logs = $alog->fetchrow_array) {
push @activity_log, $h->li ({ class=>"shaded" }, join " ", @logs);
}
return $h->ul ([@activity_log]).$h->h5 ($h->a ({ href=>"log.pl?filter-RCid=".$RCID }, "[Entire log history]"));
}
/tags/2022.final/site/schedule/mod_shift_time.pl
0,0 → 1,96
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use tableViewer;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
my $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
$user->{department} = convertDepartments ($user->{department});
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
print header (-cookie=>$RCAUTH_cookie);
 
#foreach (sort keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
my $change = param ('modtime') // "pick";
my $RCid = param ('RCid');
my $shiftid = param ('shiftid');
my $department = getShiftDepartment ($shiftid);
 
print start_html (-title => "vORC Modify Shift Time", -style => {'src' => "/style.css"}), $h->open ("body");
 
if ($user->{department}->{$department} < 2 or $LVL < 5) {
print $h->div ({ class=>"error" }, "ERROR: You're not allowed to modify this shift's time.");
print $h->close ("body"), $h->close ("html");
die;
} elsif (!$shiftid or !$RCid) {
print $h->div ({ class=>"error" }, "ERROR: Missing required fields.");
print $h->close ("body"), $h->close ("html");
die;
} elsif ($RCid eq $user->{RCid} and ($user->{department}->{$department} < 3 or $LVL < 5)) {
print $h->div ({ class=>"error" }, "ERROR: Leads aren't allowed to modify their own shift's time.");
print $h->close ("body"), $h->close ("html");
die;
}
 
if ($change eq "pick") {
use WebDB;
my $dbh = WebDB->connect ();
my ($current, $shiftlength) = $dbh->selectrow_array ("select mod_time, volhours from v_shift where RCid = ? and id = ?", undef, $RCid, $shiftid);
$shiftlength -= $current;
my $options;
print $h->p ("Modifying time for Shift ($shiftid):");
print $h->p ({ class=>"hint" }, "Add or Remove volunteer time earned if someone stays late or leaves early.");
print $h->form ({ action=>url }, [
$h->input ({ type=>"hidden", name=>"shiftid", value=>$shiftid }),
$h->input ({ type=>"hidden", name=>"RCid", value=>$RCid }),
# $h->p ("Modify Time for Shift ($RCid):"),
$h->input ({ name=>"modtime", type=>"number", value=>$current, step=>.25, min=>-$shiftlength, id=>"pickname" }),
$h->input ({ type=>"submit", value=>"Save", onClick=>"if (document.getElementById('pickname').selectedIndex === 0) { return false; }" }),
$h->input ({ type=>"reset", value=>"Cancel", onClick=>"window.close();" })
]);
 
} else {
print $h->p ("Modifying Shift Time...");
 
my $target = getUserDerbyName ($RCid);
print $h->p ("So, <b>$user->{derby_name}</b>, you'd like to add/remove time from a shift for <b>$target</b>: <b>$RCid</b>...");
my $change_err = modShiftTime ($shiftid, $RCid, $change);
 
print<<tail;
<SCRIPT language="JavaScript">
<!--
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function reloadParent() {
window.opener.document.Req.submit();
sleep(5000);
//window.close();
}
reloadParent();
//-->
</SCRIPT>
 
</body></html>
 
tail
print $h->close ("body"), $h->close ("html");
}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/mvp_class_report.pl
0,0 → 1,88
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use WebDB;
use tableViewer;
use CGI;
use CGI::Cookie;
use DateTime;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $date = param ("date");
my $dt;
if ($date =~ /^\d{4}-\d{2}-\d{2}$/) {
my ($YYYY, $MM, $DD) = split /-/, $date;
$dt = DateTime->new(
year => $YYYY,
month => $MM,
day => $DD
);
} else {
$dt = DateTime->today;
$date = $dt->date;
}
my $day = $dt->day_name;
 
## Uncomment and update to test:
#$day = "Wednesday";
#$date = "2022-07-13";
 
my $dbh = WebDB::connect ();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
print<<output;
<html><head><title>RollerCon VORC - MVP Class Sign-Ups - $day ($date)</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
output
 
my $gcount = 1; my $tcount = '';
my $sth = $dbh->prepare("select distinct note, role, location, time from v_shift where dept = ? and date = ? order by location, time");
my $crewhan = $dbh->prepare("select v_shift.derby_name, real_name from v_shift, official where v_shift.RCid = official.RCid and date = ? and dept = ? and isnull(v_shift.derby_name) = 0 and location = ? and time = ? order by v_shift.derby_name");
 
 
$sth->execute("CLA", $date);
while (my $g = $sth->fetchrow_hashref()) {
if ($tcount ne $g->{location}) { #pagebreak whenever we change tracks
print "<div class='pagebreak'></div>\n" unless (!$tcount or $gcount++ % 2);
# print "<div class='pagebreak'><hr></div>\n";
$gcount = 1;
$tcount = $g->{location};
}
print<<game;
<table>
<tr><td colspan=5 class="mvp bold">Class: ($g->{location}) $g->{note}</td></tr>
<tr><td colspan=3 class="mvp">Date: $day ($date)</td><td colspan=2 class='mvp right'>Time: $g->{time}</td></tr>
<tr><td colspan=5 class="mvp">Coach: $g->{role}</td></tr>
<tr><td colspan=5 class="mvp">&nbsp;</td></tr>
game
 
my $counter = 1;
$crewhan->execute($date, "CLA", $g->{location}, $g->{time});
while (my ($derby_name, $real_name) = $crewhan->fetchrow_array()) {
print "<tr><td class='mvp right'>".$counter++."</td><td>&nbsp;</td><td class='mvp'>".$derby_name."</td><td>&nbsp;</td><td class='mvp'>".$real_name."</td></tr>";
}
for ($counter..20) {
print "<tr><td class='mvp right'>".$_."</td><td colspan=4>&nbsp;</td></tr>";
}
print "</table><br><br>";
 
$gcount++ % 2 == 0 ? print "<div class='pagebreak'></div>\n" : { };
}
 
 
 
print<<tail;
</BODY>
</HTML>
tail
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/mvpclasses.pl
0,0 → 1,462
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
use DateTime;
#use DateTime::Duration;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string;
our ($EML, $PWD, $LVL);
my $user;
my $username;
my $RCid;
my $RCAUTH_cookie;
#my $YEAR = "2022";
 
$cookie_string = authenticate(1) || die;
($EML, $PWD, $LVL) = split /&/, $cookie_string;
$user = getUser($EML);
$username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
$RCid = $user->{RCid};
$RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
if (convertDepartments($user->{department})->{CLA} < 1 and $LVL < 4) {
print header(-cookie=>$RCAUTH_cookie);
printRCHeader("Unauthorized Page");
print $h->div ({ class=>"error" }, "No Access");
print $h->div ("Your user account is not registered to sign up for MVP Classes, so you can't see this page. It's possible that your access is still being reviewed. Please be patient.");
print $h->a ({ href=>"/schedule/" }, "[Go Home]");
print $h->close ("html");
exit;
}
 
 
my $pageTitle = "MVP Classes";
my $prefscookie = "newmvpclasses";
our $DBTABLE = 'v_mvp_class';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
note => [qw(Class 5 text static )],
date => [qw(Date 10 date )],
dayofweek => [qw(Day 15 select default )],
start_time => [qw(StartTime 20 text )],
end_time => [qw(EndTime 25 text )],
time => [qw(Time 30 text default )],
location => [qw(Track 35 select default )],
role => [qw(Coach 40 select default )],
available => [qw(SignUp 45 text static )]
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# Set any custom "where" DB filters here...
my @whereClause;
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
#use WebDB;
#my $dbh = WebDB::connect;
my $dbh = getRCDBH;
 
sub modify_available {
my $t = shift;
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
return "CLOSED" unless $now < $cutoff;
($t->{signedup}) = $dbh->selectrow_array ("select id from v_shift where RCid = ? and date = ? and start_time = ? and location = ?", undef, $RCid, $t->{date}, $t->{start_time}, $t->{location} );
my $droplink = $h->a ({ onClick=>"if (confirm('Really? You want to drop this shift?')==true) { window.open('make_shift_change.pl?change=del&RCid=$RCid&id=$t->{signedup}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");
if (!$t->{available}) {
my $full = "FULL";
$full .= " | ".$droplink unless !$t->{signedup};
return $full;
}
my $classkey = join '|', $t->{date}, $t->{start_time}, $t->{location};
$t->{available} .= " Open";
$t->{available} .= " | ".$droplink unless !$t->{signedup};
if (signUpEligible ($ORCUSER, $t, "class")) {
# SIGN UP
$t->{available} .= " | ".$h->a ({ onClick=>"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$classkey','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "[SIGN UP]");
}
if ($user->{department}->{CLA} >= 2 or $LVL > 4 or $user->{department}->{VCI} >= 2) {
# ADD USER
$t->{available} ? $t->{available} .= " | " : {};
$t->{available} .= $h->a ({ onClick=>"window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$classkey','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");
}
 
return $t->{available};
}
 
sub filter_available {
my $colName = shift;
my $filter = shift;
if (defined $filter) {
if ($filter eq "Full") {
return "$colName = 0";
}
return "$colName > 0";
} else {
my $thing = "filter-${colName}";
my $Options = "<OPTION></OPTION>"."<OPTION>Available</OPTION>"."<OPTION>Full</OPTION>";
 
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
}
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // "All"; #$pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
# if (/^year$/) { #
# $YEAR = param($_);
# next;
# }
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") { # Compile list of fields to display
if ($_ ne "shiftinclude") {
push @displayFields, $_;
}
}
}
 
#my @yearoptions = ($YEAR);
#foreach (@{&getYears()}) {
# push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
#}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$FORM{shiftinclude} = $si;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
$FORM{sortby} = "note";
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
#push @whereClause, "year(date) = '$YEAR'";
#warn join " and ", @whereClause;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "MVP_Class_List");
exit;
}
 
my @shifts;
if ($FORM{shiftinclude} eq "true") {
my @SIWhere; # = ("year(date) = '$YEAR'");
push @SIWhere, "RCid = $ORCUSER->{RCid}", "dept='CLA'";
my ($d, $c) = getData (\@displayFields, \@SIWhere, 'v_shift', $FORM{sortby});
@shifts = @{ $d };
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
my $SIChecked;
if ($FORM{shiftinclude}) {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
} else {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
}
 
# Print the header
print header(-cookie=>[$RCAUTH_cookie,$queryCookie]);
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs, $h->br,
"Show my classes: ", $SIChecked, $h->br,
$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='manage_personal_time.pl'" }),
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
if ($FORM{shiftinclude}) { # Include all of the user's shifts at the top
foreach my $t (@shifts) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
print $h->hr ({ width=>"500%" });
}
 
# Print the things
foreach my $t (@ProductList) {
my @display = map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields;
if ($t->{signedup}) {
print $h->div ({ class=>'rTableRow highlighted' }, [ @display ]);
} else {
print $h->div ({ class=>'rTableRow shaded' }, [ @display ]);
}
}
 
 
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
my @excelcode;
push @excelcode, $h->br;
push @excelcode, $h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]");
 
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
@excelcode,
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com",
# $h->br,
# "Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/officiating_shifts.pl
0,0 → 1,451
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
use DateTime;
use DateTime::Duration;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
 
 
my $cookie_string = authenticate (1) || die;
# Add checking to make sure they're in this department
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
 
if ($user->{department}->{"OFF"} < 1 and $LVL < 4) {
print header(-cookie=>$RCAUTH_cookie);
printRCHeader("Unauthorized Page");
print $h->div ({ class=>"error" }, "You're not an Official");
print $h->div ("Your user account is not registered as an Official, so you can't see these shifts. It's possible that your access is still being reviewed. Please be patient.");
print $h->a ({ href=>"/schedule/" }, "[Go Home]");
print $h->close ("html");
exit;
}
 
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
#my $YEAR = 1900 + (localtime)[5]; #which year of data to display, default to current
my $YEAR = "2022";
 
#$LVL = 1;
 
my $pageTitle = "Officiating Shifts";
my $prefscookie = "oshiftscookie";
our $DBTABLE = 'v_shift_officiating';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
id => [qw(ID 5 number )],
date => [qw(Date 10 date default )],
dayofweek => [qw(Day 15 select )],
time => [qw(Time 20 text default )],
volhours => [qw(VolHours 23 number )],
track => [qw(Track 25 select default )],
teams => [qw(Teams 30 text default )],
level => [qw(Level 35 select default )],
restrictions => [qw(Rs 40 select )],
gtype => [qw(Type 45 select default )],
signup => [qw(SignUp 46 select )],
notes => [qw(Notes 50 text )],
role => [qw(Role 55 select )],
tla => [qw(TLA 60 select default )],
name => [qw(Position 65 text )],
type => [qw(Class 70 select default )],
RCid => [qw(RCid 75 number )],
derby_name => [qw(Assignee 80 select default )]
);
 
if ($user->{department}->{"OFF"} > 1) {
# Add:
# real_name RealName
# email Email
$COLUMNS{'real_name'} = [qw(RealName 85 text)];
$COLUMNS{'email'} = [qw(Email 90 text)];
}
 
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem (RETURN the modified field at the end of the function!)
 
sub modify_derby_name {
my $t = shift;
 
if ($user->{department}->{"OFF"} < 2 and $t->{derby_name} and $t->{RCid} != $RCid and $LVL < 5) {
$t->{derby_name} = "FILLED";
}
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
 
if (($t->{RCid} == $RCid and $t->{signup} ne "selected" and $now < $cutoff) or ($t->{derby_name} and ($user->{department}->{"OFF"} >= 2 or $LVL >= 5))) {
# DROP
$t->{derby_name} = "$t->{derby_name} <A HREF='#' onClick=\"window.open('make_shift_change.pl?change=del&RCid=$t->{RCid}&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
if ($user->{department}->{"OFF"} >= 2) {
# NO SHOW
$t->{derby_name} .= " | <A HREF='#' onClick=\"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$t->{RCid}&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[NO SHOW]</a>";
}
} elsif (!$t->{derby_name}) {
$t->{dept} = "OFF";
if (signUpEligible ($ORCUSER, $t) and $now < $cutoff) {
# SIGN UP
$t->{derby_name} = "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[SIGN UP]</a>";
}
if ($user->{department}->{"OFF"} >= 2 or $LVL > 4) {
# ADD USER
$t->{derby_name} ? $t->{derby_name} .= " | " : {};
$t->{derby_name} .= "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$t->{id}&role=$t->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[ADD USER]</a>";
}
}
return $t->{derby_name};
}
 
 
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") { # Compile list of fields to display
if ($_ ne "shiftinclude") {
push @displayFields, $_;
}
}
}
 
my @addToWhereClause = ("year(date) = '$YEAR'", "type != 'announcer'");
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al, $si) = split /&/, $prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$FORM{shiftinclude} = $si;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
my @whereClause = map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
push @whereClause, @addToWhereClause;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my @shifts;
if ($FORM{shiftinclude} eq "true") {
my @SIWhere = ("year(date) = '$YEAR'");
push @SIWhere, "RCid = $ORCUSER->{RCid}";
my ($d, $c) = getData (\@displayFields, \@SIWhere, $DBTABLE, $FORM{sortby});
@shifts = @{ $d };
}
 
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({ name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
my $SIChecked;
if ($FORM{shiftinclude}) {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
} else {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
}
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
my @yearoptions;
foreach (@{&getYears()}) {
push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
}
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs, $h->br,
"Show my shifts: ", $SIChecked, $h->br,
$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='manage_personal_time.pl'" }),
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
 
if ($FORM{shiftinclude}) { # Include all of the user's shifts at the top
foreach my $t (@shifts) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
print $h->hr ({ width=>"500%" });
}
 
 
# Print the things
foreach my $t (@ProductList) {
if ($t->{RCid} eq $ORCUSER->{RCid}) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
} else {
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
}
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com",
$h->br,
"Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/password_reset.pl
0,0 → 1,137
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use CGI;
use CGI::Cookie;
 
#my $cookie_string = authenticate(1) || die;
#my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $query = new CGI;
my ($FORM, $userref, $buttonValue, $RCid);
my ($USRMSG, $USRMSGERR, $RO, $RCid_input) = ("", "", "", "");
 
if ($ENV{'QUERY_STRING'}) {
$FORM->{email} = $query->param('email');
$FORM->{action} = $query->param('action');
if ($FORM->{action} eq "Cancel") {
$FORM->{email} = "";
$FORM->{action} = "";
$buttonValue = "Lookup";
} elsif ($FORM->{action} eq "Lookup") {
if ($userref = getUser($FORM->{email})) {
$USRMSG = "User info found. Click Reset to reset your password, or Cancel to go back";
$buttonValue = "Reset";
$RO = "readonly";
$RCid_input = "<input type=hidden name=RCid value=$userref->{RCid}>";
} else {
$USRMSGERR = "No user found with that email address.";
$buttonValue = "Lookup";
}
} elsif ($FORM->{action} eq "Reset") {
if ($userref = getUser($FORM->{email})) {
if ($userref->{RCid} eq $query->param('RCid')) {
&resetPass($FORM->{email});
logit($userref->{RCid}, "Automated Password Reset");
exit;
} else {
$USRMSGERR = "There appear to be shenanigans afoot. Please don't.";
$buttonValue = "Lookup";
}
} else {
$USRMSGERR = "There appears to be tomfoolery afoot. Please don't.";
$buttonValue = "Lookup";
}
}
} else {
$FORM->{email} = "";
$FORM->{action} = "";
$buttonValue = "Lookup";
}
 
 
print CGI::header();
 
#foreach (sort keys %ENV) {
# print "$_: $ENV{$_}\n<br>";
#}
 
printRCHeader("Password Reset");
print<<page1;
 
<p class="hint">This will reset a user's password to a random string and email that new password to them.<br>
They will still need access to their email to get logged back in.</p>
 
<FORM method=GET action=password_reset.pl> $RCid_input
<TR><TD colspan=2>&nbsp</TD></TR>
<TR><TD colspan=2 align=center>$USRMSG <FONT color=red><b>$USRMSGERR</b></font></TD></TR>
<TR>
<TD valign=top align=right><b>Email Address: </b></td>
<TD valign=top><input type=text name=email value=$FORM->{email} $RO></TD>
</TR>
<TR><TD colspan=2>&nbsp</TD></TR>
<TR><TD colspan=2 align=center><input type=submit name=action value=$buttonValue><input type=button name=action value=Cancel onClick="location.href='/schedule/'"></TD></TR>
</FORM>
</TABLE>
 
page1
 
sub updateDBPass {
my ($EM, $STR) = @_;
use DBI;
use WebDB;
my $dbh = WebDB->connect;
my $sth = $dbh->prepare("update official set password = password(?) where email=?");
$sth->execute($STR, $EM);
}
 
sub resetPass {
my $email = shift;
 
my @chars = ("A".."Z", "a".."z", "1".."0", "(", ")", "-", "_", "*", "^", "!", "[", "]");
my $string;
$string .= $chars[rand @chars] for 1..8;
&updateDBPass($email, $string);
 
use RCMailer;
my $subject = 'RollerCon Officials Schedule Manager - Password Reset';
my $body = "Greetings,
 
It appears as though you've requested us to reset your password. We've done so, and your new password is '$string' (without the quotes).
 
We'd recommend you log in and change it to your liking at the following link:
 
https://volunteers.rollercon.com/schedule/manage_user.pl
 
If you didn't make this request, well, you're still the only one who received this email, and this is now your password. You should probably let us know that someone is messing with you.
 
-RollerCon Officiating Management
";
 
# send the message
EmailUser($email, $subject, $body);
 
 
print CGI::header();
print<<resetPage;
 
<HTML><HEAD><TITLE>RollerCon Officials Schedule Manager - Password Reset</TITLE></HEAD>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
<TABLE>
<TR>
<TD align=right><img SRC="/logo.jpg"></TD>
<TD align=center valign=middle><b><font size=+3>RollerCon Official<br>Schedule Manager<br>Password Reset</font></b></TD>
</TR>
<TR><TD colspan=2>&nbsp</TD></TR>
<TR><TD colspan=2 align=center>Your password has been reset and emailed to the address on record.<br>Please check your email (including Spam folders).&nbsp</TD></TR>
<TR><TD colspan=2>&nbsp</TD></TR>
<TR><TD colspan=2 align=center><a href=/schedule/>[home]</a>&nbsp</TD></TR>
</TABLE>
 
resetPage
}
/tags/2022.final/site/schedule/print_dept_by_day.pl
0,0 → 1,232
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use WebDB;
use tableViewer;
use CGI;
use CGI::Cookie;
use DateTime;
use HTML::Tiny;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
$user->{department} = convertDepartments ($user->{department});
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $DEPTS = getDepartments ();
 
my $date = param ("date");
my $dt;
if ($date =~ /^\d{4}-\d{2}-\d{2}$/) {
my ($YYYY, $MM, $DD) = split /-/, $date;
$dt = DateTime->new(
year => $YYYY,
month => $MM,
day => $DD
);
} else {
$dt = DateTime->today;
$date = $dt->date;
# noForm ($date);
}
my $day = $dt->day_name;
 
my $dept = param ("dept") // noForm ($date);
 
 
my %class = qw(
U Unrestricted
M Mens
W Womens
SS Single-Gender
);
my %dbfields = qw(
type 5
role 10
location 15
time 20
derby_name 25
);
 
 
 
my $dbh = WebDB::connect ();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
 
print<<output;
<html><head><title>RollerCon VORC - $DEPTS->{$dept} Schedule - $day ($date)</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
output
 
print $h->div ({class=>"bold"}, "$DEPTS->{$dept} - $day ($date)"), $h->br;
 
my $query = $dbh->prepare ("select type, role, location, time, derby_name from v_shift where dept = ? and date = ? order by start_time, field(type, 'manager', 'lead', 'selected', 'open'), location, end_time");
$query->execute ($dept, $date);
 
my @constants = ("&nbsp;", "&nbsp;", "&nbsp;");
print $h->open ('div', { class=>'rTable' });
 
print $h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell bold" }, map { ucfirst $_ } sort { $dbfields{$a} <=> $dbfields{$b} } keys %dbfields), $h->div ({ class=>"rTableCell bold" }, "Time In", "Time Out", "Add to VORC")]);
while (my $shift = $query->fetchrow_hashref) {
print $h->div ({ class=>"rTableRow" }, [$h->div ({ class=>"rTableCell", style=>"border: 1px dotted black;" }, map { $shift->{$_} } sort { $dbfields{$a} <=> $dbfields{$b} } keys %{$shift} ), $h->div ({ class=>"rTableCell", style=>"border: 1px dotted black;" }, @constants )]);
}
 
print $h->close ('div', { class=>'rTable' });
 
print<<tail;
</BODY>
</HTML>
tail
 
exit;
 
 
my $gcount = 1; my $tcount = '';
my $sth = $dbh->prepare("select distinct teams, track, level, time, gtype, restrictions from v_shift_officiating where date = ? order by track, time");
my $crewhan = $dbh->prepare("select role, derby_name from v_shift_officiating where date = ? and track = ? and time = ?");
my $leadhan = $dbh->prepare("select location, time, derby_name from v_shift where dept = 'OFF' and date = ? order by location, time");
my $openshifthan = $dbh->prepare("select time, level, restrictions, gtype, teams, tla, name from v_shift_officiating where tla <> 'ALT' and isNull(derby_name) = 1 and date = ? and track = ? order by time");
 
my @leads = ("<table>\n", "<tr><td colspan=5><b>Lead Shifts</b></td></tr>\n");
$leadhan->execute($date);
my $tc = 'C1';
while (my $lshift = $leadhan->fetchrow_hashref()) {
if ($tc ne $lshift->{location}) {
push @leads, "<tr><td colspan=5>&nbsp;</td></tr>\n";
$tc = $lshift->{location};
}
push @leads, "<tr><td>$lshift->{location}</td><td>&nbsp;</td><td>$lshift->{time}</td><td>&nbsp;</td><td>$lshift->{derby_name}</td></tr>\n";
}
push @leads, "</table>\n";
 
$sth->execute($date);
while (my $g = $sth->fetchrow_hashref()) {
if ($tcount ne $g->{track}) { #pagebreak whenever we change tracks
print "<div class='pagebreak'><hr></div>\n" unless !$tcount;
print @leads;
my @openshifts = ("<table>\n", "<tr><td colspan=5><b>Open Shifts on $g->{track}</b></td></tr>\n");
$openshifthan->execute($date, $g->{track});
while (my @oshift = $openshifthan->fetchrow_array()) {
my $sh = join "</td><td>&nbsp;</td><td>", @oshift;
push @openshifts, "<tr><td>$sh</td></tr>\n";
}
push @openshifts, "</table>\n";
print "<br><br><br><br>";
print @openshifts;
print "<div class='pagebreak'><hr></div>\n";
$gcount = 1;
$tcount = $g->{track};
}
$g->{gtype} = join '', map { ucfirst lc } split /(\s+)/, $g->{gtype}; # Capitalize the game time to look nicer
 
my %crew;
$crewhan->execute($date, $g->{track}, $g->{time});
while (my ($k, $v) = $crewhan->fetchrow_array()) {
$crew{$k} = $v;
}
my $P1 = "PLT-1";
my $P2 = "PLT-2";
my $PH = "PLT";
my $OPR1 = "OPR-1";
if ($g->{gtype} eq "Full Length" or $g->{gtype} eq "Selected Staffing") {
$P1 = 'PLT/H';
$P2 = 'PLT';
$PH = $P1;
} elsif ($g->{gtype} eq "Challenge-rs1") {
$crew{'OPR-1'} = "<i>-not staffed-</i>";
$crew{'OPR-2'} = "<i>-not staffed-</i>";
$crew{'OPR-3'} = "<i>-not staffed-</i>";
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
} elsif ($g->{gtype} eq "Challenge-rs2") {
$OPR1 = "OPR";
 
$crew{'IPR'} = "<i>-not staffed-</i>";
$crew{'OPR-2'} = "<i>-not staffed-</i>";
$crew{'OPR-3'} = "<i>-not staffed-</i>";
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
} elsif ($g->{gtype} eq "Scrimmage") {
$crew{'PLT-1'} = "<i>-not staffed-</i>";
$crew{'PLT-2'} = "<i>-not staffed-</i>";
$crew{'SK-1'} = "<i>-not staffed-</i>";
$crew{'SK-2'} = "<i>-not staffed-</i>";
$crew{'PBM'} = "<i>-not staffed-</i>";
$crew{'PBT-1'} = "<i>-not staffed-</i>";
$crew{'PBT-2'} = "<i>-not staffed-</i>";
$crew{'SO'} = "<i>-not staffed-</i>";
}
my $A = '';
if (defined $crew{'ALT'}) {
$A = "ALT:";
} else {
$crew{'ALT'} = '';
}
print<<game;
<table>
<tr><td>Date:</td><td>$day ($date)</td><td>&nbsp;</td><td>Track:</td><td>$g->{track}</td></tr>
<tr><td>Time:</td><td>$g->{time}</td><td>&nbsp;</td><td>Class:</td><td>$class{$g->{restrictions}} $g->{level} $g->{gtype}</td></tr>
<tr><td>Game:</td><td colspan=4>$g->{teams}</td></tr>
<tr><td colspan=5>&nbsp;</td></tr>
<tr><td>HR:</td><td>$crew{'HR'}</td><td>&nbsp;</td><td>$PH:</td><td>$crew{$P1}</td></tr>
<tr><td>IPR:</td><td>$crew{'IPR'}</td><td>&nbsp;</td><td>PLT:</td><td>$crew{$P2}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-1'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-1'}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-2'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-2'}</td></tr>
<tr><td>OPR:</td><td>$crew{$OPR1}</td><td>&nbsp;</td><td>PBM:</td><td>$crew{'PBM'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-2'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-1'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-3'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-2'}</td></tr>
<tr><td>$A</td><td>$crew{'ALT'}</td><td>&nbsp;</td><td>JT:</td><td>$crew{'JT'}</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>SO:</td><td>$crew{'SO'}</td></tr>
</table><br><br><br><br><br><br><br><br><br><br><br><br>
game
 
$gcount++ % 2 == 0 ? print "<div class='pagebreak'><hr></div>\n" : { };
}
 
 
 
print<<tail;
</BODY>
</HTML>
tail
 
 
 
sub noForm {
my $tempdate = shift;
print header (-cookie=> [ $RCAUTH_cookie ] );
print "Please pick a department and date to print:";
print $h->form ({ action=> url }, [
$h->select ({ name => "dept" }, [ $h->option (), map { $h->option ({ value => "$_" }, $DEPTS->{$_}) } ($LVL >= 5 or $user->{department}->{VCI} >= 2) ? sort keys %{$DEPTS} : sort keys %{$user->{department}} ]), $h->br,
$h->input ({
name => "date",
type => "date",
value => $tempdate,
required => [],
override => 1,
size => 30
}), $h->br,
$h->input ({ type => "submit" })
]);
exit;
}
/tags/2022.final/site/schedule/right_now.pl
0,0 → 1,206
#!/usr/bin/perl
 
use strict;
use cPanelUserConfig;
use RollerCon;
use tableViewer;
use WebDB;
use CGI;
use CGI::Cookie;
use DateTime;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $dt = DateTime->now (time_zone => 'America/Los_Angeles');
#$dt->subtract( hours => 7 );
my $day = $dt->day_name;
my $date = $dt->date;
my $curtime = $dt->hms;
 
#$day = "Wednesday";
#$date = "2022-07-13";
 
my %class = qw(
U Unrestricted
M Mens
W Womens
SS Single-Gender
);
 
my $dbh = WebDB::connect ();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
my $query = new CGI;
my $track = $query->param('t') || 'ALL';
 
 
print<<output;
<html><head><title>ORC Right Now - $day ($date) $curtime - Track $track</title>
<link rel="stylesheet" type="text/css" href="/rollercon.css">
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
output
 
my $rnh = $dbh->prepare("select * from v_shift_admin_view where id = (select id from game where date = ? and track = ? and time < CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles') and end_time > CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles'))");
my $nuh = $dbh->prepare("select * from v_shift_admin_view where id = (select id from game where date = ? and track = ? and time > CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles') order by time limit 1)");
 
my $lrnh = $dbh->prepare("select * from v_shift where id in (select id from v_shift where dept = ? and date = ? and start_time < CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles') and end_time > CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles')) order by location");
my $lnuh = $dbh->prepare("select * from v_shift where id in (select id from v_shift where dept = ? and date = ? and start_time > CONVERT_TZ(now(), 'America/Chicago', 'America/Los_Angeles') order by location, start_time)");
 
#my $gcount = 1; my $tcount = '';
#my $sth = $dbh->prepare("select distinct teams, track, level, time, gtype, restrictions from v_shift where date = ? order by track, time");
#my $crewhan = $dbh->prepare("select role, derby_name from v_shift where date = ? and track = ? and time = ?");
#my $leadhan = $dbh->prepare("select track, time, derby_name from v_lead_shift where date = ? order by track, time");
#my $openshifthan = $dbh->prepare("select time, level, restrictions, gtype, teams, tla, name from v_shift where tla <> 'ALT' and isNull(derby_name) = 1 and date = ? and track = ? order by time");
 
print "<table>\n<tr><td colspan=5><b>Right Now [$day $curtime Track $track]</b></td></tr></table><br>\n";
 
 
print "<table>\n<tr><td colspan=5><b>All Leads On Duty</b></td></tr>\n";
$lrnh->execute("OFF", $date);
while (my $lshift = $lrnh->fetchrow_hashref()) {
print "<tr><td>$lshift->{location}</td><td>&nbsp;</td><td>$lshift->{time}</td><td>&nbsp;</td><td>$lshift->{derby_name}</td></tr>\n";
}
print "</table>\n";
print "<br><br>\n";
 
my %crew;
my $g;
my $c = 1;
$rnh->execute($date, $track);
while (my $tg = $rnh->fetchrow_hashref()) {
if ($c) {
$g = $tg;
$c=0;
}
if ($tg->{derby_name}) {
$tg->{derby_name} .= " <A HREF='#' onClick=\"window.open('make_shift_change.pl?change=del&RCid=$tg->{RCid}&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
$tg->{derby_name} .= " | <A HREF='#' onClick=\"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$tg->{RCid}&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[NO SHOW]</a>";
} else {
$tg->{derby_name} = "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=lookup&RCid=$tg->RCid&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[ADD USER]</a>";
}
 
$crew{$tg->{role}} = $tg->{derby_name};
}
 
$g->{gtype} = join '', map { ucfirst lc } split /(\s+)/, $g->{gtype}; # Capitalize the game type to look nicer
 
my $P1 = "PLT-1";
my $P2 = "PLT-2";
my $PH = "PLT";
if ($g->{gtype} eq "Full Length" or $g->{gtype} eq "Selected Staffing") {
$P1 = 'PLT/H';
$P2 = 'PLT';
$PH = $P1;
}
my $A = '';
if (defined $crew{'ALT'}) {
$A = "ALT:";
} else {
$crew{'ALT'} = '';
}
 
if ($g->{teams}) {
print<<game;
<table>
<tr><td>Date:</td><td>$day ($date)</td><td>&nbsp;</td><td>Track:</td><td>$g->{track}</td></tr>
<tr><td>Time:</td><td>$g->{time}</td><td>&nbsp;</td><td>Class:</td><td>$class{$g->{restrictions}} $g->{level} $g->{gtype}</td></tr>
<tr><td>Game:</td><td colspan=4>$g->{teams}</td></tr>
<tr><td colspan=5>&nbsp;</td></tr>
<tr><td>HR:</td><td>$crew{'HR'}</td><td>&nbsp;</td><td>$PH:</td><td>$crew{$P1}</td></tr>
<tr><td>IPR:</td><td>$crew{'IPR'}</td><td>&nbsp;</td><td>PLT:</td><td>$crew{$P2}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-1'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-1'}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-2'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-2'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-1'}</td><td>&nbsp;</td><td>PBM:</td><td>$crew{'PBM'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-2'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-1'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-3'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-2'}</td></tr>
<tr><td>$A</td><td>$crew{'ALT'}</td><td>&nbsp;</td><td>JT:</td><td>$crew{'JT'}</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>SO:</td><td>$crew{'SO'}</td></tr>
</table><br>
game
} else {
print "<table>\n<tr><td colspan=5>There doesn't seem to be a game on this track right now.</td></tr></table><br>\n";
}
# $gcount++ % 2 == 0 ? print "<div class='pagebreak'><hr></div>\n" : { };
 
 
print "<table>\n<tr><td colspan=5><b>Next Up...</b></td></tr></table>\n";
 
print "<table>\n<tr><td colspan=5><b>Leads On Duty Later</b></td></tr>\n";
$lnuh->execute("OFF", $date);
while (my $lshift = $lnuh->fetchrow_hashref()) {
print "<tr><td>$lshift->{location}</td><td>&nbsp;</td><td>$lshift->{time}</td><td>&nbsp;</td><td>$lshift->{derby_name}</td></tr>\n";
}
print "</table>\n";
print "<br><br>\n";
 
my %crew;
my $g;
my $c = 1;
$nuh->execute($date, $track);
while (my $tg = $nuh->fetchrow_hashref()) {
if ($c) {
$g = $tg;
$c=0;
}
if ($tg->{derby_name}) {
$tg->{derby_name} .= " <A HREF='#' onClick=\"window.open('make_shift_change.pl?change=del&RCid=$tg->{RCid}&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[DROP]</a>";
$tg->{derby_name} .= " | <A HREF='#' onClick=\"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$tg->{RCid}&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false; }\">[NO SHOW]</a>";
} else {
$tg->{derby_name} = "<A HREF='#' onClick=\"window.open('make_shift_change.pl?change=lookup&RCid=$tg->RCid&id=$tg->{id}&role=$tg->{role}','Confirm Shift Change','resizable,height=260,width=370'); return false;\">[ADD USER]</a>";
}
 
$crew{$tg->{role}} = $tg->{derby_name};
}
$g->{gtype} = join '', map { ucfirst lc } split /(\s+)/, $g->{gtype}; # Capitalize the game type to look nicer
 
my $P1 = "PLT-1";
my $P2 = "PLT-2";
my $PH = "PLT";
if ($g->{gtype} eq "Full Length" or $g->{gtype} eq "Selected Staffing") {
$P1 = 'PLT/H';
$P2 = 'PLT';
$PH = $P1;
}
my $A = '';
if (defined $crew{'ALT'}) {
$A = "ALT:";
} else {
$crew{'ALT'} = '';
}
 
if ($g->{teams}) {
print<<game;
<table>
<tr><td>Date:</td><td>$day ($date)</td><td>&nbsp;</td><td>Track:</td><td>$g->{track}</td></tr>
<tr><td>Time:</td><td>$g->{time}</td><td>&nbsp;</td><td>Class:</td><td>$class{$g->{restrictions}} $g->{level} $g->{gtype}</td></tr>
<tr><td>Game:</td><td colspan=4>$g->{teams}</td></tr>
<tr><td colspan=5>&nbsp;</td></tr>
<tr><td>HR:</td><td>$crew{'HR'}</td><td>&nbsp;</td><td>$PH:</td><td>$crew{$P1}</td></tr>
<tr><td>IPR:</td><td>$crew{'IPR'}</td><td>&nbsp;</td><td>PLT:</td><td>$crew{$P2}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-1'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-1'}</td></tr>
<tr><td>JR:</td><td>$crew{'JR-2'}</td><td>&nbsp;</td><td>SK:</td><td>$crew{'SK-2'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-1'}</td><td>&nbsp;</td><td>PBM:</td><td>$crew{'PBM'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-2'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-1'}</td></tr>
<tr><td>OPR:</td><td>$crew{'OPR-3'}</td><td>&nbsp;</td><td>PBT:</td><td>$crew{'PBT-2'}</td></tr>
<tr><td>$A</td><td>$crew{'ALT'}</td><td>&nbsp;</td><td>JT:</td><td>$crew{'JT'}</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>SO:</td><td>$crew{'SO'}</td></tr>
</table><br>
game
} else {
print "<table>\n<tr><td colspan=5>There don't seem to be any more games on this track today.</td></tr></table><br>\n";
}
 
print "<table>\n<tr><td colspan=5><a href='/schedule/'>[ go home ]</td></tr></table><br>\n";
 
 
 
print<<tail;
</BODY>
</HTML>
tail
/tags/2022.final/site/schedule/scores.pl
0,0 → 1,393
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $secure = "";
if ($ENV{REQUEST_URI} =~ /^\/scores.pl/) {
$secure = 0;
} else {
$secure = 1;
}
 
my $cookie_string;
our ($EML, $PWD, $LVL);
my $user;
my $username;
my $RCid;
my $RCAUTH_cookie;
my $YEAR = "2022";
 
if ($secure) {
$cookie_string = authenticate(2) || die;
($EML, $PWD, $LVL) = split /&/, $cookie_string;
$user = getUser($EML);
$username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
$RCid = $user->{RCid};
$RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
}
 
 
my $pageTitle = "Game Scores";
my $prefscookie = "rcscores";
our $DBTABLE = 'v_scores';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
id => [qw(ID 5 number )],
date => [qw(Date 10 date )],
dayofweek => [qw(Day 15 select default )],
track => [qw(Track 20 select default )],
type => [qw(Type 25 select )],
time => [qw(Time 30 text default )],
team1 => [qw(Team1 35 text static )],
team2 => [qw(Team2 40 text static )]
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# Set any custom "where" DB filters here...
my @whereClause;
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_id {
my $t = shift;
if ($secure) {
if ($t->{team1_score} or $t->{team2_score}) {
$t->{id} .= " <A HREF='#' onClick=\"window.open('update_score.pl?GID=$t->{id}','Enter Score','resizable,height=260,width=370'); return false;\">[update score]</a>";
} else {
$t->{id} .= " <A HREF='#' onClick=\"window.open('update_score.pl?GID=$t->{id}','Enter Score','resizable,height=260,width=370'); return false;\">[enter score]</a>";
}
}
return $t->{id};
}
 
sub modify_team1 {
my $t = shift;
$t->{team1} .= " ($t->{team1_score})" unless !defined $t->{team1_score};
$t->{team2} .= " ($t->{team2_score})" unless !defined $t->{team2_score};;
if ($t->{team1_score} > 0 or $t->{team2_score} > 0) { #SPIKE SEZ DO SOMETHING HERE RE GAME SCORE OF 0
if ($t->{team1_score} > $t->{team2_score}) { $t->{team1} = "<b>$t->{team1}</b>"; } else { $t->{team2} = "<b>$t->{team2}</b>"; }
}
return $t->{team1};
}
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
my @yearoptions;
foreach (@{&getYears()}) {
push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
push @whereClause, "year(date) = '$YEAR'";
 
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($secure and $FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
if ($secure) {
print header(-cookie=>[$RCAUTH_cookie,$queryCookie]);
} else {
print header(-cookie=>[$queryCookie]);
}
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
 
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
my @excelcode;
 
if ($secure) {
push @excelcode, $h->br;
push @excelcode, $h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]");
}
 
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
@excelcode,
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com",
$h->br,
"Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
/tags/2022.final/site/schedule/shifts.pl
0,0 → 1,475
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
use DateTime;
use DateTime::Duration;
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (1) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments $user->{department};
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR = "2022";
 
if (!scalar (grep { $user->{department}->{$_} > 0 } grep { !/^(ANN|OFF)$/ } keys %{$user->{department}}) and
$user->{department}->{ANN} < 2 and
$user->{department}->{OFF} < 2 and
$LVL < 4) {
print header(-cookie=>$RCAUTH_cookie);
printRCHeader("Unauthorized Page");
print $h->div ({ class=>"error" }, "No Access");
print $h->div ("Your user account is not registered as a Volunteer in a department that uses this view, so you can't see these shifts. It's possible that your access is still being reviewed. Please be patient.");
print $h->a ({ href=>"/schedule/" }, "[Go Home]");
print $h->close ("html");
exit;
}
 
 
my $pageTitle = "Volunteer Shifts";
my $prefscookie = "vorcshifts";
our $DBTABLE = 'v_shift';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
id => [qw(ShiftID 5 number )],
dept => [qw(Department 10 select default )],
role => [qw(Role 15 text default )],
type => [qw(Type 20 select default )],
date => [qw(Date 25 date default )],
dayofweek => [qw(Day 27 select )],
location => [qw(Location 30 select default )],
time => [qw(Time 35 text default )],
start_time => [qw(Start 36 text )],
end_time => [qw(End 40 text )],
mod_time => [qw(ModTime 45 number )],
doubletime => [qw(DoubleTime 47 boolean )],
volhours => [qw(VolHours 50 number )],
note => [qw(Notes 55 text default )],
RCid => [qw(AssigneeID 60 text )],
derby_name => [qw(DerbyName 65 select default )],
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
my @whereClause;
if ($LVL <= 3 and $user->{department}->{VCI} < 2) {
my $string = "dept in (".join ",", map { '"'.$_.'"' } grep { $ORCUSER->{department}->{$_} > 0 } keys %{$ORCUSER->{department}};
$string .= ")";
# warn $string;
push @whereClause, $string;
}
push @whereClause, "(dept != 'PER' or RCid = $RCid)";
 
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_doubletime {
my $thing = shift;
return $thing->{doubletime} ? "True" : "False";
}
 
sub modify_derby_name {
my $t = shift;
 
if ($user->{department}->{$t->{dept}} < 2 and $t->{derby_name} and $t->{RCid} != $RCid and $LVL < 5) {
$t->{derby_name} = "FILLED";
} elsif (($user->{department}->{$t->{dept}} > 1 or $LVL > 4) and $t->{derby_name}) {
$t->{derby_name} = $h->a ({ href=>"/schedule/manage_user.pl?RCid=$t->{RCid}" }, $t->{derby_name});
}
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
my $cutoff = DateTime->new(
year => $yyyy,
month => $mm,
day => $dd,
hour => 5,
minute => 0,
second => 0,
time_zone => 'America/Los_Angeles'
);
 
if (($t->{RCid} == $RCid and $t->{type} ne "selected" and $now < $cutoff) or ($t->{derby_name} and ($user->{department}->{$t->{dept}} >= 2 or $LVL >= 5 or $user->{department}->{VCI} >= 2))) {
if ($t->{dept} eq "PER") {
# DEL Personal Block
$t->{derby_name} .= " ".$h->a ({ onClick=>"if (confirm('Really? You want to delete this personal time?')==true) { window.open('manage_personal_time.pl?choice=Delete&id=$s[0]','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DEL]");
} else {
# DROP
$t->{derby_name} .= " ".$h->a ({ onClick=>"if (confirm('Really? You want to drop this shift?')==true) { window.open('make_shift_change.pl?change=del&RCid=$t->{RCid}&id=$t->{id}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");
if ($user->{department}->{$t->{dept}} >= 2 or $LVL >= 5 or $user->{department}->{VCI} >= 2) {
# NO SHOW and MOD TIME
$t->{derby_name} .= " | ".$h->a ({ href=>'#', onClick=>"if (confirm('Really? They were a no show?')==true) { window.open('make_shift_change.pl?noshow=true&change=del&RCid=$t->{RCid}&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false; }" }, "[NO SHOW]");
$t->{derby_name} .= " | ".$h->a ({ onClick=>"window.open('mod_shift_time.pl?RCid=$t->{RCid}&shiftid=$t->{id}','Mod Vol Hours','resizable,height=260,width=370');" }, "[MOD]");
}
}
} elsif (!$t->{derby_name}) {
if (signUpEligible ($ORCUSER, $t, "vol") and $now < $cutoff) {
# SIGN UP
$t->{derby_name} = $h->a ({ onClick=>"window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "[SIGN UP]");
}
if ($user->{department}->{$t->{dept}} >= 2 or $LVL > 4 or $user->{department}->{VCI} >= 2) {
# ADD USER
$t->{derby_name} ? $t->{derby_name} .= " | " : {};
$t->{derby_name} .= $h->a ({ onClick=>"window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$t->{id}','Confirm Shift Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");
}
}
return $t->{derby_name};
}
 
my $DEPTS = getDepartments;
sub modify_dept {
my $hr = shift;
return $DEPTS->{$hr->{dept}};
}
 
sub filter_dept {
my $colName = shift;
my $filter = shift;
if (defined $filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
return "$colName = \"$filter\"";
} else {
my $thing = "filter-${colName}";
my $categories = join "", map { $FORM{$thing} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $DEPTS->{$_}) : $h->option ({ value=>$_ }, $DEPTS->{$_}) } grep { $LVL > 4 or $user->{department}->{VCI} >= 2 or exists $user->{department}->{$_} } sort keys %{$DEPTS};
my $Options = "<OPTION></OPTION>".$categories;
 
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
}
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") { # Compile list of fields to display
if ($_ ne "shiftinclude") {
push @displayFields, $_;
}
}
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$FORM{shiftinclude} = $si;
$QUERY_STRING = $prefs;
} else {
@displayFields = sort byfield @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my @shifts;
if ($FORM{shiftinclude} eq "true") {
my @SIWhere = ("year(date) = '$YEAR'");
push @SIWhere, "RCid = $ORCUSER->{RCid}";
my ($d, $c) = getData (\@displayFields, \@SIWhere, $DBTABLE, $FORM{sortby});
@shifts = @{ $d };
}
 
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my ($uri) = split /\?/, $ENV{REQUEST_URI};
my $path = `dirname $uri`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
my $SIChecked;
if ($FORM{shiftinclude}) {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
} else {
$SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
}
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
#printRCHeader ($pageTitle);
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs, $h->br,
"Show my shifts: ", $SIChecked, $h->br,
$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='manage_personal_time.pl'" }),
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f}, "&nbsp;", $h->input ({ type=>"button", value=>"Add", onClick=>"window.location.href='manage_shift.pl'" }) ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
if ($FORM{shiftinclude}) { # Include all of the user's shifts at the top
foreach my $t (@shifts) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
print $h->hr ({ width=>"500%" });
}
 
# Print the things
#foreach my $t (@ProductList) {
# print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
#}
foreach my $t (@ProductList) {
if ($t->{RCid} eq $ORCUSER->{RCid}) {
print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
} else {
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
}
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
/tags/2022.final/site/schedule/template.pl
0,0 → 1,339
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (3) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR;
 
 
my $pageTitle = "Dev Log Viewer";
my $prefscookie = "logscookie";
our $DBTABLE = 'v_log';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
eventid => [qw(EventID 5 number default )],
timestamp => [qw(Timestamp 10 date default )],
event => [qw(Event 15 text default )],
RCid => [qw(RCID 20 number default )],
derby_name => [qw(DerbyName 25 select default )],
email => [qw(Email 30 text )],
real_name => [qw(RealName 35 text )],
access => [qw(Role 40 select )]
);
my $stylesheet = "/style.css";
my $homeURL = '/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# Set any custom "where" DB filters here...
my @whereClause;
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
 
 
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
#push @whereClause, "year(date) = '$YEAR'";
 
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
 
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/update_score.pl
0,0 → 1,95
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
use cPanelUserConfig;
use CGI qw/:standard/;
use RollerCon;
use Spreadsheet::WriteExcel;
use DateTime;
use DateTime::Duration;
 
my $cookie_string = authenticate(2) || die;
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser($EML);
my $username = $user->{derby_name};
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
 
my $GID = param('GID');
my $T1 = param('T1');
my $T2 = param('T2');
my $action = param('action');
 
die unless $GID;
 
my $dbh = getRCDBH;
my $gethan = $dbh->prepare("select * from v_scores where id = ?");
my $puthan = $dbh->prepare("replace into score (gid, team1_score, team2_score) values (?, ?, ?)");
 
my $savestatus = "";
my $reload = "";
if ($action eq "Save") {
if ($T1 eq '' or $T2 eq '') {
$savestatus = "<font color=red><b>ERROR:</b> Missing Score!</font>";
} else {
$savestatus = "Saved!";
$reload = 'onload="reloadParent()"';
$puthan->execute($GID, $T1, $T2) or $savestatus="<font color=red><b>ERROR:</b> Error Saving!</font>";
}
}
 
$gethan->execute($GID);
my ($game) = $gethan->fetchrow_hashref();
 
print CGI::header(-cookie=>$RCAUTH_cookie);
 
print<<page1;
<HTML><HEAD>
<TITLE>RC17 Game Score Recorder</TITLE>
<link rel="stylesheet" type="text/css" href="/rollercon.css">
</HEAD>
<body text="#000000" bgcolor="#FFFFFF" link="#000000" vlink="#000000" alink="#FF0000" $reload>
 
<form action="update_score.pl" method=GET name=ScoreUpdate>
$savestatus
<table>
<tr>
<td colspan=2>Game: $game->{id}<input type=hidden name=GID value=$game->{id}> - $game->{dayofweek} - $game->{track} - $game->{time}</TD>
</tr><tr>
<td>$game->{team1}</td><td><input type=text name=T1 size=4 value=$game->{team1_score}></td>
</tr><tr>
<td>$game->{team2}</td><td><input type=text name=T2 size=4 value=$game->{team2_score}></td>
</tr><tr>
<td colspan=2><input type=Submit name=action value=Reset> <input type=Submit name=action value=Save> <input type=Reset value=Cancel onClick=window.close();></td>
</tr>
</table>
</form>
 
page1
 
if ($savestatus ne '') {
print<<refresh;
<SCRIPT language="JavaScript">
<!--
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function reloadParent() {
window.opener.location.reload();
setTimeout(() => { window.close(); }, 3000);
}
 
//-->
</SCRIPT>
 
refresh
}
 
print "</BODY></HTML>\n";
/tags/2022.final/site/schedule/user_report.pl
0,0 → 1,417
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (2) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR;
 
my $pageTitle = "User Report";
my $prefscookie = "userreport";
our $DBTABLE = 'official';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
RCid => [qw(ID 5 number )],
derby_name => [qw(DerbyName 10 text default )],
email => [qw(Email 15 text default )],
real_name => [qw(RealName 20 text default )],
pronouns => [qw(Pronouns 25 text default )],
tshirt => [qw(TShirtSize 30 select default )],
phone => [qw(Phone 35 text )],
access => [qw(vOrcAccess 40 select )],
department => [qw(Department 45 select default )],
added => [qw(Added 50 date )],
last_login => [qw(LastLogin 55 date )]
);
 
my $ROLE = getAccessLevels;
my $DepartmentNames = getDepartments ();
 
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
# You can also create specific "filter_column" subroutines...
 
#sub modify_RCid {
# my $li = shift // "";
# return join "&nbsp;", $li->{RCid},
# $h->a ({ href=>"manage_user.pl?RCid=$li->{RCid}" }, "[Edit]"),
# ;
#}
 
sub modify_department {
my $li = shift // "";
if ($li->{"department"}) {
my $Ds = convertDepartments $li->{"department"};
return join $h->br, map { ($Ds->{$_} == 0 and ($ORCUSER->{department}->{$_} > 1 or $LVL > 4)) ? $h->a ({ onClick=>"event.stopPropagation(); window.open('activate_user.pl?RCid=$li->{RCid}&department=$_','Activating User','resizable,height=260,width=370');" }, "$DepartmentNames->{$_} - $ROLE->{$Ds->{$_}}") : "$DepartmentNames->{$_} - $ROLE->{$Ds->{$_}}" } sort keys %{$Ds};
} else {
return "";
}
}
 
sub modify_access {
my $li = shift // "";
my @levels = ($li->{"access"});
if ($li->{"department"}) {
push @levels, values %{convertDepartments $li->{"department"}};
}
return $ROLE->{ max @levels };
}
 
sub filter_department {
my $colName = shift;
my $filter = shift // "";
if ($filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
if ($filtered_by_access ne "") {
return "$colName like \"%$filter-$filtered_by_access%\"";
} else {
return "$colName like \"%$filter%\"";
}
} else {
my @options = ("");
push @options, "-blank-" unless $LVL < 4;
push @options, ($LVL < 4 and $ORCUSER->{department}->{VCI} < 2) ? grep { $ORCUSER->{department}->{$_} >= 2 } sort keys %{$ORCUSER->{department}} : sort keys %{$DepartmentNames};
@options = map { $FORM{"filter-department"} eq $_ ?
( $h->option ({ selected=>[], value=>$_ }, $_ eq "-blank-" ? $_ : $DepartmentNames->{$_}) ) :
( $h->option ({ value=>$_ }, $_ eq "-blank-" ? $_ : $DepartmentNames->{$_}) ) } @options;
return $FORM{autoload} ? $h->select ({ name=>"filter-department", onChange=>"page.value = 1; submit();" }, [@options]) : $h->select ({ name=>"filter-department" }, [$h->option (), @options]);
}
}
 
our $filtered_by_access = "";
sub filter_access {
my $colName = shift;
my $filter = shift // "";
if ($filter ne "") {
$filtered_by_access = $filter;
return $filter eq "-1" ? "$colName = $filter" : "($colName = $filter or department like '%$filter%')";
} else {
my @options = ("", -1, 0, 1, 2, 3, 4, 5);
@options = map { $FORM{"filter-access"} eq $_ ?
( $h->option ({ selected=>[], value=>$_ }, $ROLE->{$_}) ) :
( $h->option ({ value=>$_ }, $ROLE->{$_}) ) } @options;
return $FORM{autoload} ? $h->select ({ name=>"filter-access", onChange=>"page.value = 1; submit();" }, [@options]) : $h->select ({ name=>"filter-access" }, [$h->option (), @options]);
}
}
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
my @whereClause = map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
#warn @whereClause;
if ($LVL < 4 and $ORCUSER->{department}->{VCI} < 2) {
# warn keys %{$ORCUSER->{department}};
my $string = join " or ", map { 'department like "%'.$_.'%"' } grep { $ORCUSER->{department}->{$_} >= 2 } keys %{$ORCUSER->{department}};
$string = "($string)";
# warn $string;
push @whereClause, $string;
}
#push @whereClause, "year(date) = '$YEAR'";
 
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
print $h->div ({ class=>'rTableRow shaded', onclick=>"location.href='manage_user.pl?RCid=$t->{RCid}'" }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
/tags/2022.final/site/schedule/volhours.pl
0,0 → 1,370
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (3) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments ($user->{department});
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR;
 
 
my $pageTitle = "Volunteer Hours Summary";
my $prefscookie = "volhours";
our $DBTABLE = 'v_volhours';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
derby_name => [qw(DerbyName 25 select static )],
dept => [qw(Department 30 select static )],
hours => [qw(Hours 40 number static )]
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# Set any custom "where" DB filters here...
my @whereClause;
if ($LVL < 5) {
my $string = "dept in (".join ",", map { '"'.$_.'"' } grep { $user->{department}->{$_} >= 3 } keys %{$user->{department}};
$string .= ")";
push @whereClause, $string;
}
push @whereClause, "dept != 'PER'";
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_derby_name {
my $li = shift;
return $h->a ({ href=>"manage_user.pl?RCid=".getRCid ($li->{derby_name}) }, $li->{derby_name});
}
 
 
my $DEPTS = getDepartments ();
sub modify_dept {
my $hr = shift;
return $DEPTS->{$hr->{dept}};
}
 
sub filter_dept {
my $colName = shift;
my $filter = shift;
if (defined $filter) {
if ($filter eq "-blank-") {
return "($colName = '' or isNull($colName) = 1)";
}
return "$colName = \"$filter\"";
} else {
my $thing = "filter-${colName}";
my $categories = join "", map { $FORM{$thing} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $DEPTS->{$_}) : $h->option ({ value=>$_ }, $DEPTS->{$_}) } grep { $LVL > 4 or $user->{department}->{$_} >= 3 } sort keys %{$DEPTS};
my $Options = "<OPTION></OPTION>".$categories;
 
$Options =~ s/>($FORM{$thing})/ selected>$1/;
return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
}
}
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
#push @whereClause, "year(date) = '$YEAR'";
 
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
no strict;
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
 
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/schedule/volhours_report.pl
0,0 → 1,345
#!/usr/bin/perl
 
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
 
#use strict;
use cPanelUserConfig;
use CGI qw/param cookie header start_html url/;
use HTML::Tiny;
use tableViewer;
use RollerCon;
our $h = HTML::Tiny->new( mode => 'html' );
 
my $cookie_string = authenticate (5) || die;
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
my $user = getUser ($EML);
$user->{department} = convertDepartments ($user->{department});
my $username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
my $RCid = $user->{RCid};
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
my $YEAR;
 
 
my $pageTitle = "Volunteer Hours Year End Report";
my $prefscookie = "volhours_report";
our $DBTABLE = 'v_volhours_report';
my %COLUMNS = (
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
derby_name => [qw(DerbyName 20 text static )],
real_name => [qw(RealName 25 text static )],
email => [qw(Email 30 text static )],
totalhours => [qw(TotalHours 40 number static )]
);
my $stylesheet = "/style.css";
my $homeURL = '/schedule/';
my @pagelimitoptions = ("All", 5, 10, 25);
 
# Set any custom "where" DB filters here...
my @whereClause;
 
# If we need to modify line item values, create a subroutine named "modify_$columnname"
# It will receive a hashref to the object lineitem
 
sub modify_derby_name {
my $li = shift;
return $h->a ({ href=>"manage_user.pl?RCid=".getRCid ($li->{derby_name}) }, $li->{derby_name});
}
 
 
sub modify_dept {
my $hr = shift;
return $DEPTS->{$hr->{dept}};
}
 
 
 
# Ideally, nothing below this comment needs to change
#-------------------------------------------------------------------------------
 
 
our %NAME = map { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
our %colOrderHash = map { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
our %colFilterTypeHash = map { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
our @staticFields = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
our @defaultFields = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
#our @defaultFields = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
 
our @allFields = sort byfield keys %NAME;
our @displayFields = ();
our @hideFields = ();
my $QUERY_STRING;
 
my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
my $curpage = param ("page") // 1;
 
our %FORM;
my $FILTER;
foreach (param()) {
if (/^year$/) { #
$YEAR = param($_);
next;
}
 
$FORM{$_} = param($_); # Retrieve all of the FORM data submitted
if ((/^filter/) and ($FORM{$_} ne '')) { # Build a set of filters to apply
my ($filter,$field) = split /-/, $_;
$FILTER->{$field} = $FORM{$_};
} elsif ($FORM{$_} eq "true") # Compile list of fields to display
{ push @displayFields, $_; }
}
 
 
if (exists $FORM{autoload}) { # If the FORM was submitted (i.e. the page is being redisplayed),
# build the data for the cookie that remembers the page setup
my $disFields = join ":", @displayFields;
my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
}
 
 
if (!(exists $FORM{autoload})) { # No FORM was submitted...
if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie")) { # Check for cookies from previous visits.
my ($disF, $filts, $sb, $al) = split /&/,$prefs;
@displayFields = split /:/,$disF;
foreach my $pair (split /:/, $filts) {
my ($key, $value) = split /=/, $pair;
$FORM{"filter-$key"} = $value;
$FILTER->{$key} = $value;
}
$FORM{sortby} = $sb;
$FORM{autoload} = $al;
$QUERY_STRING = $prefs;
} else {
@displayFields = @defaultFields; # Otherwise suppply a default list of columns.
$FORM{autoload} = 1; # And turn aut0load on by default.
}
}
 
# let's just make sure the columns are in the right order (and there aren't any missing)
@displayFields = sort byfield uniq @displayFields, @staticFields;
 
# If the field isn't in the displayFields list, then add it to the hideFields list
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
 
# Process any filters provided in the form to pass to the database
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
#push @whereClause, "year(date) = '$YEAR'";
 
 
# Given the fields to display and the where conditions,
# "getData" will return a reference to an array of
# hash references of the results.
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
my @ProductList = @{ $data };
 
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
my $x = scalar @ProductList; # How many results were returned?
 
# If the user is trying to download the Excel file, send it to them and then exit out.
if ($FORM{excel}) {
exportExcel (\@ProductList, "RC_Officiating_Shifts");
exit;
}
 
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl", onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/';return true;" }, "[Log Out]") : "You are not signed in.";
 
# Set some cookie stuff...
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
my $queryCookie = cookie(-NAME=>$prefscookie,
-VALUE=>"$QUERY_STRING",
-PATH=>"$path",
-EXPIRES=>'+365d');
 
# Print the header
print header (-cookie=> [ $queryCookie, $RCAUTH_cookie ] );
 
# print "<!-- FORM \n\n"; # Debug code to dump the FORM to a html comment
# print "I'm catching updates!!!\n\n";
# foreach $key (sort (keys %FORM)) # Must be done after the header is written!
# { print "\t$key: $FORM{$key}\n"; }
# print "--> \n\n";
#
#
# print "<!-- ENV \n\n"; # Debug code to dump the ENV to a html comment
# foreach $key (sort (keys %ENV)) # Must be done after the header is written!
# { print "\t$key: $ENV{$key}\n"; }
# print "--> \n\n";
#
# print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
 
 
#------------------
 
# Toggle the autoload fields within the table elements
our ($onClick, $onChange); # (also used in scanFunctions)
my ($radiobutton, $refreshbutton, $sortby);
if ($FORM{autoload}) {
$onClick = "onClick='submit();'";
$onChange = "onChange='page.value = 1; submit();'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
]);
$sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
} else {
$onClick = "";
$onChange = "onChange='page.value = 1;'";
$radiobutton = $h->div ({ class=>'autoload' },
["Autoload Changes: ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
$h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
]);
$refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
$sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
}
 
 
 
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
 
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
print $h->div ({ class => "accent pageheader" }, [
$h->h1 ($pageTitle),
$h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$radiobutton
]),
$h->div ({ class=>"spRight" }, [
$h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
$refreshbutton
]),
]),
]);
 
# Print the Hidden fields' check boxes (if there are any)
 
my $c = 1;
my @hiddencheckboxes;
my @hiddenrows;
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
if ($FORM{autoload}) {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
} else {
push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
}
if ($c++ % 4 == 0) {
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
@hiddencheckboxes = [];
}
}
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
 
 
if (scalar @hideFields) {
my @topleft;
push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [ @topleft ]),
$h->div ({ class=>"spRight" }, [
$signedOnAs
])
]);
}
 
# Print the main table...............................................
 
print $h->open ('div', { class=>'rTable' });
 
my @tmptitlerow;
foreach my $f (@displayFields) { # Print the Column headings
if (inArray ($f, \@staticFields)) {
push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
} else {
if ($FORM{autoload}) {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
} else {
push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
}
}
}
 
# Print the filter boxes...
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
 
# Print the things
foreach my $t (@ProductList) {
no strict;
print $h->div ({ class=>'rTableRow shaded' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
}
 
 
 
 
print $h->close ('div');
 
# close things out................................................
 
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
if ($curpage > $pages) { $curpage = $pages; }
 
my @pagerange;
if ($pages <= 5 ) {
@pagerange = 1 .. $pages;
} else {
if ($curpage <= 3) {
@pagerange = (1, 2, 3, 4, ">>");
} elsif ($curpage >= $pages - 2) {
@pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
} else {
@pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
}
}
 
print $h->br; # print $h->br;
print $h->div ({ class=>"sp0" }, [
$h->div ({ class=>"spLeft" }, [
$h->div ({ class=>"footer" }, [
"To bookmark, save, or send this exact view, use the ",
$h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
$h->br,
"If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
$h->br,
$h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]"),
$h->br,
"This page was displayed on ", currentTime (),
$h->br,
"Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com"
])
]),
$h->div ({ class=>"spRight" }, [
$h->h5 ([
"$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
"Sorted by ", $sortby, $h->br,
"Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
$_ eq "<<" ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
$_ eq ">>" ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
$h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
$h->input ({ type=>"hidden", name=>"page", value=>$curpage })
])
]),
]);
 
#print $h->br; # print $h->br;
#print $h->h5 ("$x Record(s) Displayed");
#print $h->div ({ class=>"footer" }, [
# "To bookmark, save, or send this exact view, use the ",
# $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
# $h->br,
# "This page was displayed on $now",
# $h->br,
# "Please direct questions, problems, and concerns to noone\@gmail.com"
#]);
 
 
print $h->close('form');
print $h->close('html');
/tags/2022.final/site/favicon.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/2022.final/site/favicon.ico
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/2022.final/site/index.html
0,0 → 1,10
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="refresh" content="0; url='/schedule/'" />
<title>RollerCon Volunteer Scheduler</title>
</head>
<body>
<p><a href="/schedule/">Redirect</a></p>
</body>
</html>
 
/tags/2022.final/site/info.html
0,0 → 1,38
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vORC Documentation</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
 
<body>
<h1> Privacy</h1>
<p>The information you provide within vORC (including personal details like your name and email address) are only ever used for managing your volunteer time at RollerCon. Those details are typically unavailable to other Volunteers, but can be viewed by Leads, Managers, Director(s), and the System Administrator(s) working in their leadership roles (e.g. a Lead typically only sees the details of the Volunteers within their Department). vORC will set cookies within your browser to manage your login session and preserve your views / preferences between sessions. vORC sends automated reminders of your upcoming scheduled shift(s), and Leadership may need to occasionally contact you.</p>
<p>While your name (and Derby Name) will not typically be visible to other Volunteers (exept as detailed above), your "RCID" will be. This is a unique, numeric identifier used within vORC. If you want to keep your schedule confidential, do not share your RCID; and vice versa, if you'd like to share your schedule with friends (maybe so they can sign up to work together), give them your RCID (viewable on your Profile page).</p>
<h1>Accounts / Logging In</h1>
<p>After registering a new account request, a leader from (one of) the requested Department(s) will review your request and approve (or deny) it. Once activated in at least one Department, you'll be able to log in. Each Department is reviewed independently, and you'll only see shifts for Departments that you're a member of.</p>
<p>If you'd like to volunteer in additional departments, edit your profile and activate the corresponding slider. <strong>The leadership of that Department will be alerted to your request and will review in due time</strong> (this is a good place for a reminder that all of the Department leaders are volunteers such as yourself, and they don't all live on a computer 24x7).</p>
<h1>Signing Up For Shifts</h1>
<p>Once activated within a Department, you'll be able to view and sign up for shifts.</p>
<p>There are two general kinds of shifts, Game-based and Time-based.</p>
<p><strong>Game-Based Shifts</strong> are tied to one of the scheduled competitive games and are generally located at a track (C1, C2, etc). The Game schedule includes warm-up time to get skaters checked in, questions sorted out, etc. You'll need to be ready to work the shift at the beginning of the timeslot and assist in any related responsibilities. You receive volunteer credit for the scheduled timeslot of the game, regardless of whether it ends early. The game schedule is of paramount importance, and games will virtually never end late. Which also means that if you're late for a game-based shift, you will be replaced.</p>
<p><strong>Time-Based Shifts</strong> have a set start and end time and can be located virtually anywhere (and everywhere) at RollerCon. The location will be designated in the shift, and you're expected to be at that place (ready to work) at the start time. Being on-time is just as important since being late typically impacts other Volunteers that you may be taking over for. If you work longer than scheduled, or need to leave early for an emergency, talk to your Department leadership and they can modify (add or reduce) the time credited for your shift.</p>
<p>Most shifts are open sign-up. Anyone in the Department can simply click on the "Sign Up" link and claim the shift. If you change your schedule (or just your mind) later, you can click on the "Drop" link to remove yourself from that shift. There are time limits though; typically shifts will be locked in the day of, at which point if you'd like to add or remove something from your schedule, you'll need to speak with someone in the Department leadership.</p>
<p>There are other shifts that are either reserved for specific roles (like Leads) or just staffed through application / selection. Each Department has their own process for those selected staffing decisions (so it won't be detailed here). Only Department Leadership can change selected staffing sign-ups.</p>
<p>vORC will not let someone sign up to be in two places at the same time. If you're looking at an open sign-up shift, but don't see a Sign Up link, you may already have a shift that would overlap. Keep in mind that you may be able to sign up for back-to-back shifts in very different locations, so be sure to give yourself enough time to relocate if necessary.</p>
<p>You are limited in the number of shifts you can claim in a day. Once that limit is reached, the Sign-Up link will not be displayed until the next day (midnight US/Central). As RollerCon gets closer, the daily limits may be raised. If you've already signed up for your daily limit of shifts, but then decide there's another one you want more, you can drop a shift to get back under the limit.</p>
<p><strong>Personal Time</strong> can be reserved in the system. On the home page, and on the shift sign-up pages, there's a link to add a Personal Time block. Department Leaders will be able to see the times you have blocked off but not other details. (Note that SysAdmins will be able to see all of the details in the database.) A Personal Time block is just a way to reserve time on your schedule to ensure you don't book yourself when you have something else happening (like a class you're taking).&nbsp;&nbsp;</p>
<p><strong>No Shows</strong> are bad. Very, very bad. If you don't show up for a shift, you may lose any future shifts at RollerCon.</p>
<h1>Using the vORC Table Views</h1>
<p>Most of the work to peruse and sign up for shifts is done through a table format. Users can customize their view in a number of ways.</p>
<h3>Columns</h3>
<p>You can hide or show columns that you care about (or don't). The top of each column has a checkbox to remove that column from the view, and there's a corral of hidden fields' checkboxes to add any of them back. (In some views, some column heading might not have a checkbox to hide it. Those columns are necessary for the page to function properly.)</p>
<h3>Filters</h3>
<p>Just below the column title, there are a series of input boxes to search and/or filter the results being displayed. Each filter acts cumulatively, so combining multiple inputs will narrow the results further and further.</p>
<h3>Sorting</h3>
<p>At the bottom right of the results, there's the option to sort the results by any of the displayed fields.</p>
<h3>Other Helpful Features</h3>
<p>There are a few useful links on the bottom left to help. Included are options to export your current view to an Excel file, a link for bookmarking (or emailing) your exact current view, and a link to reset the page's options (clear all filters, return to default set of columns displayed, etc). </p>
</body>
</html>
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/tags/2022.final/site/logo.jpg
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/2022.final/site/logo.jpg
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/tags/2022.final/site/rollercon.css
0,0 → 1,24
TH
{
font-weight: bold;
font-size: smaller;
font-family: verdana;
white-space: nowrap;
text-align: left;
}
TR:nth-child(even)
{
background-color: #F2F2F2;
}
TR.nostripe
{
background-color: #FFFFFF;
}
TD
{
font-family: verdana;
font-size: smaller;
white-space: nowrap;
text-align: left;
}
.pagebreak { page-break-after: always; }
/tags/2022.final/site/style.css
0,0 → 1,444
:root {
--dark-color: #004771;
--medium-color: #0090e4;
--light-color: rgba(0, 119, 189, .2);
--highlight: rgba(0, 119, 189, .4);
--hl-light: #ffff99;
--hl-dark: #ffe699;
}
 
body {
background-color: white;
font-family: Verdana, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "DejaVu Sans", "sans-serif";
color: var(--dark-color);
margin: 4px;
}
 
.hide {
display: none;
padding: 10px;
}
 
.show:hover + .hide {
display: block;
position: absolute;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
 
div {
color: var(--dark-color);
}
 
.index {
margin-top: 25px;
margin-left: 5px;
max-width: 875px;
}
 
.heading {
background-color: var(--dark-color);
accent-color: var(--dark-color);
border-radius: 3px 15px 3px 3px;
/* max-width: 610px; */
padding: 5px;
color: white;
}
 
ul {
max-width: 95%;
}
 
li {
/* max-width: 580px; */
}
.lisp0 {display:flex;}
.liLeft {
float:left;
display: flex;
width:80%;
margin: auto;
}
 
.liRight {
float:right;
width:20%;
text-align:right;
}
 
.accent {
background-color: var(--dark-color);
accent-color: var(--dark-color);
}
 
.pageheader {
max-width: 610px;
padding: 10px;
border-radius: 5px 35px 5px 5px;
margin-bottom: 4px;
}
 
.sp0 {display:flex; max-width:875px;}
.spLeft {
float:left;
display: flex;
width:65%;
font-size: x-small;
}
 
.spRight {
float:right;
width:35%;
text-align:right;
font-size: x-small;
}
 
.autoload {
color: rgba(255,255,255, .9);
}
 
input[type=radio] {
opacity: 75%;
}
 
h1 {
color: white;
font-style: italic;
font-weight: bold;
text-shadow: 2px 2px 4px #000000;
margin: 0;
}
 
h5 {
font-size: x-small;
margin: 0;
line-height: 200%;
}
 
.footer {
font-size: xx-small;
font-weight: bold;
}
 
a {
color: var(--dark-color);
text-decoration: none;
white-space: nowrap;
}
 
 
a:hover {
text-decoration: underline;
cursor: pointer;
}
 
.nowrap {
white-space: nowrap;
margin: auto;
}
 
input[type=text],
input[type=number],
input[type=password],
input[type=time],
input[type=date],
select,
textarea
{
font-size: small;
padding: 2px;
border: 1px solid var(--medium-color);
border-radius: 4px;
box-sizing: border-box;
outline: none;
color: var(--dark-color);
}
 
input[type=text]:focus,
input[type=number]:focus,
input[type=password]:focus,
input[type=time]:focus,
input[type=date]:focus,
select:focus,
textarea:focus {
border: 1px solid var(--dark-color);
}
 
 
button,
input[type=button],
input[type=reset],
input[type=submit] {
background-color: var(--medium-color);
border: none;
color: var(--dark-color);
padding: 4px 16px;
text-decoration: none;
margin: 4px 2px;
border-radius: 15px;
font-weight: bold;
box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
cursor: pointer;
font-size: xx-small;
vertical-align: middle;
}
 
button:hover, input:hover[type=button], input:hover[type=submit], input:hover[type=reset] {
background-color: var(--dark-color);
color: var(--medium-color);
box-shadow: -2px -2px 4px var(--light-color);
vertical-align: middle;
}
 
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
 
.inputfile + label {
background-color: var(--medium-color);
border: none;
color: var(--dark-color);
padding: 4px 16px;
text-decoration: none;
margin: 4px 2px;
border-radius: 15px;
font-weight: bold;
box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
cursor: pointer;
font-size: x-small;
display: inline-block;
}
 
.inputfile + label * {
pointer-events: none;
}
 
.inputfile:focus + label,
.inputfile + label:hover {
background-color: var(--dark-color);
color: var(--medium-color);
box-shadow: -2px -2px 4px var(--light-color);
}
 
.bold {
font-weight: bold;
}
 
.success {
font-size: small;
font-weight: bold;
color: green;
}
 
.error {
font-size: small;
font-weight: bold;
color: crimson;
}
 
.hint {
font-size: small;
font-style: italic;
color: darkgray;
}
 
.top {
vertical-align: top;
}
.rTable {
display: table;
padding: 0;
border: 0;
border-spacing: 0;
margin: 0;
min-width: 80%;
}
.rTableRow { display: table-row; }
.rTableRowSpan { display: table-row; column-span: all; }
.rTableHeading {
display: table-header-group;
}
.rTableHead {
display: table-cell;
color: white;
background-color: var(--dark-color);
font-style: italic;
font-size: small;
text-shadow: 1px 1px 2px #000000;
text-align: left;
white-space: nowrap;
padding: 3px 12px;
}
 
.rTableHead:first-child {
border-radius: 5px 0 0 0;
}
 
.rTableHead:last-child {
border-radius: 0 20px 0 0;
}
 
.rTableBody { display: table-row-group; }
.rTableFoot { display: table-footer-group; }
.rTableCell {
display: table-cell;
color: var(--dark-color);
font-size: x-small;
text-align: left;
padding: 5px 12px;
}
 
.rTableCellr {
display: table-cell;
color: var(--dark-color);
font-size: x-small;
text-align: left;
padding: 5px 12px;
}
.rTableCellr:first-child {
text-align: right;
}
 
.quarters {
width: 25%;
}
 
.right {
text-align: right;
}
 
.shaded:nth-child(odd) {
background-color: var(--light-color);
}
 
.shaded:nth-child(even) {
background-color: white;
}
 
.shaded:hover {
background-color: var(--highlight);
}
 
.highlighted {
background-color: var(--hl-light);
}
 
.highlighted:hover {
background-color: var(--hl-dark);
}
 
tr.highlighted {
background: var(--hl-light);
}
 
.filters {
background-color: var(--medium-color);
}
 
table {
padding: 0;
border: 0;
border-spacing: 0;
margin: 0;
}
 
tr:nth-child(odd).shaded {
background-color: var(--light-color);
}
 
tr:nth-child(even).shaded {
background: white;
}
 
th {
color: white;
background-color: var(--dark-color);
font-style: italic;
font-size: small;
text-shadow: 1px 1px 2px #000000;
text-align: left;
white-space: nowrap;
}
 
td {
color: var(--dark-color);
font-size: x-small;
text-align: left;
}
 
td.mvp {
font-size: small;
}
 
td.filters .filters {
background-color: var(--medium-color);
}
 
 
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
 
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
 
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
 
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 2px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
 
input:checked + .slider {
background-color: #2196F3;
}
 
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
 
input:checked + .slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
 
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
 
.slider.round:before {
border-radius: 50%;
}
 
.pagebreak { page-break-after: always; }
Property changes:
Added: svn:executable
+*
\ No newline at end of property