Subversion Repositories PEEPS

Rev

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

Rev Author Line No. Line
2 - 1
#package tableViewer;
2
 
3
#######################################################################
4
# A set of functions to assist the scan data display tool.
5
# Kept here to unclutter the main script.
6
#######################################################################
7
#
8
#
9
# $Log: scanFunctions.pm,v $
10
#
11
 
12
#use strict;
13
use Exporter 'import';
14
use DBI ();
15
use WebDB;
16
use Carp;
17
 
18
our @EXPORT = qw( byfield currentTime exportExcel fetchColEntries fetchDerbyNameWithRCid filter getFilterValue getData getDBConnection inArray notInArray uniq whereInArray printTablePage );
19
 
20
my $internalDBH = WebDB::connect () || die "Unable to connect to Database\n\n";
21
 
22
sub currentTime {
23
  use DateTime;
24
  my $now = DateTime->now (time_zone => 'America/Los_Angeles');
25
  $now =~ s/T/ at /;
26
 
27
  return $now." US/Pacific";
28
}
29
 
30
sub byfield { $colOrderHash{$a} <=> $colOrderHash{$b}; }
31
 
32
sub exportExcel {
33
  my $listref = shift;
34
  my $FN_Prefix = shift // "VORC_Export";
35
  my $displayFields = shift // "";
36
 
37
  use Spreadsheet::WriteExcel;
38
 
39
  my $date = `date +"%m%d%y%H%M%S"`; chomp $date;
40
  my $filename = "${FN_Prefix}_${date}_$$.xls";
41
 
42
  print "Content-type: application/vnd.ms-excel\n";
43
  # The Content-Disposition will generate a prompt to save the file. If you want
44
  # to stream the file to the browser, comment out the following line.
45
  print "Content-Disposition: attachment; filename=$filename\n";
46
  print "\n";
47
 
48
  # Create a new workbook and add a worksheet. The special Perl filehandle - will
49
  # redirect the output to STDOUT
50
  #
51
  my $workbook  = Spreadsheet::WriteExcel->new(\*STDOUT);
52
  my $worksheet = $workbook->add_worksheet();
53
 
54
  my $format = $workbook->add_format();
55
  $format->set_bold();
56
 
57
  my $col = $row = 0;
58
 
59
  foreach $f (@$displayFields)
60
    { $worksheet->write($row, $col++, "$NAME{$f}", $format); }
61
 
62
  foreach $t (sort @{ $listref })     # Unt now we print the tickets!
63
  {
64
    $col = 0;
65
    $row++;
66
    foreach $f (@$displayFields) {
67
      if ($f eq "derby_name") {
68
        if ($user->{department}->{"OFF"} < 2 and $t->{derby_name} and $t->{RCid} != $RCid and $LVL < 5) {
69
          $t->{derby_name} = "FILLED";
70
        }
71
      }
72
      $t->{$f} =~ s/<br>/\n/ig; $worksheet->write($row, $col++, "$t->{$f}");
73
    }
74
  }
75
 
76
  $workbook->close();
77
  return;
78
}
79
 
80
 
81
sub fetchColEntries {
82
  my $colName = shift;
83
  my $selection = shift;
84
  my $year = shift // "year(now())";
85
  my $table = $DBTABLE;
86
  my $optionList = "";
87
 
88
  if ($colName eq "derby_name" and $LVL < 2) {
89
    # special case to anonymize assignees...
90
    my @opts = ("-blank-", $ORCUSER->{derby_name});
91
    push @opts, map { @{$_} } @{ $internalDBH->selectall_arrayref ("select derby_name from official where showme = 1 and derby_name <> ? order by derby_name", undef, $ORCUSER->{derby_name}) };
92
    $optionList = join "", map { $selection eq $_ ? "<OPTION selected>$_</OPTION>" : "<OPTION>$_</OPTION>" } @opts;
93
  } else {
94
    my $dept_where = $table eq "v_shift" ? "where dept != 'PER' and year(date) = $year" : "";
95
    my $orderby = $colName eq "dayofweek" ? "field(dayofweek, 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')" : $colName;
96
    my $cathan = $internalDBH->prepare("select distinct nullif($colName, '') from $table $dept_where order by $orderby");
97
 
98
    $cathan->execute();
99
    while (my ($cat) = $cathan->fetchrow) {
100
      if (!$cat) { $cat = "-blank-"; }
101
      if ($cat eq $selection) {
102
        $optionList .= "<OPTION selected>$cat</OPTION>";
103
      } else {
104
        $optionList .= "<OPTION>$cat</OPTION>";
105
      }
106
    }
107
  }
108
 
109
  return $optionList;
110
}
111
 
112
sub fetchDerbyNameWithRCid {
113
  my $ATTRIBUTES;
114
  if (ref $_[0] eq "HASH") {
115
    $ATTRIBUTES = shift;
116
  }
117
  my $DEPT = shift // "";
118
  my $selected = shift // "";
119
  my $optionList = "";
120
 
121
  my $cathan;
122
  if (!$DEPT or $DEPT eq "CMP") {
123
    $cathan = $internalDBH->prepare("select RCid, derby_name from official where access > 0 order by derby_name");
124
    $cathan->execute();
125
  } elsif ($DEPT eq "CLA") {
126
    $cathan = $internalDBH->prepare("select RCid, derby_name from v_official where access > 0 and isnull(MVPid) = false and last_login > CURRENT_DATE - INTERVAL 365 DAY order by derby_name");
127
    $cathan->execute;
128
  } elsif ($DEPT eq "EMT") {
129
    $cathan = $internalDBH->prepare("select RCid, derby_name from v_official where access > 0 and emt_verified = true and last_login > CURRENT_DATE - INTERVAL 365 DAY order by derby_name");
130
    $cathan->execute;
131
  } else {
132
    $cathan = $internalDBH->prepare("select RCid, derby_name from official where access > 0 and (department like ? and department not like ?) and last_login > CURRENT_DATE - INTERVAL 365 DAY order by derby_name");
133
    $cathan->execute("%".$DEPT."%", "%".$DEPT."-0%");
134
  }
135
 
136
  my $valuelabel = $ATTRIBUTES->{DATALIST} ? "data-value" : "value";
137
  while (my ($id, $cat) = $cathan->fetchrow) {
138
    if ($id == $selected) {
139
      $optionList .= "<OPTION $valuelabel=$id selected>$cat</OPTION>";
140
    } else {
141
      $optionList .= "<OPTION $valuelabel=$id>$cat</OPTION>";
142
    }
143
  }
144
 
145
  return $optionList;
146
}
147
 
148
 
149
sub filter {
150
  my $colName = shift;
151
  my $filter = shift;
152
  my $year = shift;
153
 
154
  if (exists &{"filter_".$colName}) { return &{"filter_".$colName} ($colName, $filter); }
155
 
156
  if ($colFilterTypeHash{$colName} eq 'select')
157
  {
158
    if (defined $filter)  {
159
      if ($filter eq "-blank-") {
160
        return "($colName = '' or isNull($colName) = 1)";
161
      }
162
#     $filter = s/'/\'/g;
163
      return "$colName = \"$filter\"";
164
    }
165
    else
166
    {
167
      my $thing = "filter-${colName}";
168
      my $categories = $year ? fetchColEntries ($colName, $FORM{$thing}, $year) : fetchColEntries ($colName, $FORM{$thing});
169
      my $Options = "<OPTION></OPTION>".$categories;
170
 
171
      $Options =~ s/>($FORM{$thing})/ selected>$1/;
172
      return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
173
    }
174
  } elsif ($colFilterTypeHash{$colName} eq 'text') {
175
    if (defined $filter)
176
    {
177
      if ($filter =~ /\d{1,2}:\d{2}/ and $ORCUSER->{timeformat} eq "ampm") {
178
        my ($h, $m) = split /:/, $filter;
179
        my $caret;
180
        if ($h =~ s/^\^\s*//) { $caret = "^"; }
181
        if ($h < 8) { $h += 12; }
182
        $filter = $caret.join ":", $h, $m;
183
      }
184
 
185
      if ($filter =~ s/^=\s*//) { return "$colName = \"$filter\""; }
186
 
187
      if ($filter !~ s/^\^\s*//) { $filter = "\%$filter"; }
188
      if ($filter !~ s/\s*\$$//) { $filter = "$filter\%"; }
189
      $filter =~ s/\*/%/g;
190
 
191
      return "$colName like \"$filter\"";
192
    }
193
    else
194
    {
195
      my $thing = "filter-${colName}";
196
      return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $onChange>";
197
    }
198
  } elsif ($colFilterTypeHash{$colName} eq 'number') {
199
    if (defined $filter)
200
    {
201
      if ($filter =~ /^[>=<]\s*/) { return "$colName $filter"; }
202
      else { return "$colName = $filter"; }
203
    }
204
    else
205
    {
206
      my $thing = "filter-${colName}";
207
      return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=2 $onChange>";
208
    }
209
  } elsif ($colFilterTypeHash{$colName} eq 'date') {
210
    if (defined $filter)
211
    {
212
      if ($filter =~ s/^<\s*//) { return "$colName < '$filter'"; }
213
      if ($filter =~ s/^>\s*//) { return "$colName > '$filter'"; }
214
 
215
      return "$colName = '$filter'";
216
    }
217
    else
218
    {
219
      my $thing = "filter-${colName}";
220
      return "<INPUT type=text name=$thing value=\"$FORM{$thing}\" size=15 $onChange>";
221
    }
222
  } elsif ($colFilterTypeHash{$colName} eq 'boolean') {
223
    if (defined $filter)
224
    {
225
      return "$colName = $filter";
226
    }
227
    else
228
    {
229
      my $thing = "filter-${colName}";
230
      my $Options = "<OPTION></OPTION><OPTION>True</OPTION><OPTION>False</OPTION>";
231
 
232
      $Options =~ s/>($FORM{$thing})/ selected>$1/;
233
      return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
234
    }
235
  } elsif ($colFilterTypeHash{$colName} eq 'ERROR') {
236
    return "<center><strong><font color=red>ERROR!</font>";
237
  } elsif ($colFilterTypeHash{$colName} eq 'none') {
238
    return;
239
  }
240
}
241
 
242
sub getFilterValue {
243
  my $colName = shift;
244
  return $FORM{"filter-${colName}"};
245
#  my $tmpFormValue = param ("filter-${colName}");
246
#  $tmpFormValue //= url_param ("filter-${colName}");
247
#  $tmpFormValue //= $FORM{"filter-${colName}"};
248
#
249
#  return $tmpFormValue;
250
}
251
 
252
sub getData {
253
  my $fields = shift;
254
  my $whereClause = shift;
255
  my $table = shift;
256
  my $orderby = shift;
257
  my $curpage = shift; $curpage = 1 unless $curpage;
258
  my $pagelimit = shift // "All";
259
 
260
  my $selected = '*';
261
  if ($table eq "v_class_new") {
262
    foreach (@{$whereClause}) {
263
      /^RCid = \d+$/ and $table = "v_class_signup_new";
264
    }
265
 
266
  }
267
  $whereClause = scalar @{$whereClause} > 0 ? "where ".join (" and ", @{$whereClause}) : '';
268
 
269
  if ($orderby eq "dayofweek") {
270
    $orderby = "order by date, time";
271
  } elsif ($orderby eq "eventid") { # only applicable to the log viewer...
272
    $orderby = "order by eventid desc";
273
  } elsif ($orderby eq "timestamp") { # only applicable to the log viewer...
274
    $orderby = "order by timestamp desc";
275
  } elsif ($orderby eq "key") { # for the settings page, the column name 'key' is a reserved word in mysql
276
    $orderby = "order by ${table}.key";
277
  } else {
278
    $orderby = $orderby eq "" ? "" : "order by $orderby";
279
  }
280
 
281
  my $getMe;
282
  if ($pagelimit eq "All") {
283
    $getMe = "select distinct * from $table $whereClause $orderby";
284
  } else {
285
    $curpage = ($curpage - 1) * $pagelimit;
286
    $getMe = "select distinct * from $table $whereClause $orderby limit $curpage, $pagelimit";
287
  }
288
  my ($totalcount) = @{$internalDBH->selectrow_arrayref ("select distinct count(*) from $table $whereClause")};
289
#  warn $getMe;
290
  my $limhan = $internalDBH->prepare($getMe);     # Get the tickets from the DB
291
  $limhan->execute();
292
 
293
  my @results = ();
294
  while (my $P = $limhan->fetchrow_hashref)
295
  {
296
    push @results, $P;
297
  }
298
 
299
  return (\@results, $totalcount);
300
}
301
 
302
 
303
sub getDBConnection {
304
  use WebDB;
305
  $dbh = WebDB::connect ();
306
  return $dbh;
307
}
308
 
309
 
310
sub inArray {
311
  my $item = shift;
312
  my $array = shift;
313
 
314
  croak "inArray error: too many parameters. Did you pass an array instead of an array reference?" if scalar @_;
315
  croak "inArray error: unexpected parameters ($item, $array). Are the arguments reversed?" unless ref $array eq "ARRAY" and ref $item ne "ARRAY";
316
 
317
  foreach (@{$array})
318
  {
319
    return 1 if $item eq $_;
320
  }
321
  return 0;
322
}
323
 
324
sub notInArray {
325
  return ! inArray (@_);
326
}
327
 
328
 
329
sub uniq (@) {
330
    # From CPAN List::MoreUtils, version 0.22
331
    my %h;
332
    map { $h{$_}++ == 0 ? $_ : () } @_;
333
}
334
 
335
 
336
sub whereInArray {
337
  my $item = shift;
338
  my $array = shift;
339
  my $i = 0;
340
  foreach (@{$array})
341
  {
342
    return $i if $item eq $_;
343
    $i++;
344
  }
345
  return -1;
346
}
347
 
348
sub printTablePage {
349
  my $paramhash = shift;
350
  my $PEEPSAUTH_cookie = $paramhash->{PEEPSAuth} // "";
351
  my $pageTitle = $paramhash->{Title};
352
  my $prefscookie = $paramhash->{Prefs} // "";
353
    ($prefscookie = lc $pageTitle) =~ s/\s+//g unless $prefscookie;
354
  my $DBTABLE = $paramhash->{Table};
355
  my $COLUMNS = $paramhash->{Columns};
356
  my $defaultWhereClause = $paramhash->{Where} // "";
357
  my $displayYearSelect = $paramhash->{DisplayYearSelect} // 0;
358
  my $showMyShiftsOption = $paramhash->{ShowMyShifts} // 0;
359
  my $highlightShifts = $paramhash->{HighlightShifts} // 0;
360
  my $headerButton = $paramhash->{HeaderButton} // "";
361
  my $blockPersonalTime = $paramhash->{PersonalTimeButton} // "";
362
 
363
  use CGI qw/param cookie header start_html url url_param/;
364
  use HTML::Tiny;
365
  my $h = HTML::Tiny->new( mode => 'html' );
3 - 366
  $ENV{HTTPS} = 'ON';
2 - 367
 
368
  my $stylesheet = "/style.css";
369
  my $homeURL = '/';
370
  my @pagelimitoptions = ("All", 5, 10, 25);
371
  my $YEAR;
372
 
373
  # Extract the column names and build utility variables
374
  my %NAME              = map  { $_ => $COLUMNS->{$_}->[0] } keys %{$COLUMNS};
375
  my %colOrderHash      = map  { $_ => $COLUMNS->{$_}->[1] } keys %{$COLUMNS};
376
  sub byfield { $colOrderHash{$a} <=> $colOrderHash{$b}; }
377
  our %colFilterTypeHash = map  { $_ => $COLUMNS->{$_}->[2] } keys %{$COLUMNS};
378
  my @staticFields      = sort byfield grep { $COLUMNS->{$_}->[3] and $COLUMNS->{$_}->[3] eq 'static' } keys %{$COLUMNS};
379
  my @defaultFields     = sort byfield grep { defined $COLUMNS->{$_}->[3] } keys %{$COLUMNS};
380
 
381
  my @allFields = sort byfield keys %NAME;
382
  my @displayFields = ();
383
  my @hideFields = ();
384
  my $QUERY_STRING;
385
 
386
  my $pagelimit = param ("limit") // $pagelimitoptions[$#pagelimitoptions];
387
  my $curpage = param ("page") // 1;
388
 
389
  our %FORM;
390
  my $FILTER;
391
  foreach (param()) {
392
    if (/^year$/) {
393
      $YEAR = param($_);
394
      next;
395
    }
396
 
397
    $FORM{$_} = param($_);        # Retrieve all of the FORM data submitted
398
    #warn "$_: $FORM{$_}";
399
 
400
    if ((/^filter/) and ($FORM{$_} ne '')) {  # Build a set of filters to apply
401
      my ($filter,$field) = split /-/, $_;
402
      $FILTER->{$field} = $FORM{$_} unless notInArray ($field, \@allFields);
403
    } elsif ($FORM{$_} eq "true")     # Compile list of fields to display
404
      { push @displayFields, $_ unless /shiftinclude/; }
405
  }
406
 
407
  foreach (url_param()) {
408
    if (/^year$/) {
409
      $YEAR = url_param($_);
410
      next;
411
    }
412
 
413
    $FORM{$_} = url_param($_);        # Retrieve all of the FORM data submitted
414
    #warn "$_: $FORM{$_}";
415
 
416
    if ((/^filter/) and ($FORM{$_} ne '')) {  # Build a set of filters to apply
417
      my ($filter,$field) = split /-/, $_;
418
      $FILTER->{$field} = $FORM{$_} unless notInArray ($field, \@allFields);
419
    } elsif ($FORM{$_} eq "true")     # Compile list of fields to display
420
      { push @displayFields, $_ unless /shiftinclude/; }
421
  }
422
 
423
  if (exists $FORM{autoload}) {     # If the FORM was submitted (i.e. the page is being redisplayed),
424
                                    #   build the data for the cookie that remembers the page setup
425
    my $disFields = join ":", @displayFields;
426
    my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
427
 
428
    $QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload};
429
    $QUERY_STRING .= '&'.$FORM{shiftinclude} unless !$FORM{shiftinclude};
430
  }
431
 
432
  if (!(exists $FORM{autoload}))  {     # No FORM was submitted...
433
    if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie"))  { # Check for cookies from previous visits.
434
      my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;
435
      @displayFields = split /:/,$disF;
436
 
437
      foreach my $pair (split /:/, $filts)  {
438
        my ($key, $value) = split /=/, $pair;
439
        $FORM{"filter-$key"} = $value;
440
        $FILTER->{$key} = $value;
441
      }
442
 
443
      $FORM{sortby} = $sb;
444
      $FORM{autoload} = $al;
445
      $FORM{shiftinclude} = $si;
446
      $QUERY_STRING = $prefs;
447
    } else {
448
      @displayFields = @defaultFields; # Otherwise suppply a default list of columns.
449
      $FORM{autoload} = 1;             # And turn autoload on by default.
450
    }
451
  }
452
 
453
  # let's just make sure the columns are in the right order (and there aren't any missing)
454
  @displayFields = grep { inArray($_, \@allFields) } sort byfield uniq @displayFields, @staticFields;
455
 
456
  # If the field isn't in the displayFields list, then add it to the hideFields list
457
  @hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
458
 
459
  # Process any filters provided in the form to pass to the database
460
  my @whereClause; # = $defaultWhereClause;
461
  push @whereClause, $defaultWhereClause unless !$defaultWhereClause;
462
  if ($displayYearSelect) {
463
    my $yearfield = inArray("date", \@allFields) ? 'year(date)' : "year";  # some pages only use the year, and not a date
464
 
465
    if ($YEAR) {
466
      push @whereClause, "$yearfield = '$YEAR'";
467
    } else {
468
      push @whereClause, "$yearfield = year(now())";
469
    }
470
  }
471
  push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
472
 
473
                #  Given the fields to display and the where conditions,
474
                #   "getData" will return a reference to an array of
475
                #   hash references of the results.
476
  my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
477
  my @ProductList = @{ $data };
478
 
479
  my $x = scalar @ProductList; # How many results were returned?
480
 
481
  # If the user is trying to download the Excel file, send it to them and then exit out.
482
  if ($FORM{excel}) {
483
    (my $filename = $pageTitle) =~ s/\s+/_/g;
484
    exportExcel (\@ProductList, $filename, \@displayFields);
485
    exit;
486
  }
487
 
488
  my @shifts;
489
  if ($FORM{shiftinclude} eq "true") {
490
    my @SIWhere = ("year(date) = '$YEAR'");
491
    push @SIWhere, "RCid = $ORCUSER->{RCid}";
492
    my ($d, $c) = getData (\@displayFields, \@SIWhere, $DBTABLE, $FORM{sortby});
493
    @shifts = @{ $d };
494
  }
495
 
496
  my $username = $h->a ({ href=>"/view_user?submit=View&RCid=$ORCUSER->{RCid}" }, $ORCUSER->{derby_name});
497
  my $signedOnAs = $username ? "Welcome, $username. ".$h->input ({ type=>"button", value=>"Log Out", onClick=>"window.location.href='index?LOGOUT';" }) : "You are not signed in.";
498
 
499
  # Set some cookie stuff...
500
  my $path = `dirname $ENV{SCRIPT_NAME}`; chomp $path; $path .= '/' unless $path eq "/";
501
  my $queryCookie = cookie(-NAME=>$prefscookie,
502
        -VALUE=>"$QUERY_STRING",
503
        -PATH=>"$path",
504
        -EXPIRES=>'+365d');
505
 
506
  # Print the header
507
  print header (-cookie=> [ $queryCookie, $PEEPSAUTH_cookie ] );
508
 
509
  #------------------
510
 
511
  # Toggle the autoload fields within the table elements
512
  our ($onClick, $onChange);   # (also used in scanFunctions)
513
  my ($radiobutton, $refreshbutton, $sortby);
514
  if ($FORM{autoload}) {
515
    $onClick = "onClick='submit();'";
516
    $onChange = "onChange='page.value = 1; submit();'";
517
    $radiobutton = $h->div ({ class=>'autoload' },
518
      ["Autoload Changes: ",
519
      $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
520
      $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
521
      ]);
522
    $refreshbutton = "";
523
    $sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
524
  } else {
525
    $onClick = "";
526
    $onChange = "onChange='page.value = 1;'";
527
    $radiobutton = $h->div ({ class=>'autoload' },
528
      ["Autoload Changes: ",
529
      $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
530
      $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
531
      ]);
532
    $refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
533
    $sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
534
  }
535
 
536
  # "Shift Include" shows a checkbox to include a users shifts at the top of the page
537
  my $SIChecked;
538
  if ($showMyShiftsOption) {
539
    my $things = $DBTABLE eq "v_class_new" ? "classes" : "shifts";
540
    if ($FORM{shiftinclude}) {
541
      $SIChecked = "Show my $things: ".$h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
542
    } else {
543
      $SIChecked = "Show my $things: ".$h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
544
    }
545
  }
546
 
547
  # If the block personal time flag is set, include a button to go to that form.
548
  $SIChecked .= '&nbsp;'.$h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='personal_time'" }) unless !$blockPersonalTime;
549
  $SIChecked .= $h->br unless !$SIChecked;
550
 
551
  print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
552
 
553
  print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
554
  print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
555
  print $h->div ({ class => "accent pageheader" }, [
556
    $h->h1 ($pageTitle),
557
    $h->div ({ class=>"sp0" }, [
558
      $h->div ({ class=>"spLeft" }, [
559
        $radiobutton
560
      ]),
561
      $h->div ({ class=>"spRight" }, [
562
        $h->input ({ type=>"button", value=>"Home", onClick=>'window.location.href="'.$homeURL.'"' }),
563
        $refreshbutton
564
      ]),
565
    ]),
566
  ]);
567
 
568
  # Print the Hidden fields' check boxes (if there are any)
569
  my $c = 1;
570
  my @hiddencheckboxes;
571
  my @hiddenrows;
572
  foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
573
    if ($FORM{autoload}) {
574
      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} ]);
575
    } else {
576
      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} ]);
577
    }
578
    if ($c++ % 4 == 0) {
579
      push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
580
      @hiddencheckboxes = [];
581
    }
582
  }
583
  push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
584
 
585
  if (scalar @hideFields) {
586
    my @topleft;
587
    push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
588
    push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
589
 
590
    print $h->div ({ class=>"sp0" }, [
591
      $h->div ({ class=>"spLeft"  }, [ @topleft ]),
592
      $h->div ({ class=>"spRight" }, [
593
        $signedOnAs, $h->br,
594
        $SIChecked,
595
      ])
596
    ]);
597
  }
598
 
599
  # Print the main table...............................................
600
 
601
  print $h->open ('div', { class=>'rTable' });
602
 
603
  my @tmptitlerow;
604
  foreach my $f (@displayFields)  {  # Print the Column headings
605
    my $special_button = "";
606
    if ($headerButton) {
607
      if ($f eq $headerButton->{field}) {
608
        $special_button = '&nbsp;'.$headerButton->{button};
609
      }
610
    }
611
    if (inArray ($f, \@staticFields)) {
612
      push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f}, $special_button ]);
613
    } else {
614
      if ($FORM{autoload}) {
615
        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}, $special_button ]);
616
      } else {
617
        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}, $special_button ]);
618
      }
619
    }
620
  }
621
 
622
  # Print the filter boxes...
623
  print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_, undef, $YEAR)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
624
 
625
  if ($FORM{shiftinclude}) {  # Include all of the user's shifts at the top
626
    foreach my $t (@shifts) {
627
      no strict;
628
      print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_} ? $t->{$_} : "") } @displayFields ]);
629
    }
630
    print $h->hr ({ width=>"500%" });
631
  }
632
 
633
 
634
  # Print the things
635
  foreach my $t (@ProductList)  {
636
    my $shading = ($highlightShifts and $t->{RCid} eq $ORCUSER->{RCid}) ? "highlighted" : "shaded";
637
    no strict; # 'strict' doesn't like the exists functionality
638
    my $rowclick = (exists &addRowClick) ? addRowClick ($t) : "";
639
 
640
    print $h->div ({ class=>'rTableRow '.$shading, onClick=>$rowclick }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_} ? $t->{$_} : "") } @displayFields ]);
641
  }
642
 
643
  print $h->close ('div');
644
 
645
  # close things out................................................
646
 
647
  my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
648
  if ($curpage > $pages) { $curpage = $pages; }
649
 
650
  my @pagerange;
651
  if ($pages <= 5 ) {
652
    @pagerange = 1 .. $pages;
653
  } else {
654
    if ($curpage <= 3) {
655
      @pagerange = (1, 2, 3, 4, ">>");
656
    } elsif ($curpage >= $pages - 2) {
657
      @pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
658
    } else {
659
      @pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
660
    }
661
  }
662
 
663
  my @yearoptions;
664
  if ($displayYearSelect) {
665
    my $currentyear;
666
    foreach (@{&getYears()}) {
667
      push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
668
      $currentyear = $_;
669
    }
670
    $yearoptions[$#yearoptions] = $h->option ({ selected=>[] }, $currentyear) unless $YEAR;
671
  }
672
 
673
  print $h->br; # print $h->br;
674
  print $h->div ({ class=>"sp0" }, [
675
      $h->div ({ class=>"spLeft" }, [
676
        $h->div ({ class=>"footer" }, [
677
          "To bookmark, save, or send this exact view, use the ",
678
          $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
679
          $h->br,
680
          "If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
681
          $h->br,
682
          $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.]"),
683
          $h->br,
684
          "This page was displayed on ", currentTime (),
685
          $h->br,
686
          "Please direct questions, problems, and concerns to $SYSTEM_EMAIL",
687
          $displayYearSelect ? $h->br."Displaying: ".$h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ]) : $h->br
688
        ])
689
      ]),
690
      $h->div ({ class=>"spRight" }, [
691
        $h->h5 ([
692
                 "$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
693
                 "Sorted by ", $sortby, $h->br,
694
                 "Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
695
                 ( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
696
                                                  $_ eq "<<"     ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
697
                                                  $_ eq ">>"     ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
698
                                                                   $h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
699
                 $h->input ({ type=>"hidden", name=>"page", value=>$curpage })
700
        ])
701
      ]),
702
  ]);
703
 
704
  print $h->close('form');
705
  print $h->close('body');
706
  print $h->close('html');
707
}
708
 
709
# Leave this alone, it's needed to compile correctly
710
return 1;