Subversion Repositories VORC

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
35 - 1
#!/usr/bin/perl
2
 
3
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
4
 
5
#use strict;
6
use cPanelUserConfig;
7
use CGI qw/param cookie header start_html url/;
8
use HTML::Tiny;
9
use tableViewer;
10
use RollerCon;
43 - 11
use DateTime;
12
#use DateTime::Duration;
13
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
35 - 14
our $h = HTML::Tiny->new( mode => 'html' );
15
 
16
my $cookie_string;
17
our ($EML, $PWD, $LVL);
18
my $user;
19
my $username;
20
my $RCid;
21
my $RCAUTH_cookie;
53 bgadell 22
my $YEAR = 1900 + (localtime)[5];
35 - 23
 
24
$cookie_string = authenticate(1) || die;
25
($EML, $PWD, $LVL) = split /&/, $cookie_string;
26
$user = getUser($EML);
27
$username = $h->a ({ href=>"/schedule/manage_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
28
$RCid = $user->{RCid};
29
$RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
30
 
31
if (convertDepartments($user->{department})->{CLA} < 1 and $LVL < 4) {
32
	print header(-cookie=>$RCAUTH_cookie);
33
	printRCHeader("Unauthorized Page");
34
	print $h->div ({ class=>"error" }, "No Access");
35
	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.");
36
	print $h->a ({ href=>"/schedule/" }, "[Go Home]");
37
	print $h->close ("html");
38
	exit;
39
}
40
 
41
 
42
my $pageTitle = "MVP Classes";
43
my $prefscookie = "newmvpclasses";
44
our $DBTABLE = 'v_mvp_class';
45
my %COLUMNS = (
46
# colname   =>  [qw(DisplayName       N    type     status)],   status ->  static | default | <blank>
47
	note				=> [qw(Class         5    text     static )],
48
	date				=> [qw(Date         10    date              )],
49
	dayofweek		=> [qw(Day          15    select    default )],
50
	start_time	=> [qw(StartTime    20    text      )],
51
	end_time		=> [qw(EndTime      25    text       )],
52
	time				=> [qw(Time         30    text      default )],
53
	location		=> [qw(Track        35    select    default )],
54
	role				=> [qw(Coach        40    select    default )],
55
	available		=> [qw(SignUp       45    text      static )]
56
);
57
my $stylesheet = "/style.css";
58
my $homeURL = '/schedule/';
59
my @pagelimitoptions = ("All", 5, 10, 25);
60
 
61
# Set any custom "where" DB filters here...
62
my @whereClause;
63
 
64
# If we need to modify line item values, create a subroutine named "modify_$columnname"
65
#    It will receive a hashref to the object lineitem
66
 
67
#use WebDB;
68
#my $dbh = WebDB::connect;
69
my $dbh = getRCDBH;
70
 
71
sub modify_available {
72
	my $t = shift;
43 - 73
 
74
 	my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
75
	my $cutoff = DateTime->new(
76
        year => $yyyy,
77
        month => $mm,
78
        day => $dd,
79
        hour => 5,
80
        minute => 0,
81
        second => 0,
82
        time_zone => 'America/Los_Angeles'
83
  );
84
 
85
  return "CLOSED" unless $now < $cutoff;
86
 
35 - 87
	($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} );
88
	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]");
89
	if (!$t->{available}) {
90
	  my $full = "FULL";
91
	  $full .= " | ".$droplink unless !$t->{signedup};
92
	  return $full;
93
  }
94
 
95
	my $classkey = join '|', $t->{date}, $t->{start_time}, $t->{location};
96
	$t->{available} .= " Open";
97
  $t->{available} .= " | ".$droplink unless !$t->{signedup};
98
	if (signUpEligible ($ORCUSER, $t, "class")) {
99
		# SIGN UP
100
		$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]");
101
	}
102
	if ($user->{department}->{CLA} >= 2 or $LVL > 4 or $user->{department}->{VCI} >= 2) {
103
		# ADD USER
104
		$t->{available} ? $t->{available} .= " | " : {};
105
		$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]");
106
	}
107
 
108
	return $t->{available};
109
}
110
 
111
sub filter_available {
112
  my $colName = shift;
113
	my $filter = shift;
114
 
115
	if (defined $filter)	{
116
		if ($filter eq "Full") {
117
			return "$colName = 0";
118
		}
119
		return "$colName > 0";
120
	}	else {
121
		my $thing = "filter-${colName}";
122
		my $Options = "<OPTION></OPTION>"."<OPTION>Available</OPTION>"."<OPTION>Full</OPTION>";
123
 
124
		$Options =~ s/>($FORM{$thing})/ selected>$1/;
125
		return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
126
	}
127
}
128
 
50 bgadell 129
sub modify_time {
130
  my $t = shift;
131
  return convertTime $t->{time};
132
}
133
 
134
 
35 - 135
# Ideally, nothing below this comment needs to change
136
#-------------------------------------------------------------------------------
137
 
138
 
139
our %NAME              = map  { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
140
our %colOrderHash      = map  { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
141
our %colFilterTypeHash = map  { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
142
our @staticFields      = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
143
our @defaultFields     = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
144
#our @defaultFields     = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
145
 
146
our @allFields = sort byfield keys %NAME;
147
our @displayFields = ();
148
our @hideFields = ();
149
my $QUERY_STRING;
150
 
151
my $pagelimit = param ("limit") // "All"; #$pagelimitoptions[$#pagelimitoptions];
152
my $curpage = param ("page") // 1;
153
 
154
our %FORM;
155
my $FILTER;
156
foreach (param()) {
52 bgadell 157
 	if (/^year$/) { #
158
		$YEAR = param($_);
159
		next;
160
	}
35 - 161
 
162
	$FORM{$_} = param($_);				# Retrieve all of the FORM data submitted
163
 
164
	if ((/^filter/) and ($FORM{$_} ne '')) {	# Build a set of filters to apply
165
		my ($filter,$field) = split /-/, $_;
166
		$FILTER->{$field} = $FORM{$_};
167
	}	elsif ($FORM{$_} eq "true")	{		# Compile list of fields to display
168
	  if ($_ ne "shiftinclude") {
169
		  push @displayFields, $_;
170
		}
171
	}
172
}
173
 
52 bgadell 174
push @whereClause, "year(date) = '$YEAR'";
35 - 175
 
176
if (exists $FORM{autoload})	{			# If the FORM was submitted (i.e. the page is being redisplayed),
177
							                    #  	build the data for the cookie that remembers the page setup
178
	my $disFields = join ":", @displayFields;
179
	my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
180
 
181
	$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
182
}
183
 
184
 
185
if (!(exists $FORM{autoload}))	{			# No FORM was submitted...
186
	if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie"))	{ # Check for cookies from previous visits.
187
		my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;
188
		@displayFields = split /:/,$disF;
189
 
190
		foreach my $pair (split /:/, $filts)	{
191
			my ($key, $value) = split /=/, $pair;
192
			$FORM{"filter-$key"} = $value;
193
			$FILTER->{$key} = $value;
194
		}
195
 
196
		$FORM{sortby} = $sb;
197
		$FORM{autoload} = $al;
198
		$FORM{shiftinclude} = $si;
199
		$QUERY_STRING = $prefs;
200
	}	else {
201
	  @displayFields = @defaultFields; # Otherwise suppply a default list of columns.
202
	  $FORM{autoload} = 1;             # And turn aut0load on by default.
203
		$FORM{sortby} = "note";
204
	}
205
}
206
 
207
# let's just make sure the columns are in the right order (and there aren't any missing)
208
@displayFields = sort byfield uniq @displayFields, @staticFields;
209
 
210
# If the field isn't in the displayFields list,	then add it to the hideFields list
211
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
212
 
213
# Process any filters provided in the form to pass to the database
214
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
52 bgadell 215
push @whereClause, "year(date) = '$YEAR'";
35 - 216
#warn join " and ", @whereClause;
217
 
218
							#  Given the fields to display and the where conditions,
219
							#	  "getData" will return a reference to an array of
220
							#	  hash references of the results.
221
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
222
my @ProductList = @{ $data };
223
 
224
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
225
my $x = scalar @ProductList; # How many results were returned?
226
 
227
# If the user is trying to download the Excel file, send it to them and then exit out.
228
if ($FORM{excel}) {
229
  exportExcel (\@ProductList, "MVP_Class_List");
230
  exit;
231
}
232
 
233
my @shifts;
234
if ($FORM{shiftinclude} eq "true") {
235
  my @SIWhere; # = ("year(date) = '$YEAR'");
236
  push @SIWhere, "RCid = $ORCUSER->{RCid}", "dept='CLA'";
237
  my ($d, $c) = getData (\@displayFields, \@SIWhere, 'v_shift', $FORM{sortby});
238
  @shifts = @{ $d };
239
}
240
 
241
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.";
242
 
243
# Set some cookie stuff...
244
my $path = `dirname $ENV{REQUEST_URI}`; chomp $path; $path .= '/' unless $path eq "/";
245
my $queryCookie = cookie(-NAME=>$prefscookie,
246
			-VALUE=>"$QUERY_STRING",
247
			-PATH=>"$path",
248
			-EXPIRES=>'+365d');
249
 
250
my $SIChecked;
251
if ($FORM{shiftinclude}) {
252
  $SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
253
} else {
254
  $SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
255
}
256
 
257
# Print the header
258
print header(-cookie=>[$RCAUTH_cookie,$queryCookie]);
259
 
260
# 	print "<!-- FORM \n\n";				# Debug code to dump the FORM to a html comment
261
#	print "I'm catching updates!!!\n\n";
262
#	foreach $key (sort (keys %FORM))		#	Must be done after the header is written!
263
# 		{ print "\t$key:  $FORM{$key}\n"; }
264
# 	print "--> \n\n";
265
#
266
#
267
# 	print "<!-- ENV \n\n";				# Debug code to dump the ENV to a html comment
268
# 	foreach $key (sort (keys %ENV))			#	Must be done after the header is written!
269
# 		{ print "\t$key:  $ENV{$key}\n"; }
270
# 	print "--> \n\n";
271
#
272
# 	print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
273
 
274
 
275
#------------------
276
 
277
# Toggle the autoload fields within the table elements
278
our ($onClick, $onChange);   # (also used in scanFunctions)
279
my ($radiobutton, $refreshbutton, $sortby);
280
if ($FORM{autoload}) {
281
	$onClick = "onClick='submit();'";
282
	$onChange = "onChange='page.value = 1; submit();'";
283
  $radiobutton = $h->div ({ class=>'autoload' },
284
    ["Autoload Changes: ",
285
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
286
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
287
    ]);
288
  $sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
289
} else {
290
  $onClick = "";
291
	$onChange = "onChange='page.value = 1;'";
292
  $radiobutton = $h->div ({ class=>'autoload' },
293
    ["Autoload Changes: ",
294
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
295
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
296
    ]);
297
  $refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
298
  $sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
299
}
300
 
301
 
302
 
303
 
304
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
305
 
306
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
307
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
308
print $h->div ({ class => "accent pageheader" }, [
309
  $h->h1 ($pageTitle),
310
  $h->div ({ class=>"sp0" }, [
311
    $h->div ({ class=>"spLeft" }, [
312
      $radiobutton
313
    ]),
314
    $h->div ({ class=>"spRight" }, [
315
      $h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
316
      $refreshbutton
317
    ]),
318
  ]),
319
]);
320
 
321
# Print the Hidden fields' check boxes (if there are any)
322
 
323
my $c = 1;
324
my @hiddencheckboxes;
325
my @hiddenrows;
326
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
327
  if ($FORM{autoload}) {
328
    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} ]);
329
  } else {
330
    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} ]);
331
  }
332
  if ($c++ % 4 == 0) {
333
    push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
334
    @hiddencheckboxes = [];
335
  }
336
}
337
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
338
 
52 bgadell 339
my @yearoptions;
340
foreach (@{&getYears()}) {
341
	push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
342
}
35 - 343
 
344
if (scalar @hideFields) {
345
  my @topleft;
346
  push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
347
  push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
348
 
349
  print $h->div ({ class=>"sp0" }, [
350
    $h->div ({ class=>"spLeft"  }, [ @topleft ]),
351
    $h->div ({ class=>"spRight" }, [
352
      $signedOnAs, $h->br,
353
      "Show my classes: ", $SIChecked, $h->br,
354
      $h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='manage_personal_time.pl'" }),
355
    ])
356
  ]);
357
}
358
 
359
# Print the main table...............................................
360
 
361
print $h->open ('div', { class=>'rTable' });
362
 
363
my @tmptitlerow;
364
foreach my $f (@displayFields)	{  # Print the Column headings
365
  if (inArray ($f, \@staticFields)) {
366
    push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
367
  } else {
368
    if ($FORM{autoload}) {
369
      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} ]);
370
    } else {
371
      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} ]);
372
    }
373
  }
374
}
375
 
376
# Print the filter boxes...
377
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
378
 
379
if ($FORM{shiftinclude}) {  # Include all of the user's shifts at the top
380
  foreach my $t (@shifts)	{
381
	  print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields ]);
382
  }
383
  print $h->hr ({ width=>"500%" });
384
}
385
 
386
# Print the things
387
foreach my $t (@ProductList)	{
388
  my @display = map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields;
389
  if ($t->{signedup}) {
390
	  print $h->div ({ class=>'rTableRow highlighted' }, [ @display ]);
391
  } else {
392
	  print $h->div ({ class=>'rTableRow shaded' }, [ @display ]);
393
  }
394
}
395
 
396
 
397
 
398
 
399
print $h->close ('div');
400
 
401
# close things out................................................
402
 
403
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
404
if ($curpage > $pages) { $curpage = $pages; }
405
 
406
my @pagerange;
407
if ($pages <= 5 ) {
408
  @pagerange = 1 .. $pages;
409
} else {
410
  if ($curpage <= 3) {
411
    @pagerange = (1, 2, 3, 4, ">>");
412
  } elsif ($curpage >= $pages - 2) {
413
    @pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
414
  } else {
415
    @pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
416
  }
417
}
418
 
419
my @excelcode;
420
push @excelcode, $h->br;
421
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.]");
422
 
423
 
424
print $h->br; # print $h->br;
425
print $h->div ({ class=>"sp0" }, [
426
    $h->div ({ class=>"spLeft" }, [
427
      $h->div ({ class=>"footer" }, [
428
        "To bookmark, save, or send this exact view, use the ",
429
        $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
430
        $h->br,
431
        "If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
432
        @excelcode,
433
        $h->br,
434
        "This page was displayed on ", currentTime (),
435
        $h->br,
436
        "Please direct questions, problems, and concerns to Officials.RollerCon.Schedule\@gmail.com",
52 bgadell 437
        $h->br,
438
        "Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
35 - 439
      ])
440
    ]),
441
    $h->div ({ class=>"spRight" }, [
442
      $h->h5 ([
443
               "$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
444
               "Sorted by ", $sortby, $h->br,
445
               "Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
446
               ( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
447
                                                $_ eq "<<"     ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
448
                                                $_ eq ">>"     ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
449
                                                                 $h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
450
               $h->input ({ type=>"hidden", name=>"page", value=>$curpage })
451
      ])
452
    ]),
453
]);
454
 
455
#print $h->br; # print $h->br;
456
#print $h->h5 ("$x Record(s) Displayed");
457
#print $h->div ({ class=>"footer" }, [
458
#  "To bookmark, save, or send this exact view, use the ",
459
#  $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
460
#  $h->br,
461
#  "This page was displayed on $now",
462
#  $h->br,
463
#  "Please direct questions, problems, and concerns to noone\@gmail.com"
464
#]);
465
 
466
 
467
print $h->close('form');
468
print $h->close('html');