Subversion Repositories ORC

Rev

Rev 9 | Rev 19 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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