input date parser now validates the date
authorTony Cook <tony@develop-help.com>
Mon, 25 Jan 2010 04:23:16 +0000 (04:23 +0000)
committertony <tony@45cb6cf1-00bc-42d2-bb5a-07f51df49f94>
Mon, 25 Jan 2010 04:23:16 +0000 (04:23 +0000)
add order_complete custom hook called when the customer finishes an order

add more API like support for creating orders

the shop show_payment page now accepts an order id to pay an old order

an admin can now mark an order paid manually, and unmark such an
order

fixed an error handling bug in the report display

add optional includes to order_details and edit_product pages to
allow limited compatibility with Adrian's template set for custom text

remove the order list from the main user page (it's on the _t=orders page)

15 files changed:
site/cgi-bin/modules/BSE/ComposeMail.pm
site/cgi-bin/modules/BSE/CustomBase.pm
site/cgi-bin/modules/BSE/Mail/Sendmail.pm
site/cgi-bin/modules/BSE/TB/Order.pm
site/cgi-bin/modules/BSE/TB/OrderItem.pm
site/cgi-bin/modules/BSE/UI/AdminReport.pm
site/cgi-bin/modules/BSE/UI/AdminShop.pm
site/cgi-bin/modules/BSE/UI/Shop.pm
site/cgi-bin/modules/DevHelp/Date.pm
site/cgi-bin/shop.pl
site/templates/admin/add_product.tmpl
site/templates/admin/edit_product.tmpl
site/templates/admin/order_detail.tmpl
site/templates/checkoutpay_base.tmpl
site/templates/user/userpage_base.tmpl

index 34ee499..ecba59b 100644 (file)
@@ -91,7 +91,7 @@ sub start {
     || "$self->{template}_html";
   
   $self->{extra_mail_args} = {};
-  for my $arg (qw(to_name from_name)) {
+  for my $arg (qw(to_name from_name cc bcc)) {
     defined $opts{$arg}
       and $self->{extra_mail_args}{$arg} = $opts{$arg};
   }
index ddaed73..351e64e 100644 (file)
@@ -256,6 +256,11 @@ $user_id is the numeric id of the user.
 Called when a user is removed from a group.  $group is the group
 object, $user_id is the numeric id of the user.
 
+=item order_complete($cfg, $order)
+
+Called when the supplied order has been completed.  It may or may not
+have been paid.
+
 =back
 
 =cut
index 32dd411..59a7dfc 100644 (file)
@@ -29,6 +29,9 @@ sub send {
   $args{headers} =~ /^\s/
     and return $self->_error("headers starts with whitespace");
 
+  if ($args{cc}) {
+    $args{headers} = "Cc: $args{cc}\n".$args{headers};
+  }
   if ($args{bcc}) {
     $args{headers} = "Bcc: $args{bcc}\n".$args{headers};
   }
index dc8bfd3..3288dc2 100644 (file)
@@ -28,6 +28,82 @@ sub columns {
            shipping_name shipping_trace/;
 }
 
+sub defaults {
+  require BSE::Util::SQL;
+  require Digest::MD5;
+  return
+    (
+     total => 0,
+     wholesaleTotal => 0,
+     gst => 0,
+     orderDate => BSE::Util::SQL::now_datetime(),
+     filled => 0,
+     whenFilled => undef,
+     whoFilled => '',
+     paidFor => 0,
+     paymentReceipt => '',
+     randomId => Digest::MD5::md5_hex(time().rand().{}.$$),
+     ccNumberHash => '',
+     ccName => '',
+     ccExpiryHash => '',
+     ccType => '',
+     randomId => '',
+     cancelled => 0,
+     userId => '',
+     paymentType => 0,
+     customInt1 => undef,
+     customInt2 => undef,
+     customInt3 => undef,
+     customInt4 => undef,
+     customInt5 => undef,
+     customStr1 => undef,
+     customStr2 => undef,
+     customStr3 => undef,
+     customStr4 => undef,
+     customStr5 => undef,
+     instructions => '',
+     siteuser_id => undef,
+     affiliate_code => '',
+     shipping_cost => 0,
+     ccOnline => 0,
+     ccSuccess => 0,
+     ccReceipt => '',
+     ccStatus => 0,
+     ccStatusText => '',
+     ccStatus2 => '',
+     ccTranId => '',
+     complete => 0,
+     purchase_order => '',
+     shipping_method => '',
+     shipping_name => '',
+     shipping_trace => undef,
+    );
+}
+
+sub address_columns {
+  return qw/
+           delivFirstName delivLastName delivStreet delivSuburb delivState
+          delivPostCode delivCountry
+           billFirstName billLastName billStreet billSuburb billState
+           billPostCode billCountry
+           telephone facsimile emailAddress
+           instructions billTelephone billFacsimile billEmail
+           delivMobile billMobile
+           delivOrganization billOrganization
+           delivStreet2 billStreet2/;
+}
+
+sub user_columns {
+  return qw/userId siteuser_id/;
+}
+
+sub payment_columns {
+  return qw/ccNumberHash ccName ccExpiryHash ccType
+           paidFor paymentReceipt paymentType
+           ccOnline ccSuccess ccReceipt ccStatus ccStatusText
+           ccStatus2 ccTranId/;
+}
+
 =item siteuser
 
 returns the SiteUser object of the user who made this order.
@@ -187,4 +263,42 @@ sub clear_items {
   BSE::DB->run(deleteOrdersItems => $self->{id});
 }
 
+sub add_item {
+  my ($self, %opts) = @_;
+
+  my $prod = delete $opts{product}
+    or confess "Missing product option";
+  my $units = delete $opts{units} || 1;
+
+  my $options = '';
+  my @dboptions;
+  if ($opts{options}) {
+    if (ref $opts{options}) {
+      @dboptions = @{delete $opts{options}};
+    }
+    else {
+      $options = delete $opts{options};
+    }
+  }
+  
+  require BSE::TB::OrderItems;
+  my %item =
+    (
+     productId => $prod->id,
+     orderId => $self->id,
+     units => $units,
+     price => $prod->retailPrice,
+     options => $options,
+     max_lapsed => 0,
+     session_id => 0,
+     ( map { $_ => $prod->{$_} }
+       qw/wholesalePrice gst customInt1 customInt2 customInt3 customStr1 customStr2 customStr3 title description subscription_id subscription_period product_code/
+     ),
+    );
+
+  $self->set_total($self->total + $prod->retailPrice * $units);
+
+  return BSE::TB::OrderItems->make(%item);
+}
+
 1;
index 716acbd..26347ef 100644 (file)
@@ -12,6 +12,20 @@ sub columns {
             session_id product_code/;
 }
 
+sub defaults {
+  return
+    (
+     units => 1,
+     options => '',
+     customInt1 => undef,
+     customInt2 => undef,
+     customInt3 => undef,
+     customStr1 => undef,
+     customStr2 => undef,
+     customStr3 => undef,
+    );
+}
+
 sub option_list {
   my ($self) = @_;
 
index 4a68946..d25f414 100644 (file)
@@ -124,7 +124,7 @@ sub req_show {
     );
 
   $msg
-    and return prompt($req, $reports, $msg);
+    and return $class->req_prompt($req, $msg);
 
   my $levels = $reports->levels($repname, BSE::DB->single);
   my $template = $reports->show_template($repname) || 'admin/reports/show' . $levels;
index d079b9c..9fef970 100644 (file)
@@ -28,6 +28,8 @@ my %actions =
    order_list_incomplete => 'shop_order_list',
    order_detail => 'shop_order_detail',
    order_filled => 'shop_order_filled',
+   order_paid => 'shop_order_paid',
+   order_unpaid => 'shop_order_unpaid',
    product_detail => '',
    product_list => '',
   );
@@ -658,6 +660,48 @@ sub req_order_filled {
   }
 }
 
+sub req_order_paid {
+  my ($class, $req) = @_;
+
+  return $class->_set_order_paid($req, 1);
+}
+
+sub req_order_unpaid {
+  my ($class, $req) = @_;
+
+  return $class->_set_order_paid($req, 0);
+}
+
+sub _set_order_paid {
+  my ($class, $req, $value) = @_;
+
+  my $id = $req->cgi->param('id');
+  if ($id and
+      my $order = BSE::TB::Orders->getByPkey($id)) {
+    if ($order->paidFor != $value) {
+      if ($value) {
+       $order->set_paymentType(3);
+      }
+      else {
+       $order->paymentType == 3
+         or return $class->req_order_detail($req, "You can only unpay manually paid orders");
+      }
+
+      $order->set_paidFor($value);
+      my $user = $req->user;
+      my $name = $user ? $user->logon : "--unknown--";
+      require POSIX;
+      $order->{instructions} .= "\nMarked " . ($value ? "paid" : "unpaid" ) . " by $name " . POSIX::strftime("%H:%M %d/%m/%Y", localtime);
+      $order->save();
+    }
+
+    return BSE::Template->get_refresh("$ENV{SCRIPT_NAME}?a_order_detail=1&id=$id", $req->cfg);
+  }
+  else {
+    return $class->req_order_list($req);
+  }
+}
+
 #####################
 # utilities
 # perhaps some of these belong in a class...
index 7c7cd39..232a994 100644 (file)
@@ -588,7 +588,6 @@ sub req_remove_item {
   return BSE::Template->get_refresh($req->user_url(shop => 'cart'), $req->cfg);
 }
 
-
 # saves order and refresh to payment page
 sub req_order {
   my ($class, $req) = @_;
@@ -659,24 +658,75 @@ sub req_order {
   }
 }
 
-sub req_show_payment {
-  my ($class, $req, $errors) = @_;
+=item a_show_payment
 
-  $req->session->{order_info_confirmed}
-    or return $class->req_checkout($req, 'Please proceed via the checkout page');
+Allows the customer to pay for an existing order.
 
-  $req->session->{cart} && @{$req->session->{cart}}
-    or return $class->req_cart($req, "Your cart is empty");
+Parameters:
+
+=over
+
+=item *
+
+orderid - the order id to be paid (Optional, otherwise displays the
+cart for payment).
+
+=back
+
+Template: checkoutpay
+
+=cut
+
+
+sub req_show_payment {
+  my ($class, $req, $errors) = @_;
 
   my $cfg = $req->cfg;
   my $cgi = $req->cgi;
 
+  my @items;
+  my @products;
+  my $order;
+
+  my $order_id = $cgi->param('orderid');
+  if ($order_id) {
+    $order_id =~ /^\d+$/
+      or return $class->req_cart($req, "No or invalid order id supplied");
+    
+    my $user = $req->siteuser
+      or return $class->_refresh_logon
+       ($req, "Please logon before paying your existing order", "logonpayorder",
+        undef, { a_show_payment => 1, orderid => $order_id });
+    
+    require BSE::TB::Orders;
+    $order = BSE::TB::Orders->getByPkey($order_id)
+      or return $class->req_cart($req, "Unknown order id");
+    
+    $order->siteuser_id == $user->id
+      or return $class->req_cart($req, "You can only pay for your own orders");
+    
+    $order->paidFor
+      and return $class->req_cart($req, "Order $order->{id} has been paid");
+    
+    @items = $order->items;
+    @products = $order->products;
+  }
+  else {
+    $req->session->{order_info_confirmed}
+      or return $class->req_checkout($req, 'Please proceed via the checkout page');
+    
+    $req->session->{cart} && @{$req->session->{cart}}
+      or return $class->req_cart($req, "Your cart is empty");
+    
+    $order = $req->session->{order_info}
+      or return $class->req_checkout($req, "You need to enter order information first");
+
+    @items = $class->_build_items($req, \@products);
+  }
+
   $errors ||= {};
   my $msg = $req->message($errors);
 
-  my $order_values = $req->session->{order_info}
-    or return $class->req_checkout($req, "You need to enter order information first");
-
   my @pay_types = payment_types($cfg);
   my @payment_types = map $_->{id}, grep $_->{enabled}, @pay_types;
   my %types_by_name = map { $_->{name} => $_->{id} } @pay_types;
@@ -687,25 +737,22 @@ sub req_show_payment {
   $errors and $payment = $cgi->param('paymentType');
   defined $payment or $payment = $payment_types[0];
 
-  my @products;
-  my @items = $class->_build_items($req, \@products);
-
   my %acts;
   %acts =
     (
      basic_tags(\%acts),
      message => $msg,
      msg => $msg,
-     order => [ \&tag_hash, $order_values ],
+     order => [ \&tag_hash, $order ],
      shop_cart_tags(\%acts, \@items, \@products, $req, 'payment'),
      ifMultPaymentTypes => @payment_types > 1,
      checkedPayment => [ \&tag_checkedPayment, $payment, \%types_by_name ],
      ifPayments => [ \&tag_ifPayments, \@payment_types, \%types_by_name ],
      error_img => [ \&tag_error_img, $cfg, $errors ],
-     total => $order_values->{total},
-     delivery_in => $order_values->{delivery_in},
-     shipping_cost => $order_values->{shipping_cost},
-     shipping_method => $order_values->{shipping_method},
+     total => $order->{total},
+     delivery_in => $order->{delivery_in},
+     shipping_cost => $order->{shipping_cost},
+     shipping_method => $order->{shipping_method},
     );
   for my $type (@pay_types) {
     my $id = $type->{id};
@@ -729,13 +776,46 @@ my %nostore =
 sub req_payment {
   my ($class, $req, $errors) = @_;
 
-  $req->session->{order_info_confirmed}
-    or return $class->req_checkout($req, 'Please proceed via the checkout page');
+  require BSE::TB::Orders;
+  my $cgi = $req->cgi;
+  my $order_id = $cgi->param("order_id");
+  my $user = $req->siteuser;
+  my $order;
+  my $order_values;
+  my $old_order; # true if we're paying an old order
+  if ($order_id) {
+    unless ($user) {
+      return $class->_refresh_logon
+       (
+        $req,
+        "Please logon before paying your existing order",
+        "logonpayorder",
+        undef,
+        { a_show_payment => 1, orderid => $order_id }
+       );
+    }
+    $order_id =~ /^\d+$/
+      or return $class->req_cart($req, "Invalid order id");
+    $order = BSE::TB::Orders->getByPkey($order_id)
+      or return $class->req_cart($req, "Unknown order id");
+    $order->siteuser_id == $user->id
+      or return $class->req_cart($req, "You can only pay for your own orders");
+
+    $order->paidFor
+      and return $class->req_cart($req, "Order $order->{id} has been paid");
 
-  my $order_values = $req->session->{order_info}
-    or return $class->req_checkout($req, "You need to enter order information first");
+    $order_values = $order;
+    $old_order = 1;
+  }
+  else {
+    $req->session->{order_info_confirmed}
+      or return $class->req_checkout($req, 'Please proceed via the checkout page');
+
+    $order_values = $req->session->{order_info}
+      or return $class->req_checkout($req, "You need to enter order information first");
+    $old_order = 0;
+  }
 
-  my $cgi = $req->cgi;
   my $cfg = $req->cfg;
   my $session = $req->session;
 
@@ -787,99 +867,108 @@ sub req_payment {
   }
 
   $order_values->{paymentType} = $paymentType;
-
-  $order_values->{filled} = 0;
-  $order_values->{paidFor} = 0;
-
-  my @products;
-  my @items = $class->_build_items($req, \@products);
-  
-  my @columns = BSE::TB::Order->columns;
-  my %columns; 
-  @columns{@columns} = @columns;
-
-  for my $col (@columns) {
-    defined $order_values->{$col} or $order_values->{$col} = '';
-  }
-
-  my @data = @{$order_values}{@columns};
-  shift @data;
-
-  my $order;
-  if ($session->{order_work}) {
-    $order = BSE::TB::Orders->getByPkey($session->{order_work});
-  }
-  if ($order && !$order->{complete}) {
-    print STDERR "Recycling order $order->{id}\n";
-
-    my @allbutid = @columns;
-    shift @allbutid;
-    @{$order}{@allbutid} = @data;
-
-    $order->clear_items;
-    delete $session->{order_work};
-    eval {
-      tied(%$session)->save;
-    };
-  }
-  else {
-    $order = BSE::TB::Orders->add(@data)
-      or die "Cannot add order";
-  }
-
   my @dbitems;
+  my @products;
   my %subscribing_to;
-  my @item_cols = BSE::TB::OrderItem->columns;
-  for my $row_num (0..$#items) {
-    my $item = $items[$row_num];
-    my $product = $products[$row_num];
-    my %item = %$item;
-    $item{orderId} = $order->{id};
-    $item{max_lapsed} = 0;
-    if ($product->{subscription_id} != -1) {
+  if ($order) {
+    @dbitems = $order->items;
+    @products = $order->products;
+    for my $product (@products) {
       my $sub = $product->subscription;
-      $item{max_lapsed} = $sub->{max_lapsed} if $sub;
-    }
-    defined $item{session_id} or $item{session_id} = 0;
-    $item{options} = ""; # not used for new orders
-    my @data = @item{@item_cols};
-    shift @data;
-    my $dbitem = BSE::TB::OrderItems->add(@data);
-    push @dbitems, $dbitem;
-
-    if ($item->{options} and @{$item->{options}}) {
-      require BSE::TB::OrderItemOptions;
-      my @option_descs = $product->option_descs($cfg, $item->{options});
-      my $display_order = 1;
-      for my $option (@option_descs) {
-       BSE::TB::OrderItemOptions->make
-           (
-            order_item_id => $dbitem->{id},
-            original_id => $option->{id},
-            name => $option->{desc},
-            value => $option->{value},
-            display => $option->{display},
-            display_order => $display_order++,
-           );
+      if ($sub) {
+       $subscribing_to{$sub->{text_id}} = $sub;
       }
     }
-
-    my $sub = $product->subscription;
-    if ($sub) {
-      $subscribing_to{$sub->{text_id}} = $sub;
+  }
+  else {
+    $order_values->{filled} = 0;
+    $order_values->{paidFor} = 0;
+    
+    my @items = $class->_build_items($req, \@products);
+    
+    my @columns = BSE::TB::Order->columns;
+    my %columns; 
+    @columns{@columns} = @columns;
+    
+    for my $col (@columns) {
+      defined $order_values->{$col} or $order_values->{$col} = '';
     }
-
-    if ($item->{session_id}) {
-      my $user = $req->siteuser;
-      require BSE::TB::SeminarSessions;
-      my $session = BSE::TB::SeminarSessions->getByPkey($item->{session_id});
-      my $options = join(",", @{$item->{options}});
+    
+    my @data = @{$order_values}{@columns};
+    shift @data;
+    
+    if ($session->{order_work}) {
+      $order = BSE::TB::Orders->getByPkey($session->{order_work});
+    }
+    if ($order && !$order->{complete}) {
+      print STDERR "Recycling order $order->{id}\n";
+      
+      my @allbutid = @columns;
+      shift @allbutid;
+      @{$order}{@allbutid} = @data;
+      
+      $order->clear_items;
+      delete $session->{order_work};
       eval {
-       $session->add_attendee($user, 
-                              instructions => $order->{instructions},
-                              options => $options);
+       tied(%$session)->save;
       };
     }
+    else {
+      $order = BSE::TB::Orders->add(@data)
+       or die "Cannot add order";
+    }
+    
+    my @item_cols = BSE::TB::OrderItem->columns;
+    for my $row_num (0..$#items) {
+      my $item = $items[$row_num];
+      my $product = $products[$row_num];
+      my %item = %$item;
+      $item{orderId} = $order->{id};
+      $item{max_lapsed} = 0;
+      if ($product->{subscription_id} != -1) {
+       my $sub = $product->subscription;
+       $item{max_lapsed} = $sub->{max_lapsed} if $sub;
+      }
+      defined $item{session_id} or $item{session_id} = 0;
+      $item{options} = ""; # not used for new orders
+      my @data = @item{@item_cols};
+    shift @data;
+      my $dbitem = BSE::TB::OrderItems->add(@data);
+      push @dbitems, $dbitem;
+      
+      if ($item->{options} and @{$item->{options}}) {
+       require BSE::TB::OrderItemOptions;
+       my @option_descs = $product->option_descs($cfg, $item->{options});
+       my $display_order = 1;
+       for my $option (@option_descs) {
+         BSE::TB::OrderItemOptions->make
+             (
+              order_item_id => $dbitem->{id},
+              original_id => $option->{id},
+              name => $option->{desc},
+              value => $option->{value},
+              display => $option->{display},
+              display_order => $display_order++,
+             );
+       }
+      }
+      
+      my $sub = $product->subscription;
+      if ($sub) {
+       $subscribing_to{$sub->{text_id}} = $sub;
+      }
+      
+      if ($item->{session_id}) {
+       require BSE::TB::SeminarSessions;
+       my $session = BSE::TB::SeminarSessions->getByPkey($item->{session_id});
+       my $options = join(",", @{$item->{options}});
+       eval {
+         $session->add_attendee($user, 
+                                instructions => $order->{instructions},
+                                options => $options);
+       };
+      }
+    }
   }
 
   $order->{ccOnline} = 0;
@@ -942,6 +1031,10 @@ sub req_payment {
   $order->{complete} = 1;
   $order->save;
 
+  my $custom = custom_class($req->cfg);
+  $custom->can("order_complete")
+    and $custom->order_complete($req->cfg, $order);
+
   # set the order displayed by orderdone
   $session->{order_completed} = $order->{id};
   $session->{order_completed_at} = time;
@@ -1314,13 +1407,17 @@ sub tag_with_wrap {
 }
 
 sub _refresh_logon {
-  my ($class, $req, $msg, $msgid, $r) = @_;
+  my ($class, $req, $msg, $msgid, $r, $parms) = @_;
 
   my $securlbase = $req->cfg->entryVar('site', 'secureurl');
   my $url = $securlbase."/cgi-bin/user.pl";
+  $parms ||= { checkout => 1 };
+
+  unless ($r) {
+    $r = $securlbase."/cgi-bin/shop.pl?" 
+      . join("&", map "$_=" . escape_uri($parms->{$_}), keys %$parms);
+  }
 
-  $r ||= $securlbase."/cgi-bin/shop.pl?checkout=1";
-  
   my %parms;
   if ($req->cfg->entry('shop registration', 'all')
       || $req->cfg->entry('shop registration', $msgid)) {
index 55d984b..4bbca5a 100644 (file)
@@ -22,7 +22,7 @@ sub dh_parse_date {
   $bias ||= 0;
 
   my ($year, $month, $day);
-  if (($day, $month, $year) = $when =~ /(\d+)\D+(\d+)\D+(\d+)/) {
+  if (($day, $month, $year) = $when =~ /^\s*(\d+)\D+(\d+)\D+(\d+)\s*$/) {
     if ($year < 100) {
       my $base_year = 1900 + (localtime)[5];
       if ($bias < 0) {
@@ -42,6 +42,10 @@ sub dh_parse_date {
       
       $year = $work_year;
     }
+    unless (dh_valid_date($year, $month, $day)) {
+      $$rmsg = "Invalid date";
+      return;
+    }
   }
   elsif ($when =~ /^\s*([+-]\d+)y\s*$/) {
     my $yoffset = $1;
index 76e7487..88d8a75 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 # -d:ptkdb
-BEGIN { $ENV{DISPLAY} = '192.168.32.51:0.0' }
+BEGIN { $ENV{DISPLAY} = '192.168.32.54:0.0' }
 use strict;
 use FindBin;
 use lib "$FindBin::Bin/modules";
index 0683cbc..577a221 100644 (file)
             <td bgcolor="#FFFFFF" width="100%"><:iterator begin flags:><:if FieldPerm flags:><input type=checkbox name=flags value="<:flag id:>" <:ifFlagSet [flag id]:>checked<:or:><:eif:>><:or FieldPerm:><:ifFlagSet [flag id]:>Yes<:or:>No<:eif:><:eif FieldPerm:><:flag desc:><:iterator end flags:></td>
             <td bgcolor="#FFFFFF"><:help edit listed:></td>
           </tr>
-<:include admin/product_custom.tmpl optional :>
+<:include admin/product_custom.tmpl optional :><:include admin/include/custom/product_custom.tmpl optional:><:include admin/include/product_custom.tmpl optional:>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF" valign="top">Thumbnail image:</th>
             <td nowrap bgcolor="#FFFFFF"> 
index ab5f4cf..ac29797 100644 (file)
               (<:alloptions:>)<:or:><:product options:><:eif:> </td>
             <td class="help"><:help product options:> <:error_img options:></td>
           </tr>
-<:include admin/product_custom.tmpl optional:>
+<:include admin/product_custom.tmpl optional:><:include admin/include/custom/product_custom.tmpl optional:><:include admin/include/product_custom.tmpl optional:>
           <tr> 
             <th>Thumbnail image:</th>
             <td> 
index 3465eaa..64d8a07 100644 (file)
@@ -56,7 +56,7 @@
     <td><:order delivCountry:></td>
     <td><:order billCountry:></td>
   </tr>
-  <:include custom/order_detail.include optional:>
+  <:include custom/order_detail.include optional:><:include admin/include/custom/order_detail_custom.tmpl optional:><:include admin/include/order_detail_custom.tmpl optional:>
 </table>
 
 <br>
@@ -114,6 +114,9 @@ Shipping via <:order shipping_method:>:
 </tr>
 </table>
 <:switch:>
+<:case Eq [order paidFor] "0":>
+<p>This order hasn't been paid</p>
+<p>If the customer has paid by cheque, transfer, etc, you can <a href="<:script:>?a_order_paid=1&amp;id=<:order id:>">mark this order paid</a></p>
 <:case order ccOnline:>
 <p>This was processed as an online credit card transaction.</p>
 <:if Order ccSuccess:>
@@ -137,6 +140,7 @@ Shipping via <:order shipping_method:>:
 <:case Eq [order paymentType] "0":><p>Payment made by credit card.  Credit card details can be found in the encrypted email you received when the customer made the order.</p>
 <:case Eq [order paymentType] "1":><p>Payment will be made by cheque.</p>
 <:case Eq [order paymentType] "2":><p>Contact the customer to arrange for payment.</p>
+<:case Eq [order paymentType] "3":><p>Paid manually (staff marked this order paid) - you can <a href="<:script:>?a_order_unpaid=1&amp;id=<:order id:>">unmark it</a></p>
 <:endswitch:>
 <:include custom/order_detail_payment.include optional:>
 <:if Order filled:>
@@ -145,4 +149,7 @@ Shipping via <:order shipping_method:>:
 <:ifOrder complete:>
 <p>This order hasn't been filled yet.  <a href="/cgi-bin/admin/shopadmin.pl?id=<:order id:>&order_filled=Yep&filled=1&detail=1">Mark order filled</a>.</p><:or:><:eif:>
 <:eif Order:>
+<:if Order instructions:>
+<p style="white-space: pre-wrap;"><:order instructions:></p>
+<:or Order:><:eif Order:>
 </body></html>
index ec2b61d..1059ec9 100644 (file)
     </td>
   </tr>
 </table>
+<:if Order id:>
+<h2>Payment for order <:arithmetic sprintf("%06d", [order id] ) :></h2>
+<:or Order:>
 <p> <b><font face="Verdana, Arial, Helvetica, sans-serif" size="3"> Thank you 
   for shopping at <:siteName:></font></b></p>
+<:eif Order:>
 <font class="article_body_text" face="Verdana, Arial, Helvetica, sans-serif" size="2"> 
 <p> The <:siteName:> store is run on a secure encrypted server, your details are 
   safe with us.</p></font> 
@@ -92,6 +96,7 @@
   </tr>
 </table>
 <form action="<:dyntarget shop:>" method="post">
+<:ifOrder id:><input type="hidden" name="order_id" value="<:order id:>" /><:or:><:eif:>
   <font face="Verdana, Arial, Helvetica, sans-serif" size="3"> <b>Payment Details:</b></font> 
   <hr size="1" noshade>
 <:ifMsg:><p><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:msg:></font></b></p><:or:><:eif:>
index 428a160..9f8093f 100644 (file)
           <br>
         </p></td>
     </tr>
-       <:if Cfg shop enabled:>
-    <:if Orders:> <:iterator begin orders:> 
-    <tr> 
-      <td bgcolor="#CCCCCC"> <table width="100%" cellpadding="3" cellspacing="1">
-          <tr> 
-            <th align="center" nowrap width="25%" bgcolor="#666666"><a href="<:script:>?a_orderdetail=1&amp;id=<:order id:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#CCCCCC">Order 
-              No:</font><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"> 
-              <:order id:></font></a></th>
-            <th align="center" width="25%" nowrap bgcolor="#666666"><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#CCCCCC">Date:</font><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"> 
-              <:date order orderDate:></font></th>
-            <th align="center" width="25%" nowrap bgcolor="<:ifOrder filled:>#CC0033<:or:>#66CC00<:eif:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="<:ifOrder filled:>#CCCCCC<:or:>#000000<:eif:>">Status:</font><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"> 
-              <:ifOrder filled:>Complete<:or:>Processing<:eif:></font></th>
-            <th align="center" width="25%" nowrap bgcolor="#FF7F00"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Total:</font><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"> 
-              $<:money order total:></font></th>
-          </tr>
-        </table>
-        <:if Items:> <table width="100%" cellpadding="3" cellspacing="1">
-          <tr bgcolor="#EEEEEE"> 
-            <th width="100%" align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Product</font></th>
-            <th><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Quantity</font></th>
-            <th><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Unit</font></th>
-          </tr>
-          <:iterator begin items:> 
-          <tr bgcolor="#FFFFFF"> 
-            <td width="100%"><a href="<:product link:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:product 
-              description:></font></a></td>
-            <td align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:item 
-              units:></font></td>
-            <td align="right"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">$<:money 
-              item price:></font></td>
-          </tr>
-          <:iterator end items:> 
-        </table>
-        <:if Orderfiles:> <table width="100%" cellpadding="3" cellspacing="1">
-          <tr bgcolor="#CCCCCC"> 
-            <th colspan="4"><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#666666"><:if 
-              Order filled:>Files available<:or Order:><:ifCfg downloads must_be_filled:>Files 
-              available when order status is &#145;Complete&#146;<:or:>Files<:eif:><:eif 
-              Order:></font></th>
-          </tr>
-          <tr bgcolor="#EEEEEE"> 
-            <th width="50%" align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Description</font></th>
-            <th nowrap width="50%" align="left" colspan="2"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">File</font></th>
-            <th><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Size</font></th>
-          </tr>
-          <:iterator begin orderfiles:> 
-          <tr bgcolor="#FFFFFF"> 
-            <td width="50%"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:orderfile 
-              description:></font></td>
-            <td nowrap width="50%"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:if 
-              FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:orderfile id:>&order=<:order id:>&item=<:orderfile item_id:>"><:orderfile 
-              displayName:></a><:or FileAvail:><:orderfile displayName:><:eif 
-              FileAvail:></font></td>
-            <td><:if FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:orderfile id:>&order=<:order id:>&item=<:orderfile item_id:>"><img src="/images/filestatus/download.gif" width="15" height="15" alt="Download now" title="Download now" border="0"></a><:or 
-              FileAvail:><img src="/images/filestatus/locked.gif" width="15" height="15" alt="Locked" title="Locked"><:eif 
-              FileAvail:></td>
-            <td align="right"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:kb 
-              orderfile sizeInBytes:></font></td>
-          </tr>
-          <:iterator end orderfiles:> 
-        </table>
-        <:or Orderfiles:><:eif Orderfiles:> <:or Items:><:eif Items:> </td>
-    </tr>
-    <:iterator separator orders:> 
-    <tr> 
-      <td >&nbsp; </td>
-    </tr>
-    <:iterator end orders:> <:or Orders:> 
-    <tr> 
-      <td  align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">You 
-        haven't made any orders yet.</font></td>
-    </tr>
-    <:eif Orders:>
-       <:or Cfg:>
-       <:eif Cfg:>
   </table>
   
 <:if Subscriptions:>  
 </table>
 <:or Subscriptions:><:eif Subscriptions:>
 </div>
+<:include include/custom/userpage_custom.tmpl optional:><:include include/userpage_custom.tmpl optional:>
\ No newline at end of file