lots of order and cart updates
authorTony Cook <tony@develop-help.com>
Thu, 11 Jul 2013 10:43:49 +0000 (20:43 +1000)
committerTony Cook <tony@develop-help.com>
Sun, 21 Jul 2013 23:34:16 +0000 (09:34 +1000)
schema/bse.sql
site/cgi-bin/modules/BSE/Cart.pm
site/cgi-bin/modules/BSE/TB/Order.pm
site/cgi-bin/modules/BSE/UI/Shop.pm
site/cgi-bin/modules/BSE/Variables.pm
site/templates/checkoutnew_base.tmpl
site/templates/mailconfirm_html.tmpl
site/templates/preload.tmpl
site/util/mysql.str

index 8d83aa888eede482f3cc6c7ea1d6279d3544b327..612b1534ab1519bb826f958170e2dc45fd007605 100644 (file)
@@ -352,6 +352,8 @@ create table orders (
   coupon_id integer null,
   coupon_code_discount_pc real not null default 0,
 
+  delivery_in integer null,
+
   primary key (id),
   index order_cchash(ccNumberHash),
   index order_userId(userId, orderDate),
index 15aaf9be29ac2f5ec7929d3c670a6d77fb430353..b780c9cc0a9dba5ef49a5fd7e6aa0ecd59fbe421 100644 (file)
@@ -2,7 +2,7 @@ package BSE::Cart;
 use strict;
 use Scalar::Util;
 
-our $VERSION = "1.007";
+our $VERSION = "1.008";
 
 =head1 NAME
 
@@ -226,6 +226,19 @@ sub product_cost_discount {
   return $self->total_cost - $self->discounted_product_cost;
 }
 
+=item cfg_shipping
+
+Return true if the system is configured to prompt for shipper
+information.
+
+=cut
+
+sub cfg_shipping {
+  my $self = shift;
+
+  return $self->{req}->cfg->entry("shop", "shipping", 0);
+}
+
 =item set_shipping_cost()
 
 Set the cost of shipping.
@@ -252,6 +265,79 @@ sub shipping_cost {
   return $self->{shipping};
 }
 
+=item set_shipping_method
+
+Set the stored shipping method.  For internal use.
+
+=cut
+
+sub set_shipping_method {
+  my ($self, $method) = @_;
+
+  $self->{shipping_method} = $method;
+}
+
+=item shipping_method
+
+The description of the selected shipping method.
+
+=cut
+
+sub shipping_method {
+  my ($self) = @_;
+
+  return $self->{shipping_method};
+}
+
+=item set_shipping_name
+
+Set the stored shipping name.  For internal use.
+
+=cut
+
+sub set_shipping_name {
+  my ($self, $name) = @_;
+
+  $self->{shipping_name} = $name;
+}
+
+=item shipping_name
+
+The name of the selected shipping method.
+
+=cut
+
+sub shipping_name {
+  my ($self) = @_;
+
+  return $self->{shipping_name};
+}
+
+=item set_delivery_in
+
+Set the stored delivery time in days.
+
+=cut
+
+sub set_delivery_in {
+  my ($self, $days) = @_;
+
+  $self->{delivery_in} = $days;
+}
+
+=item delivery_in
+
+The expected delivery time in days.  Some shippers may not supply
+this, in which case this will be an undefined value.
+
+=cut
+
+sub delivery_in {
+  my ($self) = @_;
+
+  return $self->{delivery_in};
+}
+
 =item total_units
 
 Return the total number of units in the cart.
@@ -531,7 +617,7 @@ sub affiliate_code {
   return $code;
 }
 
-=item any_physcial_products
+=item any_phyiscal_products
 
 Returns true if the cart contains any physical products, ie. needs
 shipping.
index 0c99860989efc8ae87d15d5ba231b74d20800672..33950262aaab73e25b9f987be817cefbbfc7a7de 100644 (file)
@@ -7,7 +7,7 @@ use vars qw/@ISA/;
 use Carp 'confess';
 use BSE::Shop::PaymentTypes;
 
-our $VERSION = "1.023";
+our $VERSION = "1.024";
 
 sub columns {
   return qw/id
@@ -30,7 +30,7 @@ sub columns {
            delivStreet2 billStreet2 purchase_order shipping_method
            shipping_name shipping_trace
           paypal_token paypal_tran_id freight_tracking stage ccPAN
-          paid_manually coupon_id coupon_code_discount_pc/;
+          paid_manually coupon_id coupon_code_discount_pc delivery_in/;
 }
 
 sub table {
@@ -99,6 +99,7 @@ sub defaults {
      stage => "incomplete",
      ccPAN => "",
      paid_manually => 0,
+     delivery_in => undef,
     );
 }
 
index 2cae1785be245cb5e8b59e6d1b8568f5bd3e0b34..c21b41f49ca3a12a130a790ec9090c20eea6b6da 100644 (file)
@@ -18,7 +18,7 @@ use BSE::Countries qw(bse_country_code);
 use BSE::Util::Secure qw(make_secret);
 use BSE::Template;
 
-our $VERSION = "1.043";
+our $VERSION = "1.044";
 
 =head1 NAME
 
@@ -497,6 +497,20 @@ sub _any_physical_products {
   return 0;
 }
 
+=item checkout
+
+Display the checkout form.
+
+Variables:
+
+=over
+
+=back
+
+Template C<checkoutnew>
+
+=cut
+
 sub req_checkout {
   my ($class, $req, $message, $olddata) = @_;
 
@@ -568,7 +582,7 @@ sub req_checkout {
   my ($delivery_in, $shipping_cost, $shipping_method);
   my $shipping_error = '';
   my $shipping_name = '';
-  my $prompt_ship = $cfg->entry("shop", "shipping", 0);
+  my $prompt_ship = $cart->cfg_shipping;
 
   my $physical = $cart->any_physical_products;
 
@@ -666,6 +680,11 @@ sub req_checkout {
     $message = $req->message($errors);
   }
   $cart->set_shipping_cost($shipping_cost);
+  $cart->set_shipping_method($shipping_method);
+  $cart->set_shipping_name($shipping_name);
+  $cart->set_delivery_in($delivery_in);
+  $req->set_variable(old => $old);
+  $req->set_variable(errors => $errors);
 
   my $item_index = -1;
   my @options;
@@ -686,7 +705,7 @@ sub req_checkout {
      error_img => [ \&tag_error_img, $cfg, $errors ],
      ifShipping => $prompt_ship,
      shipping_select => $shipping_select,
-     delivery_in => escape_html($delivery_in),
+     delivery_in => escape_html(defined $delivery_in ? $delivery_in : ""),
      shipping_cost => $shipping_cost,
      shipping_method => escape_html($shipping_method),
      shipping_error => escape_html($shipping_error),
@@ -773,6 +792,11 @@ sub _order_hash {
       $values->{$delivery} = $values->{$billing};
     }
   }
+  my $cart = $req->cart;
+  if ($cart->cfg_shipping && $cart->any_physical_products) {
+    my $shipping_name = $cgi->param("shipping_name");
+    defined $shipping_name and $values->{shipping_name} = $shipping_name;
+  }
 }
 
 # saves order and refresh to payment page
@@ -809,7 +833,7 @@ sub req_order {
 
   dh_validate_hash(\%values, \%errors, { rules=>\%rules, fields=>\%fields },
                   $cfg, 'Shop Order Validation');
-  my $prompt_ship = $cfg->entry("shop", "shipping", 0);
+  my $prompt_ship = $cart->cfg_shipping;
   if ($prompt_ship) {
     my $country = $values{delivCountry} || bse_default_country($cfg);
     my $country_code = bse_country_code($country);
@@ -916,6 +940,9 @@ sub req_show_payment {
   defined $payment or $payment = $payment_types[0];
 
   $cart->set_shipping_cost($order->{shipping_cost});
+  $cart->set_shipping_method($order->{shipping_method});
+  $cart->set_shipping_name($order->{shipping_name});
+  $req->set_variable(errors => $errors);
 
   my %acts;
   %acts =
@@ -1800,7 +1827,7 @@ sub _fillout_order {
 
   my $items = $cart->items;
   my $products = $cart->products;
-  my $prompt_ship = $cfg->entry("shop", "shipping", 0);
+  my $prompt_ship = $cart->cfg_shipping;
   if ($prompt_ship) {
     if (_any_physical_products($products)) {
       my ($courier) = BSE::Shipping->get_couriers($cfg, $cgi->param("shipping_name"));
@@ -1835,8 +1862,7 @@ sub _fillout_order {
        $values->{shipping_name} = $courier->name;
        $values->{shipping_cost} = $cost;
        $values->{shipping_trace} = $courier->trace;
-       $cart->set_shipping_cost($cost);
-       #$values->{delivery_in} = $courier->delivery_in();
+       $values->{delivery_in} = $courier->delivery_in();
       }
       else {
        # XXX: What to do?
@@ -1857,6 +1883,11 @@ sub _fillout_order {
   else {
     $values->{coupon_id} = undef;
   }
+  $cart->set_shipping_cost($values->{shipping_cost});
+  $cart->set_shipping_method($values->{shipping_method});
+  $cart->set_shipping_name($values->{shipping_name});
+  $cart->set_delivery_in($values->{delivery_in});
+
   $values->{coupon_code_discount_pc} = $cart->coupon_code_discount_pc;
   $values->{total} = $cart->total;
 
index 394fca9448b68d36fd7bf5e2e5ec484b236a0ce7..a7d1969f404184bea591ebd194a218e6554ba296 100644 (file)
@@ -4,7 +4,7 @@ use Scalar::Util qw(blessed);
 use BSE::TB::Site;
 use BSE::Util::HTML;
 
-our $VERSION = "1.015";
+our $VERSION = "1.016";
 
 sub _base_variables {
   my ($self, %opts) = @_;
@@ -19,6 +19,13 @@ sub _base_variables {
       ? sub { _url_common($_[0]->admin, $_[1]) }
       : sub { _url_common($_[0]->link, $_[1]) }
      ),
+     abs_url => sub {
+       my ($url) = @_;
+
+       $url =~ /^\w+:/ and return $url;
+
+       return  BSE::Cfg->single->entryErr("site", "url") . $url;
+     },
      admin => $opts{admin},
      admin_links => $opts{admin_links},
      dumper => sub {
@@ -286,6 +293,10 @@ otherwise the normal article link.
 
 If supplied, C<extraargs> should be a hash containing extra arguments.
 
+=item bse.abs_url(url)
+
+Return an absolute form of C<url>.  This is always relative to the main site url.
+
 =item bse.admin
 
 Return true in admin mode.
index 0755766981ad5c3be2a0c3815493faa15aad18d8..a305026a16e6e6135d98a50f55c3ed71969f0e42 100644 (file)
@@ -112,18 +112,18 @@ function BSE_validateForm {
             <td width="100%" height="20" align="center" colspan="4"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">You have no items in your shopping cart!</font></td>
            </tr>
           <:.end if -:>
-        <:if Shipping_cost:>
+        <:.if cart.shipping_cost:>
         <tr valign="middle" align="center" bgcolor="#FFFFFF"> 
-          <td colspan=2 width="100%" align="left">&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2">Shipping charges (for <:shipping_method:><:if Delivery_in:>, delivery in <:delivery_in:> days<:or Delivery_in:><:eif Delivery_in:>)</font></td>
-          <td align="right"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>$<:money shipping_cost:></b></font></td>
+          <td colspan=2 width="100%" align="left">&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2">Shipping charges (for <:= cart.shipping_method:><:.if cart.delivery_in.defined:>, delivery in <:= cart.delivery_in:> days<:.end if:>)</font></td>
+          <td align="right"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>$<:= bse.number("money", cart.shipping_cost) :></b></font></td>
         </tr>
-        <:or Shipping_cost:><:eif Shipping_cost:>
-        <:if Eq [shipping_name] contact:>
+        <:.end if:>
+        <:.if cart.shipping_name eq "contact" :>
         <tr valign="middle" align="center" bgcolor="#FFFFFF"> 
           <td colspan=2 width="100%" align="left">&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2">Shipping charges to be determined later</font></td>
           <td align="right"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>$X.XX</b></font></td>
         </tr>
-        <:or Eq:><:eif Eq:>
+        <:.end if :>
       </table>
     </td>
   </tr>
@@ -294,13 +294,13 @@ Unknown coupon code
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> 
         <textarea name="instructions" rows="5" cols="40" wrap="virtual"><:old instructions:></textarea></font><:error_img instructions:></td>
     </tr>
-<:if And [ifShipping] [ifPhysical]:>
+<:.if cart.cfg_shipping and cfg.any_physical_products:>
     <tr>
       <td valign="top"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Shipping<br /> method:</font></td>
       <td><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:shipping_select:></font><:error_img shipping_name:> *
 </td>
     </tr>
-<:eif:>
+<:.end if:>
     <tr> 
       <td valign="top"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Purchase<br />Order:</font></td>
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> 
@@ -393,7 +393,7 @@ Unknown coupon code
     <tr> 
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> E-mail:</font></td>
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> 
-        <input type="Text" name="emailAddress" size=34 value="<:old emailAddress:>"><:error_img emailAddress:>
+        <input type="Text" name="emailAddress" size=34 value="<:= old("emailAddress"):>"><:.call "error_img", "field":"emailAddress":>
         *</font></td>
     </tr>
   </table>
index 17e31e9debe95c41d9865ccdd25d949acff859a1..3a597ab4cd4c8831c46e3dfa30b831fa22fdd6b9 100644 (file)
@@ -3,80 +3,85 @@
 
 <p>To stay up to date on the status of your order, see:</p>
 
-<p><a href="<:target user oda id [order randomId] |h:>"><:target user oda id [order randomId] |h:></a></p>
+<p><a href="<:= cfg.user_url("user", "oda", "id", order.randomId) |h:>"><:= cfg.user_url("user", "oda", "id", order.randomId) |h:></a></p>
 
-<p>Order: <:order id |%06d:></p>
+<p>Order: <:= order.id.format("%06d") :></p>
 
 <table>
 <tr>
-<thDelivery:</th>
-<td> <:order delivFirstName |h:> <:order delivLastName |h:><br />
-<:order delivStreet |h:><br />
-<:order delivSuburb |h:> <:order delivPostCode |h:> <:order delivState |h:><br />
-<:order delivCountry |h:></td>
+<th>Delivery:</th>
+<td><:= order.delivFirstName :> <:= order.delivLastName :><br />
+<:= order.delivStreet :><br />
+<:= order.delivSuburb :> <:= order.delivPostCode :> <:= order.delivState :><br />
+<:= order.delivCountry :></td>
 </tr>
 <tr>
   <th>Phone:</th>
-  <td><:order telephone |h:></td>
+  <td><:= order.telephone :></td>
 </tr>
-<:ifOrder delivMobile:>
+<:.if order.delivMobile:>
 <tr>
   <th>Mobile:</th>
-  <td><:order delivMobile |h:></td>
+  <td><:= order.delivMobile :></td>
 </tr>
-<:or:><:eif:>
-<:ifOrder facsimile:>
+<:.end if -:>
+<:.if order.facsimile :>
 <tr>
   <th>Fax:</th>
-  <td><:order facsimile |h:></td>
+  <td><:= order.facsimile :></td>
 </tr>
-<:or:><:eif:>
+<:.end if -:>
 <tr>
   <th>Email:</th>
-  <td><:order emailAddress |h:></td>
+  <td><:= order.emailAddress :></td>
 </tr>
 </table>
 
 <table>
 <tr>
-  <th>Product</th
+  <th>Product</th>
   <th>Units</th>
   <th>Price</th>
   <th>Extended</th>
 </tr>
-<:iterator begin items:>
-  <td><:product title |h:>
-<:if Options:>
-   <br /><:options |h:><:or Options:><:eif Options:></td>
-  <td><:item units:></td>
-  <td><:item price |m:></td>
-  <td><:extended price|m:></td>
+<:.for item in [ order.items ]:>
+  <td><a href="<:= bse.abs_url(item.product.link) :>"><:= item.title :></a>
+<:.if item.nice_options:>
+   <br /><:= item.nice_options :>
+<:-.end if -:>
+</td>
+  <td><:= item.units:></td>
+  <td><:= bse.number("money", item.price) :></td>
+  <td><:= bse.number("money", item.extended("price")):></td>
 </tr>
-<:iterator end items:>
+<:.end for -:>
 <tr>
   <td colspan="3">Shipping:</td>
-  <td><:order shipping_cost |m:></td>
+  <td><:= bse.number("money", order.shipping_cost) :></td>
 </tr>
 <tr>
   <td>Total:</td>
-  <td><:order total |m:></td>
+  <td><:= bse.number("money", order.total) :></td>
 </tr>
 </table>
 
-<:ifEq [order paymentType] "0" :>Paid by credit card.
-<:if Order ccOnline
-:><p>Processed online.</p>
-<p>Receipt No.  : <:order ccReceipt |h:></p>
-<:or Order
-:><:eif Order:><:or:><:eif
-:><:ifEq [order paymentType] "1" :><p>Will be paid by cheque</p><:or
-:><:eif:><:ifEq [order paymentType] "2"
-:><p>We will call you to arrange for payment</p><:or:><:eif:><:ifEq [order paymentType] "4"
-:><p>Paid by PayPal, transaction id <:order paypal_tran_id |h:></p><:or:><:eif:><:
-include custom/payment_type_email.include:>
-<:ifOrder shipping_method:>
-<p>To be shipped by: <:order shipping_method:></p>
-<:or:><:eif:>
-<:if Order instructions:>
-<p>Special Instructions: <:order instructions |h:></p>
-<:or Order:><:eif Order:>
+<:.if order.paymentType == 0 -:>
+<p>Paid by credit card.</p>
+  <:.if order.ccOnline -:>
+<p>Processed online.</p>
+<p>Receipt No.  : <:= order.ccReceipt :></p>
+  <:.end if :>
+<:.elsif order.paymentType == 1 -:>
+<p>Will be paid by cheque</p>
+<:.elsif order.paymentType == 2 -:>
+<p>We will call you to arrange for payment</p>
+<:.elsif order.paymentType == 4 -:>
+<p>Paid by PayPal, transaction id <:= order.paypal_tran_id :></p>
+<:.end if -:>
+<:include custom/payment_type_email.include:>
+<:.if order.shipping_method:>
+<p>To be shipped by: <:= order.shipping_method:></p>
+<:.end if -:>
+<:.if order.instructions:>
+<p>Special Instructions: <:= order.instructions :></p>
+<:.end if -:>
index 4f463813d4b6795e8653e2d778404135b8b27a8c..624a9c042f8bd4c11f200c08577356a30e39191c 100644 (file)
@@ -139,7 +139,7 @@ Page <:= pages.page :> of <:= pages.pagecount :>
 <:.end define -:>
 
 <:.define input -:>
-<:# paramaters:
+<:# parameters:
   name - field name
   field - entry from fields
   object - source for defaults in edit mode
index 3d9fa4a2d6b195c6f241609ae9eada6b15f6d65b..a336e1841bbdb3d46222dfe87344349d95538386 100644 (file)
@@ -678,6 +678,7 @@ Column ccPAN;varchar(4);NO;;
 Column paid_manually;int(11);NO;0;
 Column coupon_id;int(11);YES;NULL;
 Column coupon_code_discount_pc;double;NO;0;
+Column delivery_in;int(11);YES;NULL;
 Index PRIMARY;1;[id]
 Index order_cchash;0;[ccNumberHash]
 Index order_coupon;0;[coupon_id]