| 56 |
bgadell |
1 |
#!/usr/bin/perl
|
|
|
2 |
|
|
|
3 |
# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)
|
|
|
4 |
my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";
|
|
|
5 |
close STDERR;
|
|
|
6 |
open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";
|
|
|
7 |
#warn "Redirecting errors to ${error_log_path}vorc_error.log";
|
|
|
8 |
|
|
|
9 |
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
|
|
|
10 |
|
| 196 |
- |
11 |
use strict;
|
| 56 |
bgadell |
12 |
use cPanelUserConfig;
|
|
|
13 |
use CGI qw/param cookie header start_html url/;
|
|
|
14 |
use HTML::Tiny;
|
|
|
15 |
use tableViewer;
|
|
|
16 |
use RollerCon;
|
|
|
17 |
use DateTime;
|
|
|
18 |
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
|
|
|
19 |
our $h = HTML::Tiny->new( mode => 'html' );
|
|
|
20 |
|
| 196 |
- |
21 |
my $cookie_string = authenticate(1) || die;
|
|
|
22 |
our ($EML, $PWD, $LVL) = split /&/, $cookie_string;
|
|
|
23 |
my $RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
|
|
|
24 |
my $RCid = $ORCUSER->{RCid};
|
| 56 |
bgadell |
25 |
|
| 196 |
- |
26 |
if (!$ORCUSER->{MVPid} and $LVL < RollerCon::ADMIN and $ORCUSER->{department}->{MVP} < RollerCon::USER and $ORCUSER->{department}->{COA} < RollerCon::USER) {
|
|
|
27 |
print header(-cookie=>$RCAUTH_cookie);
|
|
|
28 |
printRCHeader("Unauthorized Page");
|
|
|
29 |
print $h->div ({ class=>"error" }, "No Access");
|
|
|
30 |
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.");
|
|
|
31 |
print $h->a ({ href=>"/schedule/" }, "[Go Home]");
|
| 222 |
- |
32 |
print $h->close ("body");
|
| 196 |
- |
33 |
print $h->close ("html");
|
|
|
34 |
exit;
|
| 56 |
bgadell |
35 |
}
|
|
|
36 |
|
|
|
37 |
my $pageTitle = "MVP Classes";
|
| 208 |
- |
38 |
our $DBTABLE = 'v_class_new';
|
| 56 |
bgadell |
39 |
my %COLUMNS = (
|
|
|
40 |
# colname => [qw(DisplayName N type status)], status -> static | default | <blank>
|
| 196 |
- |
41 |
name => [qw(Class 5 text static )],
|
|
|
42 |
date => [qw(Date 10 date )],
|
|
|
43 |
dayofweek => [qw(Day 15 select default )],
|
|
|
44 |
start_time => [qw(StartTime 20 text )],
|
|
|
45 |
end_time => [qw(EndTime 25 text )],
|
|
|
46 |
time => [qw(Time 30 text default )],
|
|
|
47 |
location => [qw(Track 35 select default )],
|
|
|
48 |
level => [qw(Level 37 select default )],
|
| 208 |
- |
49 |
coach => [qw(Coach 40 select default )],
|
|
|
50 |
assistant => [qw(Assistant 41 select )]
|
| 56 |
bgadell |
51 |
);
|
|
|
52 |
|
|
|
53 |
if ($LVL >= RollerCon::ADMIN) {
|
|
|
54 |
$COLUMNS{id} = [qw(Admin 1 none default )];
|
| 196 |
- |
55 |
$COLUMNS{available}= [qw(SignUp 45 text )]
|
| 56 |
bgadell |
56 |
}
|
|
|
57 |
|
| 196 |
- |
58 |
if ($LVL >= RollerCon::ADMIN or $ORCUSER->{department}->{MVP} >= RollerCon::VOLUNTEER or $ORCUSER->{department}->{COA} >= RollerCon::USER) {
|
|
|
59 |
$COLUMNS{note} = [qw(Notes 60 text )],
|
|
|
60 |
$COLUMNS{capacity} = [qw(Capacity 65 number default )],
|
|
|
61 |
$COLUMNS{count} = [qw(Count 70 number default )],
|
|
|
62 |
$COLUMNS{stars} = [qw(Stars 75 number default )],
|
|
|
63 |
$COLUMNS{responses} = [qw(Responses 80 number default )],
|
| 56 |
bgadell |
64 |
}
|
|
|
65 |
|
| 196 |
- |
66 |
if ($ORCUSER->{MVPid} and $LVL < RollerCon::ADMIN) {
|
|
|
67 |
$COLUMNS{available}= [qw(SignUp 45 text static)]
|
| 56 |
bgadell |
68 |
}
|
|
|
69 |
|
|
|
70 |
# Set any custom "where" DB filters here...
|
|
|
71 |
my @whereClause;
|
|
|
72 |
|
|
|
73 |
# If we need to modify line item values, create a subroutine named "modify_$columnname"
|
|
|
74 |
# It will receive a hashref to the object lineitem
|
|
|
75 |
|
|
|
76 |
my $dbh = getRCDBH;
|
|
|
77 |
|
| 222 |
- |
78 |
sub modify_coach {
|
|
|
79 |
my $line = shift;
|
|
|
80 |
if ($line->{coachRCid} =~ / & /) {
|
|
|
81 |
return join " & ", map { $h->a ({ href=>"view_coach.pl?RCid=".$_ }, getUser($_)->{derby_name}) } split / & /, $line->{coachRCid};
|
|
|
82 |
}
|
|
|
83 |
return $line->{coach} ? $h->a ({ href=>"view_coach.pl?RCid=".$line->{coachRCid} }, $line->{coach}) : "";
|
|
|
84 |
}
|
|
|
85 |
|
| 56 |
bgadell |
86 |
sub modify_id {
|
|
|
87 |
my $hr = shift;
|
|
|
88 |
my $clicky = $hr->{count} ? "event.stopPropagation(); if (confirm('WARNING!\\nYou are modifying a class that someone has signed up for.')==true) {return true;} else {return false;}" : "return true;";
|
|
|
89 |
my $extrawarning = $hr->{count} ? "\\nWARNING! It appears someone is signed up for it." : "";
|
|
|
90 |
return join " ", #$hr->{id},
|
|
|
91 |
$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Update", onClick=>$clicky }, "[Edit]"),
|
|
|
92 |
$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Copy" }, "[Copy]"),
|
|
|
93 |
$h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Delete", onClick=>"event.stopPropagation(); if (confirm('Are you sure you want to DELETE this class?$extrawarning')==true) {return true;} else {return false;}" }, "[Delete]")
|
|
|
94 |
;
|
|
|
95 |
};
|
|
|
96 |
|
|
|
97 |
sub modify_available {
|
| 196 |
- |
98 |
my $t = shift;
|
|
|
99 |
|
|
|
100 |
my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
|
|
|
101 |
my $cutoff = DateTime->new(
|
| 56 |
bgadell |
102 |
year => $yyyy,
|
|
|
103 |
month => $mm,
|
|
|
104 |
day => $dd,
|
|
|
105 |
hour => 5,
|
|
|
106 |
minute => 0,
|
|
|
107 |
second => 0,
|
|
|
108 |
time_zone => 'America/Los_Angeles'
|
|
|
109 |
);
|
|
|
110 |
|
|
|
111 |
return "CLOSED" unless $now < $cutoff;
|
|
|
112 |
|
| 196 |
- |
113 |
my $classkey = join '|', $t->{date}, $t->{start_time}, $t->{location};
|
|
|
114 |
|
| 208 |
- |
115 |
($t->{signedup}) = $dbh->selectrow_array ("select role from v_class_signup_new where RCid = ? and id = ?", undef, $RCid, $t->{id} );
|
| 196 |
- |
116 |
my $droplink = $h->a ({ onClick=>"if (confirm('Really? You want to drop this class?')==true) { window.open('make_shift_change.pl?change=del&RCid=$RCid&id=$t->{id}&role=$t->{signedup}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");
|
|
|
117 |
if (!$t->{available}) {
|
|
|
118 |
my $full = "FULL";
|
|
|
119 |
$full .= " | ".$droplink unless !$t->{signedup};
|
|
|
120 |
return $full;
|
| 56 |
bgadell |
121 |
}
|
|
|
122 |
|
| 196 |
- |
123 |
$t->{available} .= " Open";
|
| 56 |
bgadell |
124 |
$t->{available} .= " | ".$droplink unless !$t->{signedup};
|
| 85 |
bgadell |
125 |
if (findConflict ($ORCUSER->{RCid}, $t->{id}, "class")) {
|
| 87 |
bgadell |
126 |
$t->{available} .= " | *schedule conflict*" unless $t->{signedup};
|
| 85 |
bgadell |
127 |
} elsif (signUpEligible ($ORCUSER, $t, "class")) {
|
| 196 |
- |
128 |
# SIGN UP
|
|
|
129 |
$t->{available} .= " | ".$h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[SIGN UP]");
|
|
|
130 |
}
|
|
|
131 |
if ($LVL > 4 or $ORCUSER->{department}->{VCI} >= 2) {
|
|
|
132 |
# ADD USER
|
|
|
133 |
$t->{available} ? $t->{available} .= " | " : {};
|
|
|
134 |
$t->{available} .= $h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");
|
|
|
135 |
}
|
|
|
136 |
|
|
|
137 |
return $t->{available};
|
| 56 |
bgadell |
138 |
}
|
|
|
139 |
|
|
|
140 |
sub filter_available {
|
|
|
141 |
my $colName = shift;
|
| 196 |
- |
142 |
my $filter = shift;
|
|
|
143 |
|
|
|
144 |
if (defined $filter) {
|
|
|
145 |
if ($filter eq "Full") {
|
|
|
146 |
return "$colName = 0";
|
|
|
147 |
}
|
|
|
148 |
return "$colName > 0";
|
|
|
149 |
} else {
|
|
|
150 |
my $Options = "<OPTION></OPTION>"."<OPTION>Available</OPTION>"."<OPTION>Full</OPTION>";
|
| 234 |
- |
151 |
my $tmpfilter = getFilterValue ($colName);
|
| 196 |
- |
152 |
|
|
|
153 |
$Options =~ s/>($tmpfilter)/ selected>$1/;
|
|
|
154 |
return "<SELECT name=filter-${colName} onChange='page.value = 1; submit();'>$Options</SELECT>";
|
|
|
155 |
}
|
| 56 |
bgadell |
156 |
}
|
|
|
157 |
|
|
|
158 |
sub modify_time {
|
|
|
159 |
my $t = shift;
|
|
|
160 |
return convertTime $t->{time};
|
|
|
161 |
}
|
|
|
162 |
|
|
|
163 |
sub modify_start_time {
|
|
|
164 |
my $t = shift;
|
|
|
165 |
return convertTime $t->{start_time};
|
|
|
166 |
}
|
|
|
167 |
|
|
|
168 |
sub modify_end_time {
|
|
|
169 |
my $t = shift;
|
|
|
170 |
return convertTime $t->{end_time};
|
|
|
171 |
}
|
|
|
172 |
|
| 112 |
- |
173 |
sub modify_stars {
|
|
|
174 |
my $t = shift;
|
| 196 |
- |
175 |
if ($t->{coach} eq $ORCUSER->{derby_name} or $LVL >= RollerCon::ADMIN or $ORCUSER->{department}->{MVP} >= RollerCon::MANAGER) {
|
| 112 |
- |
176 |
$t->{stars} = $t->{stars};
|
|
|
177 |
} else {
|
|
|
178 |
$t->{stars} = ' ';
|
|
|
179 |
}
|
|
|
180 |
}
|
| 56 |
bgadell |
181 |
|
| 112 |
- |
182 |
sub modify_responses {
|
|
|
183 |
my $t = shift;
|
| 196 |
- |
184 |
if ($t->{coachRCid} == $ORCUSER->{RCid} or $LVL >= RollerCon::ADMIN or $ORCUSER->{department}->{MVP} >= RollerCon::MANAGER) {
|
| 112 |
- |
185 |
$t->{responses} = $t->{responses} // '0';
|
|
|
186 |
} else {
|
|
|
187 |
$t->{responses} = ' ';
|
|
|
188 |
}
|
|
|
189 |
}
|
|
|
190 |
|
| 196 |
- |
191 |
# If we need to modify how a filter works, create a subroutine named "filter_$columnname"
|
|
|
192 |
# It will receive two fields, the field name and the current filter value (if any)
|
| 112 |
- |
193 |
|
| 196 |
- |
194 |
# Uncomment and update if we want to enable clicking on a row to open a new page.
|
|
|
195 |
#
|
|
|
196 |
sub addRowClick {
|
|
|
197 |
my $t = shift;
|
| 56 |
bgadell |
198 |
|
| 196 |
- |
199 |
if ($LVL >= RollerCon::ADMIN or $ORCUSER->{department}->{MVP} >= RollerCon::VOLUNTEER or $ORCUSER->{department}->{COA} >= RollerCon::VOLUNTEER) {
|
|
|
200 |
return "location.href='view_class.pl?id=$t->{id}&choice=View'";
|
| 56 |
bgadell |
201 |
} else {
|
| 196 |
- |
202 |
return "";
|
| 56 |
bgadell |
203 |
}
|
|
|
204 |
}
|
|
|
205 |
|
| 196 |
- |
206 |
# Call the function to print the table view page (with available options)
|
| 56 |
bgadell |
207 |
|
| 196 |
- |
208 |
printTablePage ({ Title => $pageTitle,
|
|
|
209 |
Table => $DBTABLE,
|
|
|
210 |
Columns => \%COLUMNS,
|
|
|
211 |
RCAuth => $RCAUTH_cookie,
|
|
|
212 |
DisplayYearSelect => 1,
|
| 199 |
- |
213 |
ShowMyShifts => 1,
|
| 196 |
- |
214 |
PersonalTimeButton => 1,
|
| 222 |
- |
215 |
HeaderButton => { field => "id",
|
|
|
216 |
button => $h->input ({ type=>"button", value=>"Add", onClick=>"event.stopPropagation(); window.location.href='view_class.pl'" }) }
|
| 196 |
- |
217 |
});
|