0.15_51 commit r0_15_51
authorTony Cook <tony@develop-help.com>
Fri, 27 Oct 2006 03:58:57 +0000 (03:58 +0000)
committertony <tony@45cb6cf1-00bc-42d2-bb5a-07f51df49f94>
Fri, 27 Oct 2006 03:58:57 +0000 (03:58 +0000)
17 files changed:
MANIFEST
Makefile
site/cgi-bin/bse.cfg
site/cgi-bin/modules/BSE/Edit/Article.pm
site/cgi-bin/modules/BSE/Edit/Seminar.pm
site/cgi-bin/modules/BSE/UI/User.pm
site/cgi-bin/modules/BSE/UserReg.pm
site/docs/bse.pod
site/templates/admin/semcancelbooking.tmpl
site/templates/admin/user_edit_seminar.tmpl [new file with mode: 0644]
site/templates/admin/user_unbook_seminar.tmpl [new file with mode: 0644]
site/templates/user/base_bookingdetail.tmpl [new file with mode: 0644]
site/templates/user/base_bookinglist.tmpl [new file with mode: 0644]
site/templates/user/base_cancelbooking.tmpl [new file with mode: 0644]
site/templates/user/base_editbooking.tmpl [new file with mode: 0644]
site/templates/user/email_edit_seminar.tmpl [new file with mode: 0644]
site/templates/user/email_unbook_seminar.tmpl [new file with mode: 0644]

index 369a2e7..f4b75a7 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -392,6 +392,8 @@ site/templates/admin/users/list_low.tmpl
 site/templates/admin/users/view.tmpl
 site/templates/admin/users/view_bookings.tmpl
 site/templates/admin/user_book_seminar.tmpl
+site/templates/admin/user_edit_seminar.tmpl
+site/templates/admin/user_unbook_seminar.tmpl
 site/templates/admin/xbase.tmpl
 site/templates/affiliate.tmpl
 site/templates/base.tmpl
@@ -460,10 +462,14 @@ site/templates/user/admin_book_seminar.tmpl
 site/templates/user/admin_edit_seminar.tmpl
 site/templates/user/admin_unbook_seminar.tmpl
 site/templates/user/alreadyblacklisted_base.tmpl
-site/templates/user/base_orderdetail.tmpl
+site/templates/user/base_bookingdetail.tmpl
+site/templates/user/base_bookinglist.tmpl
 site/templates/user/base_bookcomplete.tmpl
 site/templates/user/base_bookconfirm.tmpl
 site/templates/user/base_bookseminar.tmpl
+site/templates/user/base_cancelbooking.tmpl
+site/templates/user/base_editbooking.tmpl
+site/templates/user/base_orderdetail.tmpl
 site/templates/user/blacklistdone_base.tmpl
 site/templates/user/cantunsub_base.tmpl
 site/templates/user/confirmed_base.tmpl
@@ -472,6 +478,8 @@ site/templates/user/confsent_nop_base.tmpl
 site/templates/user/email_conferror_base.tmpl
 site/templates/user/email_confirm.tmpl
 site/templates/user/email_confirm_nop.tmpl
+site/templates/user/email_edit_seminar.tmpl
+site/templates/user/email_unbook_seminar.tmpl
 site/templates/user/logon_base.tmpl
 site/templates/user/lostemailsent_base.tmpl
 site/templates/user/lostpassword_base.tmpl
index 14b6048..abf1595 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.15_50
+VERSION=0.15_51
 DISTNAME=bse-$(VERSION)
 DISTBUILD=$(DISTNAME)
 DISTTAR=../$(DISTNAME).tar
index bd14ab3..8fb4dad 100644 (file)
@@ -17,6 +17,10 @@ dynamic_cache=$(paths/downloads)/../cache
 [pregenerate]
 
 ; the following are required by the system - don't modify them
+user/editbooking.tmpl = user,user/base_editbooking.tmpl
+user/bookingdetail.tmpl = user,user/base_bookingdetail.tmpl
+user/cancelbooking.tmpl = user,user/base_cancelbooking.tmpl
+user/bookinglist.tmpl = user,user/base_bookinglist.tmpl
 user/orderdetail.tmpl = user,user/base_orderdetail.tmpl
 user/alreadyblacklisted.tmpl = user,user/alreadyblacklisted_base.tmpl
 user/blacklistdone.tmpl = user,user/blacklistdone_base.tmpl
index ede3375..89dfcf9 100644 (file)
@@ -1164,6 +1164,7 @@ sub edit_template {
   my $t = $cgi->param('_t');
   if ($t && $t =~ /^\w+$/) {
     $base = $t;
+    $cgi->delete('_t');
   }
   return $self->{cfg}->entry('admin templates', $base, 
                             "admin/edit_$base");
index 8ad1cff..113d867 100644 (file)
@@ -33,6 +33,7 @@ sub edit_template {
   my $t = $cgi->param('_t');
   if ($t && $t =~ /^\w+$/) {
     $base = $t;
+    $cgi->delete('_t');
   }
   return $self->{cfg}->entry('admin templates', $base, 
                             "admin/edit_$base");
@@ -541,7 +542,7 @@ sub req_delsemsession {
   }
 
   if ($other_session) {
-    $session->replace_with($other_session_id);
+    $session->replace_with($other_session);
   }
   else {
     $session->cancel;
index e6fe74c..49b3062 100644 (file)
@@ -4,6 +4,8 @@ use base 'BSE::UI::Dispatch';
 use BSE::Util::Tags qw(tag_hash tag_error_img tag_hash_plain);
 use DevHelp::HTML qw(:default popup_menu);
 use BSE::Util::Iterate;
+use BSE::Util::SQL qw/now_datetime/;
+use DevHelp::Date qw(dh_strftime_sql_datetime);
 
 my %actions =
   (
@@ -11,10 +13,16 @@ my %actions =
    bookconfirm => 1,
    book => 1,
    bookcomplete => 1,
+   bookinglist => 1,
+   bookingdetail => 1,
+   cancelbookingconfirm => 1,
+   cancelbooking => 1,
+   editbooking => 1,
+   savebooking => 1,
   );
 
 sub default_action {
-  'error';
+  'bookinglist';
 }
 
 sub actions {
@@ -56,28 +64,12 @@ sub req_bookseminar {
      $it->make_iterator(undef, 'session', 'sessions', \@sessions),
      $it->make_iterator(undef, 'option', 'options', \@options, 
                        undef, undef, \$current_option),
-     option_popup => [ \&tag_option_popup, \$current_option ],
+     option_popup => [ \&tag_option_popup, $cgi, \$current_option ],
     );
 
   return $req->dyn_response('user/bookseminar', \%acts);
 }
 
-sub tag_option_popup {
-  my ($roption) = @_;
-
-  $$roption 
-    or return '** popup_option not in options iterator **';
-
-  my $option = $$roption;
-
-  my $value = $option->{value} || $option->{values}[0];
-
-  return popup_menu(-name => $option->{id},
-                   -values => $option->{values},
-                   -labels => $option->{labels},
-                   -default => $value);
-}
-
 sub req_bookconfirm {
   my ($self, $req) = @_;
 
@@ -182,7 +174,6 @@ sub req_book {
   if ($cfg->entry('seminars', 'notify_user_booking', 1)) {
     my $email = $cfg->entry('seminar', 'notify_user_booking_email')
       || $cfg->entry('shop', 'from', $Constants::SHOP_FROM);
-    my $from = $cfg->entry('shop', 'from', $Constants::SHOP_FROM);
     my $subject = $cfg->entry('seminar', 'notify_user_booking_subject',
                              'A user has booked a seminar session');
     my @sem_options = $seminar->option_descs($cfg, \@opt_values);
@@ -200,7 +191,6 @@ sub req_book {
     require BSE::ComposeMail;
     my $mailer = BSE::ComposeMail->new(cfg => $cfg);
     unless ($mailer->send(to      => $email,
-                         from     => $from,
                          subject  => $subject,
                          template => 'admin/user_book_seminar',
                          acts     => \%acts)) {
@@ -240,7 +230,7 @@ sub req_bookcomplete {
   my @opt_values = split /,/, $booking->{options};
   my @options = $seminar->option_descs($req->cfg, \@opt_values);
   my %acts;
-  my $message = $req->message();
+  my $message ||= $req->message();
   my $it = BSE::Util::Iterate->new;
   %acts =
     (
@@ -256,6 +246,331 @@ sub req_bookcomplete {
   return $req->dyn_response('user/bookcomplete', \%acts);
 }
 
+sub req_bookinglist {
+  my ($class, $req, $message) = @_;
+
+  my @bookings = $req->siteuser->seminar_bookings_detail;
+  my $now = now_datetime;
+  for my $booking (@bookings) {
+    $booking->{past} = $booking->{when_at} lt $now ? 1 : 0;
+  }
+  my $show_past = $req->cgi->param('show_past');
+  unless ($show_past) {
+    @bookings = grep !$_->{past}, @bookings;
+  }
+
+  $message ||= $req->message;
+
+  my $it = BSE::Util::Iterate->new;
+  my %acts;
+  %acts =
+    (
+     $req->dyn_user_tags(),
+     $it->make_iterator(undef, 'booking', 'bookings', \@bookings),
+     message => escape_html($message),
+    );
+
+  return $req->dyn_response('user/bookinglist', \%acts);
+}
+
+sub _show_booking {
+  my ($class, $req, $template, $errors) = @_;
+
+  my $cgi = $req->cgi;
+
+  my $id = $cgi->param('id');
+  defined $id && $id =~ /^\d+$/
+    or return $class->req_bookinglist($req, "id parameter invalid");
+
+  require BSE::TB::SeminarBookings;
+  my $booking = BSE::TB::SeminarBookings->getByPkey($id);
+  $booking && $booking->{siteuser_id} == $req->siteuser->{id}
+    or return $class->req_bookinglist($req, "booking $id not found");
+
+  my $session = $booking->session;
+
+  my $seminar = $session->seminar;
+  my @sem_options = 
+    $seminar->option_descs($req->cfg, [ split /,/, $booking->{options} ]);
+
+  my $message = $req->message($errors);
+  $message = escape_html($message);
+
+  my $it = BSE::Util::Iterate->new;
+  my %acts;
+  %acts =
+    (
+     $req->dyn_user_tags(),
+     session  => [ \&tag_hash, $session  ],
+     seminar  => [ \&tag_hash, $seminar ],
+     location => [ \&tag_hash, $session->location ],
+     booking  => [ \&tag_hash, $booking  ],
+     message  => $message,
+     $it->make_iterator(undef, 'option', 'options', \@sem_options),
+    );
+
+  return $req->dyn_response($template, \%acts);
+}
+
+sub req_bookingdetail {
+  my ($class, $req) = @_;
+
+  return $class->_show_booking($req, 'user/bookingdetail');
+}
+
+sub req_cancelbookingconfirm {
+  my ($class, $req, $message) = @_;
+
+  return $class->_show_booking($req, 'user/cancelbooking', $message);
+}
+
+sub req_cancelbooking {
+  my ($class, $req) = @_;
+
+  my $cgi = $req->cgi;
+
+  my $id = $cgi->param('id');
+  defined $id && $id =~ /^\d+$/
+    or return $class->req_bookinglist($req, "id parameter invalid");
+
+  my $siteuser = $req->siteuser;
+
+  require BSE::TB::SeminarBookings;
+  my $booking = BSE::TB::SeminarBookings->getByPkey($id);
+  $booking && $booking->{siteuser_id} == $siteuser->{id}
+    or return $class->req_bookinglist($req, "booking $id not found");
+
+  my $session = $booking->session;
+
+  $session->{when_at} gt now_datetime
+    or return $class->req_bookinglist($req, "You cannot modify past bookings");
+
+  my @options = split /,/, $booking->{options};
+  local $SIG{__DIE__};
+  eval {
+    $session->remove_booking($siteuser);
+  };
+  $@ and return $class->req_cancelbookingconfirm
+    ($req, "Could not remove booking $@");
+
+  my $seminar = $session->seminar;
+
+  my @sem_options = $seminar->option_descs($req->cfg, \@options);
+
+  require BSE::ComposeMail;
+  my $cfg = $req->cfg;
+  my $it = DevHelp::Tags::Iterate->new;
+  my %acts;
+  %acts =
+    (
+     BSE::Util::Tags->static(undef, $cfg),
+     user     => [ \&tag_hash_plain, $siteuser ],
+     seminar  => [ \&tag_hash_plain, $seminar  ],
+     session  => [ \&tag_hash_plain, $session  ],
+     booking  => [ \&tag_hash_plain, $booking  ],
+     location => [ \&tag_hash_plain, $session->location ],
+     $it->make_iterator(undef, 'option', 'options', \@sem_options),
+    );
+
+  my $mailer = BSE::ComposeMail->new(cfg => $cfg);
+  if ($cfg->entry('seminars', 'notify_user_cancel', 1)) {
+    my $email = $cfg->entry('seminar', 'notify_user_cancel_email')
+      || $cfg->entry('shop', 'from', $Constants::SHOP_FROM);
+    my $from = $cfg->entry('shop', 'from', $Constants::SHOP_FROM);
+    my $subject = $cfg->entry('seminar', 'notify_user_cancel_subject',
+                             'A user has cancelled their booking');
+    unless ($mailer->send(to        => $email,
+                         subject   => $subject,
+                         template  => 'admin/user_unbook_seminar',
+                         acts      => \%acts)) {
+      return $class->req_cancelbookingconfirm
+       ($req, "The user booking was cancelled, but there was an error sending the email notification:".$mailer->errstr );
+    }
+  }
+  my $subject = $cfg->entry('seminars', 'unbooked_notify_subject',
+                           'Seminar booking cancellation confirmation');
+  unless ($mailer->send(to       => $siteuser,
+                       subject   => $subject,
+                       template  => 'user/email_unbook_seminar',
+                       acts      => \%acts)) {
+    return $class->req_cancelbookingconfirm
+      ($req, "The user booking was cancelled, but there was an error sending the email notification:".$mailer->errstr );
+  }
+
+  my $r = $cgi->param('r');
+  unless ($r) {
+    $r = '/cgi-bin/nuser.pl/user/bookinglist';
+  }
+  $r .= $r =~ /\?/ ? '&' : '?';
+  $r .= "m=Booking+cancelled";
+
+  return BSE::Template->get_refresh($r, $req->cfg);
+}
+
+sub req_editbooking {
+  my ($class, $req, $errors) = @_;
+
+  my $cgi = $req->cgi;
+
+  my $id = $cgi->param('id');
+  defined $id && $id =~ /^\d+$/
+    or return $class->req_bookinglist($req, "id parameter invalid");
+
+  my $siteuser = $req->siteuser;
+
+  require BSE::TB::SeminarBookings;
+  my $booking = BSE::TB::SeminarBookings->getByPkey($id);
+
+  $booking && $booking->{siteuser_id} == $siteuser->{id}
+    or return $class->req_bookinglist($req, "booking $id not found");
+
+  my $session = $booking->session;
+
+  my $now = now_datetime;
+  $session->{when_at} gt $now
+    or return $class->req_bookinglist($req, "You cannot modify past bookings");
+
+  my $message = $req->message($errors);
+
+  my $seminar = $session->seminar;
+  my @sem_options = 
+    $seminar->option_descs($req->cfg, [ split /,/,  $booking->{options} ]);
+  my @unbooked = $seminar->get_unbooked_by_user($siteuser);
+  @unbooked = 
+    sort { $b->{when_at} cmp $a->{when_at} } 
+      grep $_->{when_at} gt $now, ( @unbooked, $session );
+    
+  my $current_option;
+  my $it = BSE::Util::Iterate->new;
+  my %acts;
+  %acts =
+    (
+     $req->dyn_user_tags(),
+     session  => [ \&tag_hash, $session  ],
+     seminar  => [ \&tag_hash, $seminar ],
+     location => [ \&tag_hash, $session->location ],
+     booking  => [ \&tag_hash, $booking  ],
+     message  => escape_html($message),
+     error_img => [ \&tag_error_img, $req->cfg, $errors ],
+     $it->make_iterator(undef, 'option', 'options', \@sem_options, 
+                       undef, undef, \$current_option),
+     option_popup => [ \&tag_option_popup, $req->cgi, \$current_option ],
+     $it->make_iterator(undef, 'isession', 'sessions', \@unbooked),
+     session_popup => 
+     [ \&tag_session_popup, $req->cfg, $booking, $req->cgi, \@unbooked ],
+    );
+
+  return $req->dyn_response('user/editbooking', \%acts);
+}
+
+sub req_savebooking {
+  my ($self, $req, $message) = @_;
+
+  my $cgi = $req->cgi;
+
+  my $id = $cgi->param('id');
+  defined $id && $id =~ /^\d+$/
+    or return $self->req_bookinglist($req, "id parameter invalid");
+
+  my $siteuser = $req->siteuser;
+
+  require BSE::TB::SeminarBookings;
+  my $booking = BSE::TB::SeminarBookings->getByPkey($id);
+  $booking && $booking->{siteuser_id} == $siteuser->{id}
+    or return $self->req_bookinglist($req, "booking $id not found");
+
+  my $old_session = $booking->session;
+  $old_session->{when_at} gt now_datetime
+    or return $self->req_bookinglist($req, "You cannot modify past bookings");
+
+  my @cols = qw/customer_instructions/;
+  for my $name (@cols) {
+    my $value = $cgi->param($name);
+    defined $value and $booking->set($name => $value);
+  }
+  my %errors;
+  my $session_id = $cgi->param('session_id');
+  if (defined $session_id && $session_id != $booking->{session_id}) {
+    my $new_session = BSE::TB::SeminarSessions->getByPkey($session_id);
+    if ($old_session->{seminar_id} != $new_session->{seminar_id}) {
+      $errors{session_id} = "Invalid session";
+    }
+    elsif ($new_session->{when_at} lt now_datetime) {
+      $errors{session_id} = "That session is now in the past, sorry";
+    }
+    else {
+      $booking->{session_id} = $new_session->{id};
+    }
+  }
+  keys %errors
+    and return $self->req_editbooking($req, \%errors);
+
+  my $seminar = $booking->session->seminar;
+  my @options;
+  for my $name (split /,/, $seminar->{options}) {
+    push @options, ($cgi->param($name))[0];
+  }
+  $booking->{options} = join ',', @options;
+
+  eval {
+    $booking->save;
+  };
+  $@
+    and return $self->req_editbooking($req, { error => $@ });
+
+  my @sem_options = $seminar->option_descs($req->cfg, \@options);
+
+  my $session = $booking->session;
+  require BSE::ComposeMail;
+  my $cfg = $req->cfg;
+  my $mailer = BSE::ComposeMail->new(cfg => $cfg);
+  my $it = DevHelp::Tags::Iterate->new;
+  my %acts;
+  %acts =
+    (
+     BSE::Util::Tags->static(undef, $cfg),
+     user     => [ \&tag_hash_plain, $siteuser ],
+     seminar  => [ \&tag_hash_plain, $seminar  ],
+     session  => [ \&tag_hash_plain, $session  ],
+     booking  => [ \&tag_hash_plain, $booking  ],
+     location => [ \&tag_hash_plain, $session->location ],
+     $it->make_iterator(undef, 'option', 'options', \@sem_options),
+    );
+
+  if ($cfg->entry('seminars', 'notify_user_edit', 1)) {
+    my $email = $cfg->entry('seminar', 'notify_user_edit_email')
+      || $cfg->entry('shop', 'from', $Constants::SHOP_FROM);
+    my $subject = $cfg->entry('seminar', 'notify_user_edit_subject',
+                             'A user has edited their booking');
+    unless ($mailer->send(to        => $email,
+                         subject   => $subject,
+                         template  => 'admin/user_edit_seminar',
+                         acts      => \%acts)) {
+      return $self->req_editbooking
+       ($req, "Your booking was changed, but there was an error sending the email notification:".$mailer->errstr );
+    }
+  }
+
+  my $subject = $cfg->entry('seminars', 'edit_notify_subject',
+                           'Your seminar booking has been changed');
+  unless ($mailer->send(to       => $siteuser,
+                       subject   => $subject,
+                       template  => 'user/email_edit_seminar',
+                       acts      => \%acts)) {
+    return $self->req_editbooking
+      ($req, _email => "Your booking was changed, but there was an error sending the email notification:".$mailer->errstr );
+  }
+
+  my $r = $cgi->param('r');
+  unless ($r) {
+    $r = '/cgi-bin/nuser.pl/user/bookinglist'
+  }
+  $r .= $r =~ /\?/ ? '&' : '?';
+  $r .= "m=Booking+updated";
+
+  return BSE::Template->get_refresh($r, $req->cfg);
+}
+
 sub check_action {
   my ($self, $req, $action, $rresult) = @_;
 
@@ -292,4 +607,59 @@ sub check_action {
   return 1;
 }
 
+sub tag_option_popup {
+  my ($cgi, $roption) = @_;
+
+  $$roption 
+    or return '** popup_option not in options iterator **';
+
+  my $option = $$roption;
+
+  my @extras;
+  my $value = $cgi->param($option->{id});
+  defined $value or $value = $option->{value};
+  if ($value) {
+    push @extras, -default => $value;
+  }
+
+  return popup_menu(-name => $option->{id},
+                   -values => $option->{values},
+                   -labels => $option->{labels},
+                   @extras);
+}
+
+sub tag_session_popup {
+  my ($cfg, $booking, $cgi, $unbooked) = @_;
+
+  my $default = $cgi->param('session_id');
+  defined $default or $default = $booking->{session_id};
+  my %locations;
+  for my $session (@$unbooked) {
+    unless ($locations{$session->{location_id}}) {
+      $locations{$session->{location_id}} = $session->location;
+    }
+  }
+
+  my $date_fmt = $cfg->entry('seminars', 'popup_date_format', 
+                            "%I:%M %p %d %b %Y");
+  return popup_menu
+    (-name => 'session_id',
+     -values => [ map $_->{id}, @$unbooked ],
+     -labels => 
+     { map 
+       { $_->{id} => 
+          _session_desc($_, $locations{$_->{location_id}}, $date_fmt) 
+        } @$unbooked 
+     },
+     -default => $default);
+}
+
+sub _session_desc {
+  my ($session, $location, $date_fmt) = @_;
+
+  $location->{description} . ' ' . 
+    dh_strftime_sql_datetime($date_fmt, $session->{when_at});
+}
+
+
 1;
index df682d8..f078302 100644 (file)
@@ -811,6 +811,12 @@ sub iter_usersubs {
   $user->subscribed_services;
 }
 
+sub iter_sembookings {
+  my ($user) = @_;
+
+  $user->seminar_bookings_detail;
+}
+
 sub userpage {
   my ($self, $req, $message) = @_;
 
@@ -885,6 +891,8 @@ sub userpage {
      },
      $it->make_iterator([ \&iter_usersubs, $user ], 
                        'subscription', 'subscriptions'),
+     $it->make_iterator([ \&iter_sembookings, $user ],
+                       'booking', 'bookings'),
     );
   my $base_template = 'user/userpage';
   my $template = $base_template;
index 93a9162..d7bc3fd 100644 (file)
@@ -10,6 +10,30 @@ Maybe I'll add some other bits here.
 
 =head1 CHANGES
 
+=head2 0.15_51
+
+There are additions to [pregenerate] in bse.cfg in this release.
+
+=over
+
+=item *
+
+the bookings/booking iterator has been added to the userpage, this can
+be used to list bookings for the current user.
+
+=item *
+
+the article edit pages had doubled _t suffixes, but it fell back to
+the original names, simply causing noise in the error log.
+
+=item *
+
+nuser.pl/user has the following new targets: bookinglist,
+bookingdetail, cancelbookingconfirm, cancelbooking, editbooking,
+savebooking.  This implements Member Seminar Management for AZA.
+
+=back
+
 =head2 0.15_50
 
 This release involves some large potentially destabilizing changes,
index 149487a..658667a 100644 (file)
@@ -19,7 +19,7 @@
   </tr>
   <tr>
     <th>Location:</th>
-    <td><a href="/cgi-bin/admin/admin_seminar.pl?a_locview=1&amp;<:location id:>"><:location description:></a></td>
+    <td><a href="/cgi-bin/admin/admin_seminar.pl?a_locview=1&amp;id=<:location id:>"><:location description:></a></td>
   </tr>
   <tr>
     <th>Date:</th>
diff --git a/site/templates/admin/user_edit_seminar.tmpl b/site/templates/admin/user_edit_seminar.tmpl
new file mode 100644 (file)
index 0000000..391ee73
--- /dev/null
@@ -0,0 +1,13 @@
+Dear Administrator,
+
+The following user has modified their seminar booking:
+
+  User     : <:user userId:>
+  Course   : <:seminar title:>
+  Location : <:location description:>
+  Date     : <:date session when_at:>
+  Time     : <:date "%I:%M %P" session when_at:>
+<:iterator begin options
+:>  <:option desc:>: <:option value:>
+<:iterator end options:>
+  
\ No newline at end of file
diff --git a/site/templates/admin/user_unbook_seminar.tmpl b/site/templates/admin/user_unbook_seminar.tmpl
new file mode 100644 (file)
index 0000000..ef4d7f1
--- /dev/null
@@ -0,0 +1,11 @@
+Dear Administrator
+
+User <:user userId:> has cancelled their booking as below.
+
+  Course   : <:seminar title:>
+  Location : <:location description:>
+  Date     : <:date session when_at:>
+  Time     : <:date "%I:%M %P" session when_at:>
+<:iterator begin options
+:>  <:option desc:>: <:option value:>
+<:iterator end options:>
diff --git a/site/templates/user/base_bookingdetail.tmpl b/site/templates/user/base_bookingdetail.tmpl
new file mode 100644 (file)
index 0000000..1cf56f9
--- /dev/null
@@ -0,0 +1,30 @@
+<:wrap base.tmpl title=>"Seminar Booking Details":>
+<h1>Seminar Booking Details</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:> 
+<table>
+  <tr>
+    <th>Seminar:</th>
+    <td><a href="<:seminar link:>"><:seminar title:></a></td>
+  </tr>
+  <tr>
+    <th>Location:</th>
+    <td><a href="/cgi-bin/shop.pl?a_location=1&amp;location_id=<:location id:>"><:location description:></a>
+<:ifLocation room:><br />Room: <:location room:><:or:><:eif:>
+<:ifLocation street1:><br /><:location street1:><:or:><:eif:>
+<:ifLocation street2:><br />Room: <:location street2:><:or:><:eif:>
+<br /><:location suburb:> <:location state:> <:location postcode:>
+<:ifLocation country:><br /><:location country:><:or:><:eif:>
+<:ifLocation public_notes:><textarea readonly="readonly" style="border-style: none" cols="60" rows="20"><:location public_notes:></textarea><:or:><:eif:>
+</td>
+  </tr>
+  <tr>
+    <th>Date:</th>
+    <td><:date session when_at:></td>
+  </tr>
+  <tr>
+    <th>Time:</th>
+    <td><:date "%I:%M %P" session when_at:></td>
+  </tr>
+</table>
diff --git a/site/templates/user/base_bookinglist.tmpl b/site/templates/user/base_bookinglist.tmpl
new file mode 100644 (file)
index 0000000..e6dbad3
--- /dev/null
@@ -0,0 +1,32 @@
+<:wrap base.tmpl title=>"Booked Seminars":>
+<h1>Booked Seminars</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:> 
+
+      <table border=0 cellpadding="6" cellspacing="1" width="100%">
+        <tr bgcolor="#FFFFFF"> 
+          <th width="50%">Seminar</th>
+          <th width="50%">Location</th>
+          <th>Time</th>
+          <th>Date</th>
+        </tr>
+<:if Bookings:>
+        <:iterator begin bookings:> 
+        <tr bgcolor="#FFFFFF"> 
+          <td><a href="<:booking link:>"><:booking title:></a></td>
+          <td><a href="/cgi-bin/shop.pl?a_location=1&amp;location_id=<:booking location_id:>"><:booking loc_description:></a></td>
+          <td nowrap="nowrap"><:date "%I:%M %p" booking when_at:></td>
+          <td nowrap="nowrap"><:date booking when_at:></td>
+          <td nowrap="nowrap">
+            <a href="/cgi-bin/nuser.pl/user/cancelbookingconfirm?id=<:booking booking_id:>">Cancel</a>
+            <a href="/cgi-bin/nuser.pl/user/editbooking?id=<:booking booking_id:>">Edit</a>
+          </td>
+        </tr>
+        <:iterator end bookings:> 
+<:or Bookings:>
+        <tr>
+          <td colspan="5" align="center">No bookings found</td>
+        </tr>
+<:eif Bookings:>
+      </table>
diff --git a/site/templates/user/base_cancelbooking.tmpl b/site/templates/user/base_cancelbooking.tmpl
new file mode 100644 (file)
index 0000000..a4d859b
--- /dev/null
@@ -0,0 +1,36 @@
+<:wrap base.tmpl title=>"Cancel Seminar Booking":>
+<h1>Cancel Seminar Booking</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:> 
+<form action="/cgi-bin/nuser.pl/user/cancelbooking" method="post">
+<input type="hidden" name="id" value="<:booking id:>" />
+<:ifCgi r:><input type="hidden" name="r" value="<:cgi r:>" /><:or:><:eif:>
+<table>
+  <tr>
+    <th>Seminar:</th>
+    <td><a href="<:seminar link:>"><:seminar title:></a></td>
+  </tr>
+  <tr>
+    <th>Location:</th>
+    <td><a href="/cgi-bin/shop.pl?a_location=1&amp;location_id=<:location id:>"><:location description:></a></td>
+  </tr>
+  <tr>
+    <th>Date:</th>
+    <td><:date session when_at:></td>
+  </tr>
+  <tr>
+    <th>Time:</th>
+    <td><:date "%I:%M %P" session when_at:></td>
+  </tr>
+<:iterator begin options:>
+  <tr>
+   <th><:option desc:>:</th>
+   <td><:option display:></td>
+  </tr>
+<:iterator end options:>
+  <tr>
+    <td colspan="3"><input type="submit" value="Cancel Booking" /></td>
+  </tr>
+</table>
+</form>
diff --git a/site/templates/user/base_editbooking.tmpl b/site/templates/user/base_editbooking.tmpl
new file mode 100644 (file)
index 0000000..c2464af
--- /dev/null
@@ -0,0 +1,34 @@
+<:wrap base.tmpl title=>"Edit Seminar Booking":>
+<h1>Edit Seminar Booking</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:> 
+<form action="/cgi-bin/nuser.pl/user/savebooking" method="post">
+<input type="hidden" name="id" value="<:booking id:>" />
+<:ifCgi r:><input type="hidden" name="r" value="<:cgi r:>" /><:or:><:eif:>
+<table>
+  <tr>
+    <th>Seminar:</th>
+    <td><a href="<:seminar link:>"><:seminar title:></a></td>
+  </tr>
+  <tr>
+    <th>Session:</th>
+    <td><:session_popup:></td>
+  </tr>
+<:iterator begin options:>
+  <tr>
+   <th><:option desc:></th>
+   <td><:option_popup:></td>
+   <td></td>
+  </tr>
+<:iterator end options:>
+  <tr>
+   <th>Customer<br />Instructions:</th>
+   <td><textarea name="customer_instructions" cols="70" rows="10" /><:old customer_instructions booking customer_instructions:></textarea></td>
+   <td><:error_img customer_instructions:></td>
+  </tr>
+  <tr>
+    <td colspan="3"><input type="submit" value="Save Booking" /></td>
+  </tr>
+</table>
+</form>
diff --git a/site/templates/user/email_edit_seminar.tmpl b/site/templates/user/email_edit_seminar.tmpl
new file mode 100644 (file)
index 0000000..f0986b5
--- /dev/null
@@ -0,0 +1,11 @@
+Dear <:user name1:>,
+
+This email is sent to confirm your seminar booking change as follows:
+
+  Course   : <:seminar title:>
+  Location : <:location description:>
+  Date     : <:date session when_at:>
+  Time     : <:date "%I:%M %P" session when_at:>
+<:iterator begin options
+:>  <:option desc:>: <:option value:>
+<:iterator end options:>
diff --git a/site/templates/user/email_unbook_seminar.tmpl b/site/templates/user/email_unbook_seminar.tmpl
new file mode 100644 (file)
index 0000000..2ccf542
--- /dev/null
@@ -0,0 +1,11 @@
+Dear <:user name1:>
+
+This email confirms your seminar booking cancellation as follows:
+
+  Course   : <:seminar title:>
+  Location : <:location description:>
+  Date     : <:date session when_at:>
+  Time     : <:date "%I:%M %P" session when_at:>
+<:iterator begin options
+:>  <:option desc:>: <:option value:>
+<:iterator end options:>