]> git.imager.perl.org - bse.git/blame - site/cgi-bin/modules/BSE/UI/AdminSeminar.pm
0.15_47 commit
[bse.git] / site / cgi-bin / modules / BSE / UI / AdminSeminar.pm
CommitLineData
37dd20ad
TC
1package BSE::UI::AdminSeminar;
2use strict;
3use base qw(BSE::UI::AdminDispatch);
20d6805f 4use BSE::Util::Tags qw(tag_hash tag_error_img tag_hash_plain);
37dd20ad
TC
5use BSE::Util::DynSort qw(sorter tag_sorthelp);
6use BSE::Template;
7use BSE::Util::Iterate;
8use BSE::TB::Locations;
2076966c 9use DevHelp::HTML qw(:default popup_menu);
37dd20ad 10use constant SECT_LOCATION_VALIDATION => "BSE Location Validation";
2076966c 11use BSE::CfgInfo 'product_options';
11c35ec9 12use DevHelp::Date qw(dh_strftime_sql_datetime);
37dd20ad
TC
13
14my %rights =
15 (
20d6805f
TC
16 loclist => 'bse_location_list',
17 locaddform => 'bse_location_add',
18 locadd => 'bse_location_add',
19 locedit => 'bse_location_edit',
20 locsave => 'bse_location_edit',
21 locview => 'bse_location_view',
22 locdelask => 'bse_location_delete',
23 locdelete => 'bse_location_delete',
24 # detail => 'bse_subscr_detail',
25 # update => 'bse_subscr_update',
26 addattendseminar => 'bse_session_booking_add',
27 addattendsession => 'bse_session_booking_add',
28 addattendsave => 'bse_session_booking_add',
29 cancelbookingconfirm => 'bse_session_booking_cancel',
30 cancelbooking => 'bse_session_booking_cancel',
31 editbooking => 'bse_session_booking_edit',
32 savebooking => 'bse_session_booking_edit',
37dd20ad
TC
33 );
34
35sub actions { \%rights }
36
37sub rights { \%rights }
38
39sub default_action { 'loclist' }
40
41sub req_loclist {
42 my ($class, $req, $errors) = @_;
43
44 my $msg = $req->message($errors);
45 my $cgi = $req->cgi;
46 my @locations = BSE::TB::Locations->all;
47 my ($sortby, $reverse) =
48 sorter(data=>\@locations, cgi=>$cgi, sortby=>'description',
49 session=>$req->session,
50 name=>'locations', fields=> { id => {numeric => 1 } });
51 my $it = BSE::Util::Iterate->new;
52 my $current_loc;
53
54 my %acts;
55 %acts =
56 (
57 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
58 BSE::Util::Tags->admin(\%acts, $req->cfg),
59 BSE::Util::Tags->secure($req),
60 msg => $msg,
61 message => $msg,
62 $it->make_paged_iterator('ilocation', 'locations', \@locations, undef,
63 $cgi, undef, 'pp=20', $req->session,
64 'locations', \$current_loc),
65 sorthelp => [ \&tag_sorthelp, $sortby, $reverse ],
66 sortby=>$sortby,
67 reverse=>$reverse,
68 ifRemovable => [ \&tag_ifRemovable, \$current_loc ],
69 );
70
71 return $req->dyn_response('admin/locations/list', \%acts);
72}
73
74sub tag_ifRemovable {
75 my ($rlocation) = @_;
76
77 $$rlocation or return;
78
79 $$rlocation->is_removable;
80}
81
82sub tag_field {
83 my ($fields, $args) = @_;
84
85 my ($name, $parm) = split ' ', $args;
86
87 exists $fields->{$name}
88 or return "** Unknown field $name **";
89 exists $fields->{$name}{$parm}
90 or return '';
91
92 return escape_html($fields->{$name}{$parm});
93}
94
95sub req_locaddform {
96 my ($class, $req, $errors) = @_;
97
98 my $msg = $req->message($errors);
99
100 my %fields = BSE::TB::Location->valid_fields();
16ac5598 101 my $cfg_fields = $req->configure_fields(\%fields, SECT_LOCATION_VALIDATION);
37dd20ad
TC
102
103 my %acts;
104 %acts =
105 (
106 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
107 BSE::Util::Tags->admin(\%acts, $req->cfg),
108 BSE::Util::Tags->secure($req),
109 msg => $msg,
110 message => $msg,
111 error_img => [ \&tag_error_img, $req->cfg, $errors ],
16ac5598 112 field => [ \&tag_field, $cfg_fields ],
37dd20ad
TC
113 );
114
115 return $req->dyn_response('admin/locations/add', \%acts);
116}
117
118sub req_locadd {
119 my ($class, $req) = @_;
120
121 my $cgi = $req->cgi;
122 my $cfg = $req->cfg;
123 my %fields = BSE::TB::Location->valid_fields($cfg);
124 my %rules = BSE::TB::Location->valid_rules($cfg);
125 my %errors;
126 $req->validate(errors=> \%errors,
127 fields=> \%fields,
128 rules => \%rules,
129 section => SECT_LOCATION_VALIDATION);
130
131 keys %errors
132 and return $class->req_locaddform($req, \%errors);
133
134 my %location;
135 for my $field (keys %fields) {
136 $location{$field} = $cgi->param($field);
137 }
138 $location{disabled} = 0;
139 my @cols = BSE::TB::Location->columns;
140 shift @cols;
141 my $loc = BSE::TB::Locations->add(@location{@cols});
142
143 my $r = $class->_loclist_refresh($req, "Location $location{description} added");
144
145 return BSE::Template->get_refresh($r, $req->cfg);
146}
147
148sub _loc_show_common {
149 my ($class, $req, $errors, $template) = @_;
150
151 my $loc_id = $req->cgi->param('id');
152 $loc_id && $loc_id =~ /^\d+/
153 or return $class->req_loclist
154 ($req, { id=>'Missing or invalid location id' });
155 my $location = BSE::TB::Locations->getByPkey($loc_id);
156 $location
157 or return $class->req_loclist
158 ($req, { id=>'Unknown location id' });
159
160 my $msg = $req->message($errors);
161
162 my %fields = BSE::TB::Location->valid_fields();
16ac5598 163 my $cfg_fields = $req->configure_fields(\%fields, SECT_LOCATION_VALIDATION);
37dd20ad 164
2076966c
TC
165 my $it = BSE::Util::Iterate->new;
166
37dd20ad
TC
167 my %acts;
168 %acts =
169 (
170 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
171 BSE::Util::Tags->admin(\%acts, $req->cfg),
172 BSE::Util::Tags->secure($req),
173 msg => $msg,
174 message => $msg,
175 error_img => [ \&tag_error_img, $req->cfg, $errors ],
176 location => [ \&tag_hash, $location ],
16ac5598 177 field => [ \&tag_field, $cfg_fields ],
2076966c
TC
178 $it->make_iterator([ \&iter_locsessions, $location ],
179 'session', 'sessions'),
37dd20ad
TC
180 );
181
2076966c
TC
182 my $t = $req->cgi->param('_t');
183 if ($t && $t =~ /^\w+$/) {
184 $template .= "_$t";
185 }
186
37dd20ad
TC
187 return $req->dyn_response($template, \%acts);
188}
189
2076966c
TC
190sub iter_locsessions {
191 my ($location) = @_;
192
193 $location->sessions_detail;
194}
195
37dd20ad
TC
196sub req_locedit {
197 my ($class, $req, $errors) = @_;
198
199 return $class->_loc_show_common($req, $errors, 'admin/locations/edit');
200}
201
202sub req_locsave {
203 my ($class, $req) = @_;
204
205 my $loc_id = $req->cgi->param('id');
206 $loc_id && $loc_id =~ /^\d+/
207 or return $class->req_loclist
208 ($req, { id=>'Missing or invalid location id' });
209 my $location = BSE::TB::Locations->getByPkey($loc_id);
210 $location
211 or return $class->req_loclist
212 ($req, { id=>'Unknown location id' });
213
214 my $cgi = $req->cgi;
215 my $cfg = $req->cfg;
216 my %fields = $location->valid_fields($cfg);
217 my %rules = $location->valid_rules($cfg);
218 my %errors;
219 $req->validate(errors=> \%errors,
220 fields=> \%fields,
221 rules => \%rules,
222 section => SECT_LOCATION_VALIDATION);
223
224 keys %errors
225 and return $class->req_locedit($req, \%errors);
226
227 for my $field (keys %fields) {
228 my $value = $cgi->param($field);
229 $location->{$field} = $value if defined $value;
230 }
231
232 if ($cgi->param('save_disabled')) {
233 $location->{disabled} = $cgi->param('disabled') ? 1 : 0;
234 }
235
236 $location->save;
237
238 my $r = $class->_loclist_refresh($req,
239 "Location $location->{description} saved");
240
241 return BSE::Template->get_refresh($r, $req->cfg);
242}
243
2076966c
TC
244sub req_locview {
245 my ($class, $req, $errors) = @_;
246
247 return $class->_loc_show_common($req, $errors, 'admin/locations/view');
248}
249
37dd20ad
TC
250sub req_locdelask {
251 my ($class, $req, $errors) = @_;
252
253 return $class->_loc_show_common($req, $errors, 'admin/locations/delete');
254}
255
256sub req_locdelete {
257 my ($class, $req) = @_;
258
259 my $loc_id = $req->cgi->param('id');
260 $loc_id && $loc_id =~ /^\d+/
261 or return $class->req_loclist
262 ($req, { id=>'Missing or invalid location id' });
263 my $location = BSE::TB::Locations->getByPkey($loc_id);
264 $location
265 or return $class->req_loclist
266 ($req, { id=>'Unknown location id' });
267
268 $location->is_removable
269 or return $class->req_loclist
270 ($req, { id=>"Location $location->{description} cannot be removed" });
271
272 my $description = $location->{description};
273 $location->remove;
274
275 my $r = $class->_loclist_refresh($req,
276 "Location $description removed");
277
278 return BSE::Template->get_refresh($r, $req->cfg);
279}
280
281sub _loclist_refresh {
282 my ($class, $req, $msg) = @_;
283
284 my $r = $req->cgi->param('r') || $req->cgi->param('refreshto');
285 unless ($r) {
286 $r = "/cgi-bin/admin/admin_seminar.pl";
287 }
288 if ($msg && $r !~ /[&?]m=/) {
289 my $sep = $r =~ /\?/ ? '&' : '?';
290
291 $r .= $sep . "m=" . escape_uri($msg);
292 }
293
294 return $r;
295}
296
718a070d
TC
297sub req_addattendseminar {
298 my ($class, $req, $errors) = @_;
299
300 # make sure we're passed a valid siteuser_id
301 my $cgi = $req->cgi;
302 my $siteuser_id = $cgi->param('siteuser_id');
303 defined $siteuser_id && $siteuser_id =~ /^\d+$/
304 or return $class->req_loclist($req, { siteuser_id =>
305 "Missing or invalid siteuser_id" });
306 require SiteUsers;
307 my $siteuser = SiteUsers->getByPkey($siteuser_id)
308 or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
309 my $msg = $req->message($errors);
310 require BSE::TB::Seminars;
311 my @seminars = BSE::TB::Seminars->all;
312
313 my $it = BSE::Util::Iterate->new;
314 my %acts;
315 %acts =
316 (
317 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
318 BSE::Util::Tags->admin(\%acts, $req->cfg),
319 BSE::Util::Tags->secure($req),
320 $it->make_iterator(undef, 'seminar', 'seminars', \@seminars),
321 siteuser => [ \&tag_hash, $siteuser ],
322 msg => $msg,
323 message => $msg,
324 error_img => [ \&tag_error_img, $req->cfg, $errors ],
325 );
326
327 return $req->dyn_response('admin/addattendee1.tmpl', \%acts);
328}
329
330sub req_addattendsession {
331 my ($class, $req, $errors) = @_;
332
333 # make sure we're passed a valid siteuser_id
334 my $cgi = $req->cgi;
335 my $siteuser_id = $cgi->param('siteuser_id');
336 defined $siteuser_id && $siteuser_id =~ /^\d+$/
337 or return $class->req_loclist($req, { siteuser_id =>
338 "Missing or invalid siteuser_id" });
339 require SiteUsers;
340 my $siteuser = SiteUsers->getByPkey($siteuser_id)
341 or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
342
343 # make sure we got a valid seminar
344 require BSE::TB::Seminars;
345 my $seminar_id = $cgi->param('seminar_id');
346 defined $seminar_id && $seminar_id =~ /^\d*$/
347 or return $class->req_addattendseminar
348 ($req, { seminar_id => "Missing or invalid seminar_id" });
349 $seminar_id
350 or return $class->req_addattendseminar
351 ($req, { seminar_id => "Please select a seminar" });
352 my $seminar = BSE::TB::Seminars->getByPkey($seminar_id)
353 or return $class->req_addattendseminar
354 ($req, { seminar_id => "Unknown seminar_id" });
355 my $msg = $req->message($errors);
356
20d6805f 357 my @sem_options = _get_sem_options($req->cfg, $seminar);
2076966c
TC
358 my $current_option;
359
718a070d
TC
360 my @sessions = $seminar->session_info;
361 my %user_booked = map { $_=>1 }
362 $siteuser->seminar_sessions_booked($seminar_id);
363 @sessions = grep !$user_booked{$_->{id}}, @sessions;
364
365 my $it = BSE::Util::Iterate->new;
366 my %acts;
367 %acts =
368 (
369 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
370 BSE::Util::Tags->admin(\%acts, $req->cfg),
371 BSE::Util::Tags->secure($req),
372 siteuser => [ \&tag_hash, $siteuser ],
373 seminar => [ \&tag_hash, $seminar ],
374 msg => $msg,
375 message => $msg,
376 error_img => [ \&tag_error_img, $req->cfg, $errors ],
377 $it->make_iterator(undef, 'session', 'sessions', \@sessions),
2076966c
TC
378 $it->make_iterator(undef, 'option', 'options', \@sem_options,
379 undef, undef, \$current_option),
380 option_popup => [ \&tag_option_popup, $req->cgi, \$current_option ],
718a070d
TC
381 );
382
383 return $req->dyn_response('admin/addattendee2.tmpl', \%acts);
384}
385
2076966c
TC
386sub tag_option_popup {
387 my ($cgi, $roption) = @_;
388
389 $$roption
390 or return '** popup_option not in options iterator **';
391
392 my $option = $$roption;
393
394 my @extras;
20d6805f
TC
395 my $value = $cgi->param($option->{id});
396 defined $value or $value = $option->{value};
397 if ($value) {
398 push @extras, -default => $value;
2076966c
TC
399 }
400
401 return popup_menu(-name => $option->{id},
402 -values => $option->{values},
403 -labels => $option->{labels},
404 @extras);
405}
406
718a070d
TC
407sub req_addattendsave {
408 my ($class, $req, $errors) = @_;
409
410 # make sure we're passed a valid siteuser_id
411 my $cgi = $req->cgi;
412 my $siteuser_id = $cgi->param('siteuser_id');
413 defined $siteuser_id && $siteuser_id =~ /^\d+$/
414 or return $class->req_loclist($req, { siteuser_id =>
415 "Missing or invalid siteuser_id" });
416 require SiteUsers;
417 my $siteuser = SiteUsers->getByPkey($siteuser_id)
418 or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
419
420 # make sure we got a valid seminar
421 require BSE::TB::Seminars;
422 my $seminar_id = $cgi->param('seminar_id');
423 defined $seminar_id && $seminar_id =~ /^\d*$/
424 or return $class->req_addattendseminar
425 ($req, { seminar_id => "Missing or invalid seminar_id" });
426 $seminar_id
427 or return $class->req_addattendseminar
428 ($req, { seminar_id => "Please select a seminar" });
429 my $seminar = BSE::TB::Seminars->getByPkey($seminar_id)
430 or return $class->req_addattendseminar
431 ($req, { seminar_id => "Unknown seminar_id" });
432 my $msg = $req->message($errors);
433
434 # make sure we get a valid session
435 require BSE::TB::SeminarSessions;
436 my $session_id = $cgi->param('session_id');
437 defined $session_id && $session_id =~ /^\d*$/
438 or return $class->req_addattendsession
439 ($req, { session_id => "Missing or invalid session_id" });
440 $session_id
441 or return $class->req_addattendsession
442 ($req, { session_id => "Please select a session" });
443 my $session = BSE::TB::SeminarSessions->getByPkey($session_id)
444 or return $class->req_addattendsession
445 ($req, { session_id => "Unknown session_id" });
446
2076966c
TC
447 # accumulate the options
448 my %errors;
449 my @options;
450 for my $opt_name (split /,/, $seminar->{options}) {
451 my $value = $cgi->param($opt_name);
452 defined $value
453 or return $class->req_addattendsession
454 ($req, { opt_name => "Missing value for $opt_name" });
455
456 push @options, $value;
457 }
458
459 my %more;
460 for my $name (qw/customer_instructions support_notes roll_present/) {
461 my $value = $cgi->param($name);
462 $value and $more{$name} = $value;
463 }
464 $more{roll_present} ||= 0;
20d6805f 465 $more{options} = join(',', @options);
2076966c 466
718a070d 467 eval {
20d6805f 468 $session->add_attendee($siteuser, %more);
718a070d
TC
469 };
470 if ($@) {
471 if ($@ =~ /duplicate/i) {
472 return $class->req_addattendsession
473 ($req, { session_id => "User already booked for this session" });
474 }
11c35ec9
TC
475 else {
476 return $class->req_addattendsession
477 ($req, { _error => $@ });
478 }
718a070d
TC
479 }
480
20d6805f
TC
481 require BSE::ComposeMail;
482 my $cfg = $req->cfg;
483 my $mailer = BSE::ComposeMail->new(cfg => $cfg);
484 my $subject = $cfg->entry('seminars', 'booked_notify_subject',
485 'You have been booked for seminar');
486 my @sem_options = _get_sem_options($cfg, $seminar, @options);
487 my $it = DevHelp::Tags::Iterate->new;
488 my %acts;
489 %acts =
490 (
491 BSE::Util::Tags->static(undef, $cfg),
11c35ec9 492 user => [ \&tag_hash_plain, $siteuser ],
20d6805f
TC
493 seminar => [ \&tag_hash_plain, $seminar ],
494 session => [ \&tag_hash_plain, $session ],
495 booking => [ \&tag_hash_plain, \%more ],
496 location => [ \&tag_hash_plain, $session->location ],
497 $it->make_iterator(undef, 'option', 'options', \@sem_options),
498 );
499
500 unless ($mailer->send(to => $siteuser,
501 subject => $subject,
502 template => 'user/admin_book_seminar',
503 acts => \%acts)) {
504 return $class->req_addattendsession
505 ($req, { _email => "The user has been booked, but there was an error seding the email notification:".$mailer->errstr });
506 }
507
508
718a070d
TC
509 my $r = $cgi->param('r');
510 unless ($r) {
511 $r = "/cgi-bin/admin/siteusers.pl?a_edit=1&id=" . $siteuser->{id};
512 }
718a070d
TC
513
514 return BSE::Template->get_refresh($r, $req->cfg);
515}
516
20d6805f
TC
517sub req_cancelbookingconfirm {
518 my ($class, $req, $message) = @_;
519
520 my $cgi = $req->cgi;
521
11c35ec9
TC
522 my $id = $cgi->param('id');
523 defined $id && $id =~ /^\d+$/
524 or return $class->error($req, "id parameter invalid");
20d6805f 525
11c35ec9
TC
526 require BSE::TB::SeminarBookings;
527 my $booking = BSE::TB::SeminarBookings->getByPkey($id)
528 or return $class->error($req, "booking $id not found");
20d6805f 529
11c35ec9
TC
530 my $session = $booking->session;
531 my $siteuser = $booking->siteuser;
20d6805f
TC
532
533 my $seminar = $session->seminar;
534 my @sem_options = _get_sem_options($req->cfg, $seminar,
535 split /,/, $session->{options});
536
537 defined $message or $message = '';
538 $message = escape_html($message);
539
540 my $it = BSE::Util::Iterate->new;
541 my %acts;
542 %acts =
543 (
544 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
545 BSE::Util::Tags->admin(\%acts, $req->cfg),
546 BSE::Util::Tags->secure($req),
547 siteuser => [ \&tag_hash, $siteuser ],
548 session => [ \&tag_hash, $session ],
549 seminar => [ \&tag_hash, $seminar ],
550 location => [ \&tag_hash, $session->location ],
551 booking => [ \&tag_hash, $booking ],
552 message => $message,
553 $it->make_iterator(undef, 'option', 'options', \@sem_options),
554 );
555
556 return $req->dyn_response('admin/semcancelbooking', \%acts);
557}
558
559sub req_cancelbooking {
560 my ($class, $req) = @_;
561
562 my $cgi = $req->cgi;
563
11c35ec9
TC
564 my $id = $cgi->param('id');
565 defined $id && $id =~ /^\d+$/
566 or return $class->error($req, "id parameter invalid");
20d6805f 567
11c35ec9
TC
568 require BSE::TB::SeminarBookings;
569 my $booking = BSE::TB::SeminarBookings->getByPkey($id)
570 or return $class->error($req, "booking $id not found");
20d6805f 571
11c35ec9
TC
572 my $session = $booking->session;
573 my $siteuser = $booking->siteuser;
20d6805f
TC
574
575 my @options = split /,/, $booking->{options};
576 local $SIG{__DIE__};
577 eval {
578 $session->remove_booking($siteuser);
579 };
580 $@ and return $class->req_cancelbookingconfirm
581 ($req, "Could not remove booking $@");
582
583 my $seminar = $session->seminar;
584
585 my @sem_options = _get_sem_options($req->cfg, $seminar, @options);
586
587 require BSE::ComposeMail;
588 my $cfg = $req->cfg;
589 my $mailer = BSE::ComposeMail->new(cfg => $cfg);
590 my $subject = $cfg->entry('seminars', 'unbooked_notify_subject',
591 'Your seminar booking has been cancelled');
592 my $it = DevHelp::Tags::Iterate->new;
593 my %acts;
594 %acts =
595 (
596 BSE::Util::Tags->static(undef, $cfg),
11c35ec9 597 user => [ \&tag_hash_plain, $siteuser ],
20d6805f
TC
598 seminar => [ \&tag_hash_plain, $seminar ],
599 session => [ \&tag_hash_plain, $session ],
600 booking => [ \&tag_hash_plain, $booking ],
601 location => [ \&tag_hash_plain, $session->location ],
602 $it->make_iterator(undef, 'option', 'options', \@sem_options),
603 );
604
605 unless ($mailer->send(to => $siteuser,
606 subject => $subject,
607 template => 'user/admin_unbook_seminar',
608 acts => \%acts)) {
609 return $class->req_cancelbookingconfirm
610 ($req, "The user booking was cancelled, but there was an error sending the email notification:".$mailer->errstr );
611 }
612
613 my $r = $cgi->param('r');
614 unless ($r) {
615 $r = '/cgi-bin/admin/siteusers.pl?a_view=1&id='.$siteuser->{id};
616 }
617 $r .= $r =~ /\?/ ? '&' : '?';
618 $r .= "m=Booking+cancelled";
619
620 return BSE::Template->get_refresh($r, $req->cfg);
621}
622
623sub req_editbooking {
624 my ($class, $req, $errors) = @_;
625
626 my $cgi = $req->cgi;
627
11c35ec9
TC
628 my $id = $cgi->param('id');
629 defined $id && $id =~ /^\d+$/
630 or return $class->error($req, "id parameter invalid");
20d6805f 631
11c35ec9
TC
632 require BSE::TB::SeminarBookings;
633 my $booking = BSE::TB::SeminarBookings->getByPkey($id)
634 or return $class->error($req, "booking $id not found");
20d6805f 635
11c35ec9 636 my $session = $booking->session;
20d6805f 637
11c35ec9 638 my $siteuser = $booking->siteuser;
20d6805f
TC
639
640 my $message = $req->message($errors);
641
642 my $seminar = $session->seminar;
643 my @sem_options = _get_sem_options($req->cfg, $seminar,
644 split /,/, $booking->{options});
11c35ec9
TC
645 my @unbooked = $seminar->get_unbooked_by_user($siteuser);
646 @unbooked = sort { $b->{when_at} cmp $a->{when_at} } ( @unbooked, $session );
20d6805f
TC
647
648 my $current_option;
649 my $it = BSE::Util::Iterate->new;
650 my %acts;
651 %acts =
652 (
653 BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
654 BSE::Util::Tags->admin(\%acts, $req->cfg),
655 BSE::Util::Tags->secure($req),
656 siteuser => [ \&tag_hash, $siteuser ],
657 session => [ \&tag_hash, $session ],
658 seminar => [ \&tag_hash, $seminar ],
659 location => [ \&tag_hash, $session->location ],
660 booking => [ \&tag_hash, $booking ],
661 message => $message,
662 error_img => [ \&tag_error_img, $req->cfg, $errors ],
663 $it->make_iterator(undef, 'option', 'options', \@sem_options,
664 undef, undef, \$current_option),
665 option_popup => [ \&tag_option_popup, $req->cgi, \$current_option ],
11c35ec9
TC
666 $it->make_iterator(undef, 'isession', 'sessions', \@unbooked),
667 session_popup => [ \&tag_session_popup, $booking, $req->cgi, \@unbooked ],
20d6805f
TC
668 );
669
670 return $req->dyn_response('admin/semeditbooking', \%acts);
671}
672
673sub req_savebooking {
674 my ($class, $req, $message) = @_;
675
676 my $cgi = $req->cgi;
677
11c35ec9
TC
678 my $id = $cgi->param('id');
679 defined $id && $id =~ /^\d+$/
680 or return $class->error($req, "id parameter invalid");
20d6805f 681
11c35ec9
TC
682 require BSE::TB::SeminarBookings;
683 my $booking = BSE::TB::SeminarBookings->getByPkey($id)
684 or return $class->error($req, "booking $id not found");
20d6805f 685
11c35ec9
TC
686 my @cols = $booking->columns;
687 shift @cols;
688 for my $name (@cols) {
20d6805f 689 my $value = $cgi->param($name);
11c35ec9 690 defined $value and $booking->set($name => $value);
20d6805f 691 }
11c35ec9 692 my $seminar = $booking->session->seminar;
20d6805f
TC
693 my @options;
694 for my $name (split /,/, $seminar->{options}) {
695 push @options, ($cgi->param($name))[0];
696 }
11c35ec9 697 $booking->{options} = join ',', @options;
20d6805f
TC
698
699 eval {
11c35ec9 700 $booking->save;
20d6805f
TC
701 };
702 $@
703 and return $class->req_editbooking($req, { error => $@ });
704
705 my @sem_options = _get_sem_options($req->cfg, $seminar, @options);
706
11c35ec9
TC
707 my $session = $booking->session;
708 my $siteuser = $booking->siteuser;
20d6805f
TC
709 require BSE::ComposeMail;
710 my $cfg = $req->cfg;
711 my $mailer = BSE::ComposeMail->new(cfg => $cfg);
712 my $subject = $cfg->entry('seminars', 'edit_notify_subject',
713 'Your seminar booking has been changed');
714 my $it = DevHelp::Tags::Iterate->new;
715 my %acts;
716 %acts =
717 (
718 BSE::Util::Tags->static(undef, $cfg),
11c35ec9 719 user => [ \&tag_hash_plain, $siteuser ],
20d6805f
TC
720 seminar => [ \&tag_hash_plain, $seminar ],
721 session => [ \&tag_hash_plain, $session ],
722 booking => [ \&tag_hash_plain, $booking ],
723 location => [ \&tag_hash_plain, $session->location ],
724 $it->make_iterator(undef, 'option', 'options', \@sem_options),
725 );
726
727 unless ($mailer->send(to => $siteuser,
728 subject => $subject,
729 template => 'user/admin_edit_seminar',
730 acts => \%acts)) {
731 return $class->req_editbooking
732 ($req, _email => "The user booking was changed, but there was an error sending the email notification:".$mailer->errstr );
733 }
734
735 my $r = $cgi->param('r');
736 unless ($r) {
737 $r = '/cgi-bin/admin/siteusers.pl?a_view=1&id='.$siteuser->{id};
738 }
739 $r .= $r =~ /\?/ ? '&' : '?';
740 $r .= "m=Booking+updated";
741
742 return BSE::Template->get_refresh($r, $req->cfg);
743}
744
745sub _get_sem_options {
746 my ($cfg, $seminar, @values) = @_;
747
748 my $avail_options = product_options($cfg);
749 my @opt_names = split /,/, $seminar->{options};
750 push @values, '' while @values < @opt_names;
751 my %values;
752 @values{@opt_names} = @values;
753
754 my @sem_options = map
755 +{
756 id => $_,
757 %{$avail_options->{$_}},
758 value => $values{$_},
759 }, @opt_names;
760 for my $option (@sem_options) {
761 $option->{display} = $option->{labels}{$option->{value}};
762 }
763
764 return @sem_options;
765}
766
11c35ec9
TC
767sub tag_session_popup {
768 my ($booking, $cgi, $unbooked) = @_;
769
770 my $default = $cgi->param('session_id');
771 defined $default or $default = $booking->{session_id};
772 my %locations;
773 for my $session (@$unbooked) {
774 unless ($locations{$session->{location_id}}) {
775 $locations{$session->{location_id}} = $session->location;
776 }
777 }
778
779 return popup_menu
780 (-name => 'session_id',
781 -values => [ map $_->{id}, @$unbooked ],
782 -labels =>
783 { map
784 { $_->{id} =>
785 _session_desc($_, $locations{$_->{location_id}})
786 } @$unbooked
787 },
788 -default => $default);
789}
790
791sub _session_desc {
792 my ($session, $location) = @_;
793
794 $location->{description} . ' ' .
795 dh_strftime_sql_datetime("%H:%M %d %b %Y", $session->{when_at});
796}
797
37dd20ad 7981;