| 2 |
- |
1 |
## RollerCon support functions...
|
|
|
2 |
|
|
|
3 |
use strict;
|
|
|
4 |
use Exporter;
|
|
|
5 |
use CGI qw/:standard :netscape/;
|
|
|
6 |
use CGI::Cookie;
|
|
|
7 |
use DBI;
|
| 7 |
- |
8 |
use WebDB;
|
| 2 |
- |
9 |
|
| 7 |
- |
10 |
|
|
|
11 |
my $dbh = WebDB->connect ();
|
| 2 |
- |
12 |
our $ORCUSER;
|
| 7 |
- |
13 |
use constant {
|
|
|
14 |
USER => 1,
|
|
|
15 |
LEAD => 2,
|
|
|
16 |
MANAGER => 3,
|
|
|
17 |
DIRECTOR => 4,
|
|
|
18 |
ADMIN => 5
|
|
|
19 |
};
|
| 2 |
- |
20 |
|
| 7 |
- |
21 |
sub getAccessLevels {
|
|
|
22 |
my %AccessLevels = (
|
|
|
23 |
-1 => "Locked",
|
|
|
24 |
|
|
|
25 |
1 => "Volunteer",
|
|
|
26 |
2 => "Lead",
|
|
|
27 |
3 => "Manager",
|
|
|
28 |
4 => "Director",
|
|
|
29 |
5 => "SysAdmin"
|
|
|
30 |
);
|
|
|
31 |
return \%AccessLevels;
|
|
|
32 |
}
|
|
|
33 |
|
| 2 |
- |
34 |
sub authDB {
|
|
|
35 |
my $src = shift;
|
|
|
36 |
my $id = shift;
|
|
|
37 |
my $pass = shift;
|
|
|
38 |
my $level = shift;
|
|
|
39 |
my ($result, $encpass);
|
|
|
40 |
|
|
|
41 |
my $sth = $dbh->prepare("select * from official where email = ?");
|
|
|
42 |
$sth->execute($id);
|
|
|
43 |
my $RCDBIDHASH = $sth->fetchrow_hashref();
|
|
|
44 |
|
|
|
45 |
if ($src eq "form") {
|
|
|
46 |
my $pwdhan = $dbh->prepare("select password(?)");
|
|
|
47 |
$pwdhan->execute($pass);
|
|
|
48 |
($encpass) = $pwdhan->fetchrow();
|
|
|
49 |
} else {
|
|
|
50 |
$encpass = $pass;
|
|
|
51 |
}
|
|
|
52 |
|
|
|
53 |
if (!$RCDBIDHASH) {
|
|
|
54 |
$result->{ERRMSG} = "User-ID/Email Address not found!";
|
|
|
55 |
$result->{cookie_string} = '';
|
|
|
56 |
$result->{RCid} = '';
|
|
|
57 |
logit(0, "Account not found: $id");
|
|
|
58 |
$result->{authenticated} = 'false';
|
|
|
59 |
} elsif ($RCDBIDHASH->{'password'} ne $encpass) {
|
|
|
60 |
$result->{ERRMSG} = "Incorrect Password!";
|
|
|
61 |
$result->{cookie_string} = '';
|
|
|
62 |
$result->{RCid} = $RCDBIDHASH->{'RCid'};
|
|
|
63 |
logit($RCDBIDHASH->{'RCid'}, "Incorrect Password");
|
|
|
64 |
$result->{authenticated} = 'false';
|
| 7 |
- |
65 |
} elsif (max ($RCDBIDHASH->{'access'}, values %{convertDepartments ($RCDBIDHASH->{department})}) < $level) {
|
|
|
66 |
if (getSetting ("MAINTENANCE")) {
|
|
|
67 |
$result->{ERRMSG} = "MAINTENANCE MODE: Logins are temporarily disabled.";
|
|
|
68 |
} else {
|
|
|
69 |
$result->{ERRMSG} = "Your account either needs to be activated, or doesn't have access to this page!";
|
|
|
70 |
logit($RCDBIDHASH->{'RCid'}, "Insufficient Privileges");
|
|
|
71 |
}
|
| 2 |
- |
72 |
$result->{cookie_string} = "${id}&${encpass}&$RCDBIDHASH->{'access'}";
|
|
|
73 |
$result->{RCid} = $RCDBIDHASH->{'RCid'};
|
|
|
74 |
$result->{authenticated} = 'false';
|
|
|
75 |
} else {
|
|
|
76 |
$result->{ERRMSG} = '';
|
| 7 |
- |
77 |
$RCDBIDHASH->{department} = convertDepartments ($RCDBIDHASH->{department});
|
|
|
78 |
$RCDBIDHASH->{'access'} = max ($RCDBIDHASH->{'access'}, values %{$RCDBIDHASH->{department}});
|
| 2 |
- |
79 |
$result->{cookie_string} = "${id}&${encpass}&$RCDBIDHASH->{'access'}";
|
|
|
80 |
$result->{RCid} = $RCDBIDHASH->{'RCid'};
|
|
|
81 |
logit($RCDBIDHASH->{'RCid'}, "Logged In") if $src eq "form";
|
| 7 |
- |
82 |
$dbh->do ("update official set last_login = now() where RCid = ?", undef, $RCDBIDHASH->{'RCid'}) if $src eq "form";
|
| 2 |
- |
83 |
$result->{authenticated} = 'true';
|
| 7 |
- |
84 |
# my @depts = map { s/-\d// } split /:/, $RCDBIDHASH->{department};
|
|
|
85 |
# my @depts = split /:/, $RCDBIDHASH->{department};
|
|
|
86 |
|
| 2 |
- |
87 |
$ORCUSER=$RCDBIDHASH;
|
|
|
88 |
}
|
|
|
89 |
return $result;
|
|
|
90 |
}
|
|
|
91 |
|
| 7 |
- |
92 |
sub max {
|
|
|
93 |
my ($max, $next, @vars) = @_;
|
|
|
94 |
return $max if not $next;
|
|
|
95 |
return max( $max > $next ? $max : $next, @vars );
|
|
|
96 |
}
|
|
|
97 |
|
| 2 |
- |
98 |
sub authenticate { # Verifies the user has logged in or puts up a log in screen
|
| 7 |
- |
99 |
my $MAINTMODE = getSetting ("MAINTENANCE");
|
|
|
100 |
my $MINLEVEL = $MAINTMODE ? $MAINTMODE : shift // 1;
|
|
|
101 |
|
| 2 |
- |
102 |
my ($ERRMSG, $authenticated, %FORM);
|
|
|
103 |
my $sth = $dbh->prepare("select * from official where email = '?'");
|
|
|
104 |
|
|
|
105 |
my $query = new CGI;
|
| 7 |
- |
106 |
# Check to see if the user has already logged in (there should be cookies with their authentication)?
|
|
|
107 |
my $RCAUTH = $query->cookie('RCAUTH');
|
| 2 |
- |
108 |
$FORM{'ID'} = $query->param('id') || '';
|
|
|
109 |
$FORM{'PASS'} = $query->param('pass') || '';
|
|
|
110 |
$FORM{'SUB'} = $query->param('login') || '';
|
|
|
111 |
|
|
|
112 |
if ($FORM{'SUB'}) {
|
|
|
113 |
#a log in form was submited
|
|
|
114 |
if ($FORM{'SUB'} eq "Submit") {
|
|
|
115 |
$authenticated = authDB('form', $FORM{'ID'}, $FORM{'PASS'}, $MINLEVEL);
|
|
|
116 |
} elsif ($FORM{'SUB'} eq "New User") {
|
|
|
117 |
# Print the new user form and exit
|
|
|
118 |
}
|
|
|
119 |
} elsif ($RCAUTH) {
|
|
|
120 |
#We have an authenication cookie. Double-check it
|
|
|
121 |
my ($RCID, $RCPASS, $RCLVL) = split /&/, $RCAUTH;
|
|
|
122 |
$authenticated = authDB('cookie', $RCID, $RCPASS, $MINLEVEL);
|
|
|
123 |
} else {
|
|
|
124 |
$authenticated->{authenticated} = 'false';
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
|
|
|
128 |
if ($authenticated->{authenticated} eq 'true') {
|
|
|
129 |
return $authenticated->{cookie_string};
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
|
134 |
# If we get here, the user has failed authentication; throw up the log-in screen and die.
|
|
|
135 |
|
|
|
136 |
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"",-expires=>"now");
|
|
|
137 |
|
|
|
138 |
if ($authenticated->{ERRMSG}) {
|
|
|
139 |
$authenticated->{ERRMSG} = "<TR><TD colspan=2 align=center><font color=red><b>".$authenticated->{ERRMSG}."</b></font> </TD></TR>";
|
|
|
140 |
# Log the failed access attempt
|
|
|
141 |
} else {
|
|
|
142 |
$authenticated->{ERRMSG} = "";
|
|
|
143 |
# Since there was no ERRMSG, no need to log anything.
|
|
|
144 |
}
|
|
|
145 |
|
|
|
146 |
print header(-cookie=>$RCAUTH_cookie);
|
|
|
147 |
printRCHeader("Please Sign In");
|
|
|
148 |
print<<authpage;
|
|
|
149 |
<form action="$ENV{REQUEST_URI}" method=POST name=Req id=Req>
|
|
|
150 |
<TR><TD colspan=2 align=center><b><font size=+2>Please Sign In</font>
|
| 7 |
- |
151 |
<TABLE>
|
| 2 |
- |
152 |
</TD></TR>
|
|
|
153 |
<TR><TD colspan=2> </TD></TR>
|
|
|
154 |
$authenticated->{ERRMSG}
|
|
|
155 |
<TR>
|
| 7 |
- |
156 |
<TD align=right><B>User ID:</TD><TD><INPUT type=text id=login name=id></TD>
|
| 2 |
- |
157 |
</TR>
|
|
|
158 |
<TR>
|
|
|
159 |
<TD align=right><B>Password:</TD><TD><INPUT type=password name=pass></TD>
|
|
|
160 |
</TR>
|
|
|
161 |
<TR><TD></TD><TD><INPUT type=submit name=login value=Submit></TD></TR>
|
|
|
162 |
<TR><TD colspan=2 align=center> </TD></TR>
|
|
|
163 |
<TR><TD colspan=2 align=center><A HREF="/schedule/manage_user.pl?submit=New%20User">[register as a new user]</A></TD></TR>
|
|
|
164 |
<TR><TD colspan=2 align=center><A HREF="/schedule/password_reset.pl">[reset your password]</A></TD></TR>
|
|
|
165 |
</TABLE>
|
|
|
166 |
</FORM>
|
|
|
167 |
|
|
|
168 |
<SCRIPT language="JavaScript">
|
|
|
169 |
<!--
|
| 7 |
- |
170 |
document.getElementById("login").focus();
|
| 2 |
- |
171 |
|
|
|
172 |
function Login () {
|
|
|
173 |
document.getElementById('Req').action = "$ENV{SCRIPT_NAME}";
|
|
|
174 |
document.getElementById('Req').submit.click();
|
|
|
175 |
return true;
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
//-->
|
|
|
180 |
</SCRIPT>
|
|
|
181 |
|
|
|
182 |
authpage
|
|
|
183 |
|
|
|
184 |
#foreach (keys %ENV) {
|
|
|
185 |
# print "$_: $ENV{$_}<br>";
|
|
|
186 |
#}
|
|
|
187 |
# &JScript;
|
|
|
188 |
exit;
|
|
|
189 |
}
|
|
|
190 |
|
| 7 |
- |
191 |
sub getShiftDepartment {
|
|
|
192 |
my $shiftID = shift // "";
|
|
|
193 |
my $dept;
|
|
|
194 |
|
|
|
195 |
if ($shiftID =~ /^\d+$/) {
|
|
|
196 |
($dept) = $dbh->selectrow_array ("select dept from shift where id = ?", undef, $shiftID);
|
|
|
197 |
} elsif ($shiftID =~ /^\d+-ANN/) {
|
|
|
198 |
$dept = "ANN";
|
|
|
199 |
} else {
|
|
|
200 |
$dept = "OFF";
|
|
|
201 |
}
|
|
|
202 |
|
|
|
203 |
return $dept;
|
|
|
204 |
}
|
|
|
205 |
|
|
|
206 |
sub getDepartments {
|
|
|
207 |
my $RCid = shift // "";
|
|
|
208 |
# If we get an RCid, return the list of departments and levels for that user.
|
|
|
209 |
# Otherwise (no parameter), return the list of departments with their display names.
|
|
|
210 |
|
|
|
211 |
if ($RCid) {
|
|
|
212 |
my $sth = $dbh->prepare("select department from official where RCid = ?");
|
|
|
213 |
$sth->execute($RCid);
|
|
|
214 |
my ($dlist) = $sth->fetchrow;
|
|
|
215 |
return convertDepartments ($dlist);
|
|
|
216 |
} else {
|
|
|
217 |
my %HASH;
|
|
|
218 |
my $sth = $dbh->prepare("select TLA, name from department");
|
|
|
219 |
$sth->execute();
|
|
|
220 |
while (my ($tla, $name) = $sth->fetchrow) {
|
|
|
221 |
$HASH{$tla} = $name;
|
|
|
222 |
}
|
|
|
223 |
return \%HASH;
|
|
|
224 |
}
|
|
|
225 |
|
|
|
226 |
}
|
|
|
227 |
|
|
|
228 |
sub convertDepartments {
|
|
|
229 |
# For the department membership, converts the DB string back and forth to a hashref...
|
|
|
230 |
my $input = shift // "";
|
|
|
231 |
my $output;
|
|
|
232 |
|
|
|
233 |
if (ref $input eq "HASH") {
|
|
|
234 |
$output = join ":", map { $_."-".$input->{$_} } sort keys %{$input};
|
|
|
235 |
} else {
|
|
|
236 |
foreach (split /:/, $input) {
|
|
|
237 |
my ($tla, $level) = split /-/;
|
|
|
238 |
$output->{$tla} = $level;
|
|
|
239 |
}
|
|
|
240 |
}
|
|
|
241 |
|
|
|
242 |
return $output;
|
|
|
243 |
}
|
|
|
244 |
|
|
|
245 |
sub getSchedule {
|
|
|
246 |
my $RCid = shift // return "ERROR: No RCid provided to getSchedule";
|
|
|
247 |
my $filter = shift // "";
|
|
|
248 |
|
|
|
249 |
my @whereclause;
|
|
|
250 |
push @whereclause, "date >= date(now())" unless $filter eq "all";
|
|
|
251 |
# if ($RCid ne $ORCUSER->{RCid}) {
|
|
|
252 |
# push @whereclause, "dept != 'PER'";
|
|
|
253 |
# }
|
|
|
254 |
|
|
|
255 |
use DateTime;
|
|
|
256 |
my $dt = DateTime->today;
|
|
|
257 |
$dt =~ s/T00\:00\:00$//;
|
|
|
258 |
my $now = DateTime->now;
|
|
|
259 |
|
|
|
260 |
|
|
|
261 |
use HTML::Tiny;
|
|
|
262 |
my $h = HTML::Tiny->new( mode => 'html' );
|
|
|
263 |
|
|
|
264 |
my $where = scalar @whereclause ? "where ".join " and ", @whereclause : "";
|
|
|
265 |
my @shifts;
|
|
|
266 |
my $sth = $dbh->prepare("select * from (select id, date, dayofweek, track as location, time, role, teams, gtype, 'OFF' as dept, volhours from v_shift_officiating where RCid = ? union
|
|
|
267 |
select id, date, dayofweek, track as location, time, role, teams, gtype, 'ANN' as dept, volhours from v_shift_announcer where RCid = ? union
|
|
|
268 |
select id, date, dayofweek, location, time, role, '' as teams, type as gtype, dept, volhours from v_shift where RCid = ?) temp
|
|
|
269 |
$where order by date, time");
|
|
|
270 |
$sth->execute($RCid, $RCid, $RCid);
|
|
|
271 |
my $hours;
|
|
|
272 |
while (my $s = $sth->fetchrow_hashref) {
|
|
|
273 |
my ($yyyy, $mm, $dd) = split /\-/, $s->{date};
|
|
|
274 |
my $cutoff = DateTime->new(
|
|
|
275 |
year => $yyyy,
|
|
|
276 |
month => $mm,
|
|
|
277 |
day => $dd,
|
|
|
278 |
hour => 5,
|
|
|
279 |
minute => 0,
|
|
|
280 |
second => 0,
|
|
|
281 |
time_zone => 'America/Los_Angeles'
|
|
|
282 |
);
|
|
|
283 |
|
|
|
284 |
|
|
|
285 |
if (!$s->{teams}) {
|
|
|
286 |
# it's a time-based shift
|
|
|
287 |
if ($s->{dept} eq "PER") {
|
|
|
288 |
if ($RCid eq $ORCUSER->{RCid}) {
|
|
|
289 |
# DROP
|
|
|
290 |
$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")." ".$h->button ({ onClick=>"location.href='manage_personal_time.pl?choice=Update&id=$s->{id}'" }, "EDIT");
|
|
|
291 |
} else {
|
|
|
292 |
$s->{location} = "";
|
|
|
293 |
$s->{role} = "";
|
|
|
294 |
}
|
|
|
295 |
} elsif (($RCid == $ORCUSER->{RCid} and $s->{gtype} !~ /^selected/ and $now < $cutoff) or ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5)) {
|
|
|
296 |
# DROP
|
|
|
297 |
$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");
|
|
|
298 |
if ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5) {
|
|
|
299 |
# NO SHOW
|
|
|
300 |
$s->{buttons} .= " ".$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");
|
|
|
301 |
}
|
|
|
302 |
$hours += $s->{volhours};
|
|
|
303 |
}
|
|
|
304 |
|
|
|
305 |
} elsif (($RCid == $ORCUSER->{RCid} and $s->{gtype} !~ /^selected/ and $now < $cutoff) or ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5)) {
|
|
|
306 |
# it's a game shift
|
|
|
307 |
#DROP
|
|
|
308 |
$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");
|
|
|
309 |
if ($ORCUSER->{department}->{$s->{dept}} >= 2 or $ORCUSER->{access} >= 5) {
|
|
|
310 |
# NO SHOW
|
|
|
311 |
$s->{buttons} .= " ".$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");
|
|
|
312 |
}
|
|
|
313 |
$hours += $s->{volhours};
|
|
|
314 |
}
|
|
|
315 |
$s->{role} =~ s/\-\d$//;
|
|
|
316 |
|
|
|
317 |
push @shifts, $h->li ({ class=> $s->{date} eq $dt ? "nowrap highlighted" : "nowrap shaded" }, join ' ', $s->{date}, $s->{dayofweek}, $s->{time}, $s->{location}, getDepartments()->{$s->{dept}}, $s->{role}, $s->{teams}, $s->{buttons});
|
|
|
318 |
}
|
|
|
319 |
|
|
|
320 |
if (scalar @shifts) {
|
|
|
321 |
return $h->ul ([ @shifts, $h->h5 ("Currently showing $hours hours of Volunteer Time.") ]);
|
|
|
322 |
} else {
|
|
|
323 |
return $h->p ({ class=>"hint" }, "[nothing scheduled at the moment]");
|
|
|
324 |
}
|
|
|
325 |
}
|
|
|
326 |
|
| 2 |
- |
327 |
sub getSetting {
|
|
|
328 |
my $k = shift;
|
|
|
329 |
my $sth = $dbh->prepare("select setting.value from setting where setting.key = ?");
|
|
|
330 |
$sth->execute($k);
|
|
|
331 |
return $sth->fetchrow_hashref()->{value};
|
|
|
332 |
}
|
|
|
333 |
|
|
|
334 |
sub getUser {
|
| 7 |
- |
335 |
my $ID = shift;
|
|
|
336 |
|
|
|
337 |
my $sth;
|
|
|
338 |
if ($ID =~ /^\d+$/) {
|
|
|
339 |
$sth = $dbh->prepare("select * from official where RCid = ?");
|
|
|
340 |
} else {
|
|
|
341 |
$sth = $dbh->prepare("select * from official where email = ?");
|
|
|
342 |
}
|
|
|
343 |
$sth->execute($ID);
|
|
|
344 |
return $sth->fetchrow_hashref;
|
| 2 |
- |
345 |
}
|
|
|
346 |
|
|
|
347 |
sub getUserEmail {
|
|
|
348 |
my $RCid = shift;
|
|
|
349 |
my $sth = $dbh->prepare("select email from official where RCid = ?");
|
|
|
350 |
$sth->execute($RCid);
|
|
|
351 |
my ($email) = $sth->fetchrow_array();
|
|
|
352 |
return $email;
|
|
|
353 |
}
|
|
|
354 |
|
|
|
355 |
sub getUserDerbyName {
|
|
|
356 |
my $RCid = shift;
|
|
|
357 |
my $sth = $dbh->prepare("select derby_name from official where RCid = ?");
|
|
|
358 |
$sth->execute($RCid);
|
|
|
359 |
my ($dname) = $sth->fetchrow_array();
|
|
|
360 |
return $dname;
|
|
|
361 |
}
|
|
|
362 |
|
|
|
363 |
sub getYears {
|
| 7 |
- |
364 |
# my $sth = $dbh->prepare("select distinct year(date) from v_shift_admin_view union select year(now())");
|
|
|
365 |
my $sth = $dbh->prepare("select distinct year(date) from v_shift_admin_view");
|
| 2 |
- |
366 |
$sth->execute();
|
|
|
367 |
my @years;
|
|
|
368 |
while (my ($y) =$sth->fetchrow_array()) { push @years, $y; }
|
|
|
369 |
return \@years;
|
|
|
370 |
}
|
|
|
371 |
|
|
|
372 |
sub printRCHeader {
|
|
|
373 |
my $PAGE_TITLE = shift;
|
| 7 |
- |
374 |
use CGI qw/start_html/;
|
|
|
375 |
use HTML::Tiny;
|
|
|
376 |
my $h = HTML::Tiny->new( mode => 'html' );
|
| 2 |
- |
377 |
|
| 7 |
- |
378 |
# 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]");
|
|
|
379 |
my $logout = $h->button ({ onClick=>"document.cookie = 'RCAUTH=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'; location.href='/';" }, "Log Out");
|
|
|
380 |
my $loggedinas = $ORCUSER ? "Currently logged in as: ".$h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$ORCUSER->{RCid}" }, $ORCUSER->{derby_name})." $logout" : "";
|
|
|
381 |
|
|
|
382 |
print start_html (-title=>"vORC - $PAGE_TITLE", -style => {'src' => "/style.css"} );
|
|
|
383 |
|
|
|
384 |
#<html><head><title>Officials' RollerCon Schedule Manager - $PAGE_TITLE</title>
|
|
|
385 |
#<link rel="stylesheet" type="text/css" href="/style.css">
|
|
|
386 |
#</head>
|
|
|
387 |
#<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
|
|
388 |
print $h->div ({ class=>"sp0" }, [ $h->div ({ class=>"spLeft" }, $h->a ({ href=>"/schedule/" }, $h->img ({ src=>"/logo.jpg", width=>"75", height=>"75" }))),
|
|
|
389 |
$h->div ({ class=>"spRight" }, [ $h->h1 (["vORC $PAGE_TITLE", $h->br]),
|
|
|
390 |
$loggedinas,
|
|
|
391 |
])
|
|
|
392 |
]);
|
|
|
393 |
#print<<rcheader;
|
|
|
394 |
# <TABLE>
|
|
|
395 |
# <TR class="nostripe">
|
|
|
396 |
# <TD align=right><img SRC="/logo.jpg"></TD>
|
|
|
397 |
# <TD align=center valign=middle><b><font size=+3>Officials' RollerCon<br>Schedule Manager<br>$PAGE_TITLE</FONT></b>
|
|
|
398 |
# <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>
|
|
|
399 |
# </TR>
|
| 2 |
- |
400 |
|
| 7 |
- |
401 |
#rcheader
|
| 2 |
- |
402 |
}
|
|
|
403 |
|
|
|
404 |
sub changeShift {
|
| 7 |
- |
405 |
my ($change, $shift_id, $role, $user_id) = @_;
|
|
|
406 |
my $leadership_change = 0;
|
|
|
407 |
my $department = getShiftDepartment ($role ? $shift_id."-".$role : $shift_id);
|
|
|
408 |
my $game_based = $role ? "game" : "shift";
|
|
|
409 |
my $sth;
|
| 2 |
- |
410 |
|
| 7 |
- |
411 |
if ($change eq "add") {
|
|
|
412 |
my $taken;
|
|
|
413 |
if ($game_based eq "game") {
|
|
|
414 |
($taken) = $dbh->selectrow_array ("select count(*) from assignment where Gid = ? and role = ?", undef, $shift_id, $role);
|
|
|
415 |
} else {
|
|
|
416 |
($taken) = $dbh->selectrow_array ("select count(*) from shift where id = ? and isnull(assignee_id) = 0", undef, $shift_id);
|
|
|
417 |
}
|
|
|
418 |
if ($taken) {
|
|
|
419 |
return "<br>Denied! This shift is already taken ($shift_id).<br>\n";
|
|
|
420 |
}
|
|
|
421 |
}
|
| 2 |
- |
422 |
|
| 7 |
- |
423 |
if (lc ($user_id) ne lc ($ORCUSER->{RCid})) { # they're changing someone else's schedule...
|
|
|
424 |
if ($ORCUSER->{department}->{$department} >= 2 or $ORCUSER->{access} >= 5) {
|
|
|
425 |
# the user making the change is either a lead in the dept or a sysadmin
|
|
|
426 |
logit ($ORCUSER->{RCid}, "$ORCUSER->{derby_name} changed someone else's schedule. ($change, $shift_id, $role, $user_id)");
|
|
|
427 |
logit ($user_id, "Schedule was changed by $ORCUSER->{derby_name}. ($change, $shift_id, $role, $user_id)");
|
|
|
428 |
$leadership_change = 1;
|
| 2 |
- |
429 |
} else {
|
| 7 |
- |
430 |
logit ($ORCUSER->{RCid}, "Unauthorized attempt to change someone else's schedule. ($change, $shift_id, $role, $user_id)");
|
|
|
431 |
return "<br>Denied! You are not authorized to change someone else's schedule in this department ($department).<br>\n";
|
| 2 |
- |
432 |
}
|
| 7 |
- |
433 |
} elsif ($ORCUSER->{department}->{$department} >= 3) {
|
|
|
434 |
# Managers can sign up for as many shifts within their own department as they like...
|
|
|
435 |
$leadership_change = 1;
|
| 2 |
- |
436 |
}
|
|
|
437 |
|
| 7 |
- |
438 |
if ($change eq "add" and convertDepartments(getUser($user_id)->{department})->{$department} < 1) {
|
|
|
439 |
return "<br>Denied! User ($user_id) is not a member of Department ($department)!<br>\n";
|
|
|
440 |
}
|
|
|
441 |
|
|
|
442 |
if ($change eq "add" and findConflict ($user_id, $shift_id, $game_based)) {
|
|
|
443 |
return "<br>Denied! There is a conflict with that shift's time!<br>\n";
|
|
|
444 |
}
|
|
|
445 |
|
|
|
446 |
my ($game_type) = $dbh->selectrow_array ("select type from ".$game_based." where id = ?", undef, $shift_id);
|
|
|
447 |
if ($game_type =~ /^selected/ and !$leadership_change) {
|
|
|
448 |
return "<br>Denied! Only leadership can make changes to 'selected staffing' shifts!<br>\n";
|
|
|
449 |
}
|
|
|
450 |
|
|
|
451 |
if ($change eq "add" and $game_type eq "lead" and convertDepartments(getUser($user_id)->{department})->{$department} < 2 and $ORCUSER->{access} < 3) {
|
|
|
452 |
return "<br>Denied! Shift reserved for leadership staff!<br>\n";
|
|
|
453 |
}
|
|
|
454 |
|
|
|
455 |
my $MAXSHIFTS = getSetting ("MAX_SHIFT_SIGNUP_PER_DAY");
|
|
|
456 |
my $daily_count = signUpCount ('get', $user_id);
|
|
|
457 |
if ($change eq "add" and $daily_count >= $MAXSHIFTS and !$leadership_change) {
|
|
|
458 |
return "<br>Denied! You may only sign up for $MAXSHIFTS $game_type shifts in one day!<br>\n";
|
|
|
459 |
}
|
|
|
460 |
|
|
|
461 |
my @DBARGS;
|
|
|
462 |
if ($game_based eq "game") {
|
|
|
463 |
if ($change eq "add") {
|
|
|
464 |
$sth = $dbh->prepare("insert into assignment (Gid, role, RCid) values (?, ?, ?)");
|
|
|
465 |
} elsif ($change eq "del") {
|
|
|
466 |
$sth = $dbh->prepare("delete from assignment where Gid = ? and role = ? and RCid= ?");
|
|
|
467 |
}
|
|
|
468 |
@DBARGS = ($shift_id, $role, $user_id);
|
|
|
469 |
} else {
|
|
|
470 |
if ($change eq "add") {
|
|
|
471 |
$sth = $dbh->prepare("update shift set assignee_id = ? where id = ?");
|
|
|
472 |
@DBARGS = ($user_id, $shift_id);
|
|
|
473 |
} elsif ($change eq "del") {
|
|
|
474 |
$sth = $dbh->prepare("update shift set assignee_id = null where id = ?");
|
|
|
475 |
@DBARGS = ($shift_id);
|
|
|
476 |
}
|
|
|
477 |
}
|
|
|
478 |
|
|
|
479 |
print "<br>attempting to make DB changes...<br>";
|
|
|
480 |
if ($sth->execute (@DBARGS)) {
|
|
|
481 |
$daily_count = signUpCount ($change, $user_id) unless $leadership_change;
|
|
|
482 |
logit ($user_id, "Shift ".ucfirst($change).": $shift_id -> $role");
|
|
|
483 |
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";
|
|
|
484 |
return;
|
|
|
485 |
} else {
|
|
|
486 |
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();
|
|
|
487 |
}
|
|
|
488 |
}
|
|
|
489 |
|
|
|
490 |
sub modShiftTime {
|
|
|
491 |
my ($shift_id, $user_id, $diff) = @_;
|
|
|
492 |
my $ORCUSER = getUser (1);
|
| 2 |
- |
493 |
|
| 7 |
- |
494 |
use Scalar::Util qw(looks_like_number);
|
|
|
495 |
if (!looks_like_number ($diff)) {
|
|
|
496 |
print "<br>ERROR! The time adjustment ($diff) doesn't look like a number.<br>\n";
|
|
|
497 |
return;
|
| 2 |
- |
498 |
}
|
|
|
499 |
|
| 7 |
- |
500 |
my ($validate_assignee) = $dbh->selectrow_array ("select count(*) from v_shift where id = ? and RCid = ?", undef, $shift_id, $user_id);
|
|
|
501 |
if (!$validate_assignee) {
|
|
|
502 |
print "<br>ERROR! This shift is assigned to someone else.<br>\n";
|
|
|
503 |
return;
|
|
|
504 |
}
|
|
|
505 |
|
|
|
506 |
my $department = getShiftDepartment ($shift_id);
|
|
|
507 |
if (convertDepartments ($ORCUSER->{department})->{$department} < 2 and $ORCUSER->{access} < 5) {
|
|
|
508 |
print "<br>ERROR! You're not authorized to modify this shift's time.<br>\n";
|
|
|
509 |
logit ($ORCUSER->{RCid}, "Unauthorized attempt to modify shift time. ($department, $shift_id)");
|
|
|
510 |
return;
|
|
|
511 |
}
|
|
|
512 |
|
|
|
513 |
my $rows_changed;
|
|
|
514 |
print "<br>attempting to make DB changes...<br>";
|
|
|
515 |
if ($diff == 0) {
|
|
|
516 |
$rows_changed = $dbh->do ("update shift set mod_time = null where id = ? and assignee_id = ?", undef, $shift_id, $user_id);
|
|
|
517 |
} else {
|
|
|
518 |
$rows_changed = $dbh->do ("update shift set mod_time = ? where id = ? and assignee_id = ?", undef, $diff, $shift_id, $user_id);
|
|
|
519 |
}
|
|
|
520 |
|
|
|
521 |
|
|
|
522 |
if (!$rows_changed or $dbh->errstr) {
|
|
|
523 |
print "ERROR: Nothing got updated".$dbh->errstr;
|
|
|
524 |
logit (0, "ERROR modifying a shift time ($diff, $shift_id, $user_id):".$dbh->errstr);
|
|
|
525 |
} else {
|
|
|
526 |
print "SUCCESS: Shift $shift_id succesfully modified by $diff hour(s)";
|
|
|
527 |
logit ($ORCUSER->{RCid}, "SUCCESS: Shift $shift_id succesfully modified by $diff hour(s)");
|
|
|
528 |
|
|
|
529 |
}
|
|
|
530 |
return;
|
| 2 |
- |
531 |
}
|
|
|
532 |
|
|
|
533 |
sub signUpCount {
|
|
|
534 |
my $action = shift;
|
|
|
535 |
my $id = shift;
|
|
|
536 |
my $gtype = shift // "";
|
|
|
537 |
|
| 7 |
- |
538 |
if ($id eq $ORCUSER->{RCid}) {
|
| 2 |
- |
539 |
if ($action eq 'add') {
|
| 7 |
- |
540 |
if (signUpCount ('get', $id)) {
|
|
|
541 |
$dbh->do("update sign_up_count set sign_ups = sign_ups + 1 where date = curdate() and RCid = ?", undef, $id);
|
| 2 |
- |
542 |
} else {
|
| 7 |
- |
543 |
$dbh->do("replace into sign_up_count values (curdate(), ?, 1)", undef, $id);
|
| 2 |
- |
544 |
}
|
|
|
545 |
} elsif ($action eq 'del') {
|
| 7 |
- |
546 |
if (signUpCount ('get', $id)) {
|
|
|
547 |
$dbh->do("update sign_up_count set sign_ups = sign_ups - 1 where date = curdate() and RCid = ?", undef, $id);
|
| 2 |
- |
548 |
}
|
|
|
549 |
}
|
|
|
550 |
}
|
|
|
551 |
|
| 7 |
- |
552 |
my ($R) = $dbh->selectrow_array ("select sign_ups from sign_up_count where RCid = ? and date = curdate()", undef, $id);
|
| 2 |
- |
553 |
|
|
|
554 |
return $R ? $R : '0';
|
|
|
555 |
}
|
|
|
556 |
|
|
|
557 |
sub signUpEligible {
|
|
|
558 |
my $user = shift;
|
|
|
559 |
my $t = shift;
|
| 7 |
- |
560 |
my $shifttype = shift // "game";
|
| 2 |
- |
561 |
|
| 7 |
- |
562 |
if (findConflict ($user->{RCid}, $t->{id}, $shifttype)) { return 0; }
|
|
|
563 |
|
| 2 |
- |
564 |
if (!exists $user->{sign_ups_today}) {
|
|
|
565 |
$user->{sign_ups_today} = signUpCount('get', $user->{RCid});
|
|
|
566 |
}
|
|
|
567 |
|
| 7 |
- |
568 |
if ($shifttype eq "game") {
|
|
|
569 |
if ($t->{gtype} !~ /^selected/ and $t->{gtype} ne "short track" and $user->{sign_ups_today} < getSetting("MAX_SHIFT_SIGNUP_PER_DAY")) {
|
| 2 |
- |
570 |
return 1;
|
|
|
571 |
} else {
|
|
|
572 |
return 0;
|
|
|
573 |
}
|
| 7 |
- |
574 |
} else {
|
|
|
575 |
if ($user->{department}->{$t->{dept}} < 1) { return 0; }
|
|
|
576 |
if ($t->{type} eq "lead" and $user->{department}->{$t->{dept}} < 2) { return 0; }
|
|
|
577 |
if ($t->{type} eq "manager" and $user->{department}->{$t->{dept}} < 3) { return 0; }
|
|
|
578 |
if ($t->{type} !~ /^selected/ and $user->{sign_ups_today} < getSetting("MAX_SHIFT_SIGNUP_PER_DAY")) {
|
| 2 |
- |
579 |
return 1;
|
|
|
580 |
} else {
|
|
|
581 |
return 0;
|
|
|
582 |
}
|
|
|
583 |
}
|
|
|
584 |
}
|
|
|
585 |
|
|
|
586 |
sub findConflict {
|
|
|
587 |
my $rcid = shift;
|
|
|
588 |
my $gid = shift;
|
| 7 |
- |
589 |
my $type = shift // "";
|
|
|
590 |
my ($date, $start, $end, $conflicts);
|
| 2 |
- |
591 |
|
| 7 |
- |
592 |
if ($type eq "game") {
|
|
|
593 |
# Are they already signed up for this game? (It's faster to check the two views one at a time...)
|
|
|
594 |
# ($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where substring_index(id, '-', 1) = ? and RCid = ?", undef, $gid, $rcid);
|
|
|
595 |
($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_officiating where id = ? and RCid = ?", undef, $gid, $rcid);
|
|
|
596 |
if ($conflicts) { return 1; } # no need to keep looking...
|
|
|
597 |
($conflicts) = $dbh->selectrow_array ("select count(*) from v_shift_announcer where id = ? and RCid = ?", undef, $gid, $rcid);
|
|
|
598 |
if ($conflicts) { return 1; } # no need to keep looking...
|
|
|
599 |
|
|
|
600 |
($date, $start, $end) = $dbh->selectrow_array ("select distinct date, time, end_time from game where id = ?", undef, $gid);
|
|
|
601 |
} elsif ($type eq "personal") {
|
|
|
602 |
($date, $start, $end) = @{ $gid };
|
|
|
603 |
} else {
|
|
|
604 |
($date, $start, $end) = $dbh->selectrow_array ("select distinct date, start_time, end_time from shift where id = ?", undef, $gid);
|
|
|
605 |
}
|
| 2 |
- |
606 |
|
|
|
607 |
# Are they signed up for any games that would conflict with this one?
|
| 7 |
- |
608 |
# 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 = ?");
|
|
|
609 |
# 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 = ?");
|
| 2 |
- |
610 |
|
| 7 |
- |
611 |
($conflicts) = $dbh->selectrow_array ("select count(*) from (
|
|
|
612 |
select id from v_shift where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? union
|
|
|
613 |
select id from v_shift_announcer where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? union
|
|
|
614 |
select id from v_shift_officiating where date = ? and ((start_time <= ? and end_time > ?) or (start_time > ? and start_time < ?)) and RCid = ? ) alltables",
|
|
|
615 |
undef, $date, $start, $start, $start, $end, $rcid, $date, $start, $start, $start, $end, $rcid, $date, $start, $start, $start, $end, $rcid
|
|
|
616 |
);
|
|
|
617 |
|
| 2 |
- |
618 |
return $conflicts;
|
|
|
619 |
}
|
|
|
620 |
|
|
|
621 |
sub changeLeadShift {
|
|
|
622 |
my ($change, $lshift, $user_id) = @_;
|
|
|
623 |
my $ERRMSG;
|
|
|
624 |
|
|
|
625 |
my $sth = $dbh->prepare("update lead_shift set assignee_id = ? where id = ?");
|
|
|
626 |
|
|
|
627 |
print "<br>attempting to make DB changes...<br>";
|
|
|
628 |
if ($change eq "add") {
|
|
|
629 |
$sth->execute($user_id, $lshift)
|
|
|
630 |
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
|
|
|
631 |
} elsif ($change eq "del") {
|
|
|
632 |
$sth->execute('', $lshift)
|
|
|
633 |
or $ERRMSG = "ERROR: Can't execute SQL statement: ".$sth->errstr()."\n";
|
|
|
634 |
}
|
|
|
635 |
if ($ERRMSG) {
|
|
|
636 |
print $ERRMSG;
|
|
|
637 |
} else {
|
|
|
638 |
logit($user_id, "Lead Shift ".ucfirst($change).": $lshift");
|
|
|
639 |
print "Success.<br>";
|
|
|
640 |
}
|
|
|
641 |
}
|
|
|
642 |
|
|
|
643 |
sub logit {
|
|
|
644 |
my $RCid = shift;
|
|
|
645 |
my $msg = shift;
|
|
|
646 |
my $sth = $dbh->prepare("insert into log (RCid, event) values (?, ?)");
|
|
|
647 |
$sth->execute($RCid, $msg);
|
|
|
648 |
}
|
|
|
649 |
|
|
|
650 |
1;
|