Index: openacs-4/packages/ecommerce/ecommerce.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/ecommerce.info,v
diff -u -r1.51 -r1.52
--- openacs-4/packages/ecommerce/ecommerce.info	13 Sep 2010 05:22:50 -0000	1.51
+++ openacs-4/packages/ecommerce/ecommerce.info	13 Oct 2010 09:59:24 -0000	1.52
@@ -7,7 +7,7 @@
     <initial-install-p>f</initial-install-p>
     <singleton-p>t</singleton-p>
     
-    <version name="5.16" url="http://openacs.org/repository/download/apm/ecommerce-5.16.apm">
+    <version name="5.17" url="http://openacs.org/repository/download/apm/ecommerce-5.17.apm">
         <owner url="mailto:janine@furfly.net">Janine Sisk</owner>
         <owner url="mailto:bart.teeuwisse@7-sisters.com">Bart Teeuwisse</owner>
         <owner url="mailto:alfred@thunderstick.com">Alfred Werner</owner>
@@ -17,7 +17,7 @@
         <description format="text/plain">This module implements a standard business-to-consumer Web store service. A feature summary is included with the documentaion.</description>
         <maturity>0</maturity>
 
-        <provides url="ecommerce" version="5.16"/>
+        <provides url="ecommerce" version="5.17"/>
         <requires url="acs-datetime" version="4.0"/>
         <requires url="acs-kernel" version="5.0"/>
         <requires url="ref-countries" version="0.1d"/>
@@ -92,6 +92,7 @@
             <parameter datatype="number"  min_n_values="1"  max_n_values="1"  name="UserClassUserViewP"  default="1" description="whether users can see what user classes they are in" section_name="display"/>
             <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="WeightUnits"  default="lbs" description="weight units such as pounds, carats, ounces, etc. If using PayPal, must comply with PayPal choices." section_name="units"/>
             <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="PayPalBusiness"  default="" description="email associated with paypal account." section_name="PayPal"/>
+            <parameter datatype="string"  min_n_values="1"  max_n_values="1"  name="PayPalStandardMode"  default="0" description="PayPal Standard mode: 0 = not used, 1 = shipping by weight, 2 = shipping calculated by price, 3 = custom shipping (as a line item)." section_name="PayPal"/>
         </parameters>
 
     </version>
Index: openacs-4/packages/ecommerce/www/paypal-thankyou.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/paypal-thankyou.tcl,v
diff -u
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/ecommerce/www/paypal-thankyou.tcl	13 Oct 2010 09:59:24 -0000	1.1
@@ -0,0 +1,51 @@
+# set any form defaults here
+
+# get form variables passed with connection
+set __form [ns_getform]
+if { $__form eq "" } {
+    set __form_size 0
+} else {
+    set __form_size [ns_set size $__form]
+}
+for { set __form_counter_i 0 } { $__form_counter_i < $__form_size } { incr __form_counter_i } {
+    
+    # The name of the argument passed in the form
+    set __form_key [ns_set key $__form $__form_counter_i]
+
+    # This is the value
+    set __form_input [ns_set value $__form $__form_counter_i]
+    if { [info exists --form_input_arr($__form_key) ] } {
+        if { $__form_input ne $__form_input_arr($__form_key) } {
+            # which one is correct? log error
+            ns_log Error "paypal-thankyou.tcl: form input error. duplcate key provided for ${__form_key}"
+            ad_script_abort
+        } else {
+            ns_log Notice "paypal-thankyou.tcl: notice, form has two keys with same info.."
+        }
+    } else {
+        set __form_input_arr($__form_key) [ns_set value $__form $__form_counter_i]
+    }
+}
+
+# filter out variables not explicitly requested?
+
+# build new form? would also need __form_input_type(key,attribute), where attribute is type,maxlength, accesskey, alt, id, class, size, style, size
+# formbuilder specs: order, item#
+# how to specify multi input select, box and radio inputs and form order?
+
+if { [info exists __form_input_arr(invoice)] } {
+    set order_id [string trim [string range 9 end]]
+    # set order to confirmed state.
+    if { [info exists __form_input_arr(txn_id)] } {
+        set trans_id $__form_input_arr(txn_id) 
+        #call state change here.
+        db_transaction {
+          db_dml change_cart_state "update ec_orders 
+      set order_state='confirmed', confirmed_date=current_timestamp
+      where order_id=:order_id"
+        }
+        ns_log Notice "paypal-thankyou.tcl,ref(186) order_id $order_id now in confirmed state."
+        # we really cannot convert beyond that for Paypal Web Standard edition
+    }
+}
+ad_returnredirect "[ec_url]"
\ No newline at end of file
Index: openacs-4/packages/ecommerce/www/shopping-cart.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart.adp,v
diff -u -r1.14 -r1.15
--- openacs-4/packages/ecommerce/www/shopping-cart.adp	13 Sep 2008 11:41:44 -0000	1.14
+++ openacs-4/packages/ecommerce/www/shopping-cart.adp	13 Oct 2010 09:59:24 -0000	1.15
@@ -30,7 +30,7 @@
     </if>
     <tr>
       <td>
-        <a href="product?product_id=@in_cart.product_id@">@in_cart.product_name;noquote@</a>
+       @in_cart.sku;noquote@ <a href="product?product_id=@in_cart.product_id@">@in_cart.product_name;noquote@</a>
       </td>
       <td>
         <if @in_cart.color_choice@ not nil>
@@ -71,6 +71,7 @@
 @pretty_total_price@</td>
       <td><input type=submit value="update"></td>
     </tr>
+
 <if @shipping_gateway_in_use@ false>
   <if @no_shipping_options@ false>
       <tr>
@@ -81,7 +82,13 @@
           <td colspan="3" align="right">
       </else>
            @shipping_options@</td>
-      <td align="right">@total_reg_shipping_price@</td><td>standard</td>
+      <td align="right">@total_reg_shipping_price@</td><td>
+<if @paypal_standard_mode@ eq 3>
+@paypal_checkout_button_stand;noquote@
+</if><else>
+standard 
+</else>
+ </td>
       </tr>
 
       <if @offer_express_shipping_p@ true>
@@ -93,7 +100,13 @@
             <td colspan="3">
         </else>
             &nbsp;</td>
-        <td align="right">@total_exp_shipping_price@</td><td>express</td>
+        <td align="right">@total_exp_shipping_price@</td><td>
+<if @paypal_standard_mode@ eq 3>
+@paypal_checkout_button_expr;noquote@
+</if><else>
+express
+</else>
+</td>
         </tr>
       </if>
 
@@ -118,7 +131,6 @@
 <p>** - Special message for items marked as @display_price_of_zero_as@</p>
 </td></tr>
 </if>
-
     <multiple name="tax_entries">
       <tr>
         <td colspan="5">
@@ -135,9 +147,21 @@
     </form>
 
     <center>
+
+<if @paypal_standard_mode@ eq 0>
       <form method=post action="checkout-one-form">
         <input type=submit value="Proceed to Checkout"><br>
       </form>
+</if><else>
+  <if @paypal_standard_mode@ ne 3>
+  @paypal_checkout_button;noquote@
+  </if><else>
+    <if @paypal_shipping_mode@ eq 1>
+    @paypal_checkout_button;noquote@
+    </if>
+   </else>
+</else>
+
     </center>
   </if>
   <else>
Index: openacs-4/packages/ecommerce/www/shopping-cart.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/ecommerce/www/shopping-cart.tcl,v
diff -u -r1.20 -r1.21
--- openacs-4/packages/ecommerce/www/shopping-cart.tcl	25 Sep 2010 19:50:12 -0000	1.20
+++ openacs-4/packages/ecommerce/www/shopping-cart.tcl	13 Oct 2010 09:59:24 -0000	1.21
@@ -11,8 +11,7 @@
     usca_p:optional
     product_id:optional
 }
-
-    set logout_url "/register/logout?return_url=[ns_urlencode "[ec_url]"]"
+set logout_url "/register/logout?return_url=[ns_urlencode "[ec_url]"]"
 # bottom links:
 # 1) continue shopping (always)
 
@@ -56,6 +55,12 @@
 #    where o.order_id=i.order_id
 #    and o.user_session_id=:user_session_id and o.order_state='in_basket'"]
 
+set order_id [db_string get_order_id "
+    select order_id
+    from ec_orders
+    where user_session_id = :user_session_id
+    and order_state = 'in_basket'"  -default ""]
+
 # calculate shipping charge options when not using shipping-gateway,
 #  and then include the value with each option (for an informed choice)
 
@@ -78,9 +83,16 @@
 set max_add_quantity_length [string length [parameter::get -parameter CartMaxToAdd]]
 set offer_express_shipping_p [parameter::get -parameter ExpressShippingP]
 set offer_pickup_option_p [parameter::get -parameter PickupP]
+set paypal_business [parameter::get -parameter PayPalBusiness]
+set paypal_standard_mode [parameter::get -parameter PayPalStandardMode]
+set store_name [parameter::get -parameter SystemName]
 set total_reg_shipping_price 0
 set total_exp_shipping_price 0
+set total_weight 0
 set no_shipping_options "t"
+set paypal_shipping_mode 1
+# papal_shipping_mode should mirror no_shipping_options
+
 # Check if a shipping gateway has been selected.
 set shipping_gateway [parameter::get -parameter ShippingGateway]
 set shipping_gateway_in_use [acs_sc_binding_exists_p ShippingGateway $shipping_gateway]
@@ -141,7 +153,7 @@
 # basically collect shipping information for any items where ec_products.no_shipping_avail_p = 't'
 
 db_multirow -extend { line_subtotal } in_cart get_products_in_cart "
-      select p.product_name, p.one_line_description, p.no_shipping_avail_p, p.shipping, p.shipping_additonal, p.weight, p.product_id, count(*) as quantity, u.offer_code, i.color_choice, i.size_choice, i.style_choice, '' as price 
+      select p.product_name, p.one_line_description, p.no_shipping_avail_p, p.shipping, p.shipping_additonal, p.weight, p.product_id, p.sku, count(*) as quantity, u.offer_code, i.color_choice, i.size_choice, i.style_choice, '' as price 
       from ec_orders o
       join ec_items i on (o.order_id=i.order_id)
       join ec_products p on (i.product_id=p.product_id)
@@ -153,12 +165,23 @@
       group by p.product_name, p.one_line_description, p.no_shipping_avail_p, p.shipping, p.shipping_additional, p.weight, p.product_id, u.offer_code, i.color_choice, i.size_choice, i.style_choice" {
           set line_subtotal "$quantity"
       }
+# <input type=\"hidden\" name=\"item_name\" value=\"${store_name}\">  not used?
+set paypal_checkout_button "<form action=\"https://www.paypal.com/cgi-bin/webscr\" method=\"post\">
+<input type=\"hidden\" name=\"charset\" value=\"utf-8\">
+<input type=\"hidden\" name=\"cmd\" value=\"_cart\">
+<input type=\"hidden\" name=\"upload\" value=\"1\">
+<input type=\"hidden\" name=\"_cart\" value=\"upload\">
+<input type=\"hidden\" name=\"currency_code\" value=\"${currency}\">
+<input type=\"hidden\" name=\"business\" value=\"${paypal_business}\">"
 
+set line_items_count 0
+
 for {set i 1} {$i <= [template::multirow size in_cart]} {incr i} {
 
     set product_name [template::multirow get in_cart $i product_name]
     set one_line_description [template::multirow get in_cart $i one_line_description]
     set product_id [template::multirow get in_cart $i product_id]
+    set sku [template::multirow get in_cart $i sku]
     set no_shipping_avail_p [template::multirow get in_cart $i no_shipping_avail_p]
     set shipping [template::multirow get in_cart $i shipping]
     set shipping_additional [template::multirow get in_cart $i shipping_additional]
@@ -169,6 +192,7 @@
     set size_choice [template::multirow get in_cart $i size_choice]
     set style_choice [template::multirow get in_cart $i style_choice]
 
+
     set max_quantity_length [max $max_add_quantity_length [string length $quantity]]
     # Deletions are done by product_id, color_choice, size_choice,
     # style_choice, not by item_id because we want to delete the
@@ -195,7 +219,7 @@
     if { [string equal $no_shipping_avail_p "f"] && !$shipping_gateway_in_use} {
         # at least one thing is shippable, begin calculating ship value(s)
         set no_shipping_options "f"
-
+        set paypal_shipping_mode 2
         # Calculate shipping for line item
         set first_instance 1
         set shipping_prices_for_first_line_item [ec_shipping_prices_for_one_item_by_rate $product_id $shipping $shipping_additional $default_shipping_per_item $weight $weight_shipping_cost $first_instance $add_exp_amount_per_item $add_exp_amount_by_weight]
@@ -218,18 +242,35 @@
     set total_price [expr $total_price + ($quantity * $lowest_price)]
     incr product_counter $quantity
 
+    # Add weight to order
+    set total_weight [expr { $quantity * $weight + $total_weight } ]
+
     template::multirow set in_cart $i delete_export_vars $delete_export_vars
     template::multirow set in_cart $i price "[lindex $lowest_price_and_price_name 1]:&nbsp;&nbsp;[ec_pretty_price [lindex $lowest_price_and_price_name 0] $currency]"
 
+    set line_items_count $i
+
+    # calculate paypal line item
+    set item_name [string range "${sku} ${product_name}, ${one_line_description}" 0 126]
+    append paypal_checkout_button "
+<input type=\"hidden\" name=\"item_name_${i}\" value=\"${item_name}\">
+<input type=\"hidden\" name=\"item_number_${i}\" value=\"${sku}\">
+<input type=\"hidden\" name=\"amount_${i}\" value=\"${lowest_price}\">
+<input type=\"hidden\" name=\"quantity_${i}\" value=\"${quantity}\">"
+
+
 }
 
+set weight_unit_of_measure [parameter::get -parameter WeightUnits]
+
+
 # Add adjust quantities line if there are products in the cart.
 set pretty_total_price [ec_pretty_pure_price $total_price $currency]
 
+# require shipping address
+
 if { $shipping_gateway_in_use  && $shipping_address_id > 0} {
-            
-    set weight_unit_of_measure [parameter::get -parameter WeightUnits]
-    
+
     set shipping_options "<table align=\"center\"><tr><td colspan=\"3\"
     	<p><b>Shipping method:</b></p></td></tr>"
     
@@ -274,15 +315,15 @@
 
     # 4. set total costs for each shipping option
     set total_shipping_price_default $total_reg_shipping_price
-    set total_reg_shipping_price [ec_pretty_pure_price [expr $total_reg_shipping_price + $shipping_method_standard] $currency "t"]
-
-    set total_exp_shipping_price [ec_pretty_pure_price [expr $total_exp_shipping_price + $shipping_method_express] $currency "t"]
+    set total_reg_ship_price [format "%0.2f" [expr $total_reg_shipping_price + $shipping_method_standard]]
+    set total_reg_shipping_price [ec_pretty_pure_price $total_reg_ship_price $currency "t"]
+    set total_exp_ship_price [format "%0.2f" [expr $total_exp_shipping_price + $shipping_method_express]]
+    set total_exp_shipping_price [ec_pretty_pure_price $total_exp_ship_price $currency "t"]
     set shipping_method_pickup [ec_pretty_pure_price 0 $currency "t"]
     set shipping_method_no_shipping 0
 
     # 5 prepare shipping options to present to user
     if { [string equal $no_shipping_options "f" ] } {
-
         # standard shipping is total_reg_shipping_price
         set shipping_options "Shipping is addtional:"
         if { $offer_express_shipping_p } {
@@ -295,6 +336,7 @@
         }
     } else {
         set shipping_options "No shipping options available."
+
     }
 }
 
@@ -308,6 +350,53 @@
 		set pretty_tax "[format %0.2f [expr $tax_rate * 100]]%"
 }
 
+# calculate paypal cart totals, finish button html
+if { $paypal_standard_mode == 1 } {
+# 
+append paypal_checkout_button "
+<input type=\"hidden\" name=\"weight_cart\" value=\"${total_weight}\"> 
+<input type=\"hidden\" name=\"weight_unit\" value=\"${weight_unit_of_measure}\">"
+}
+
+append paypal_checkout_button "
+<input type=\"hidden\" name=\"custom\" value=\"user_session_id ${user_session_id}\">
+<input type=\"hidden\" name=\"invoice\" value=\"order_id ${order_id}\">
+<input type=\"hidden\" name=\"tax_cart\" value=\"0\">
+<input type=\"hidden\" name=\"no_shipping\" value=\"${paypal_shipping_mode}\">
+<input type=\"hidden\" name=\"return\" value=\"[ec_secure_location][ec_url]paypal-thankyou\">
+<input type=\"hidden\" name=\"cancel_return\" value=\"[ec_secure_location][ec_url]shopping-cart\">
+<input type=\"hidden\" name=\"rm\" value=\"2\">
+<input type=\"hidden\" name=\"paymentaction\" value=\"authorization\">"
+
+
+if { $paypal_shipping_mode == 2 && $paypal_standard_mode == 3 } {
+    set ii [expr { $line_items_count + 1 } ]
+    set paypal_checkout_button_stand "${paypal_checkout_button}
+<input type=\"hidden\" name=\"item_number_${ii}\" value=\"ship-hand\">
+<input type=\"hidden\" name=\"item_name_${ii}\" value=\"Shipping and Handling, standard/CIF\">
+<input type=\"hidden\" name=\"amount_${ii}\" value=\"${total_reg_ship_price}\">
+<input type=\"hidden\" name=\"quantity_${ii}\" value=\"1\">
+Standard&nbsp;shipping&nbsp;<input type=\"submit\" value=\"PayPal\" title=\"Standard shipping\" alt=\"Check out with PayPal. The safer, easier way to pay.\">&nbsp;checkout
+</form>"
+    set paypal_checkout_button_expr "${paypal_checkout_button}
+<input type=\"hidden\" name=\"item_number_${ii}\" value=\"ship-hand\">
+<input type=\"hidden\" name=\"item_name_${ii}\" value=\"Shipping and Handling, express/CIF\">
+<input type=\"hidden\" name=\"amount_${ii}\" value=\"${total_exp_ship_price}\">
+<input type=\"hidden\" name=\"quantity_${ii}\" value=\"1\">
+Express&nbsp;shipping&nbsp;<input type=\"submit\" value=\"PayPal\" title=\"Express shipping\" alt=\"Check out with PayPal. The safer, easier way to pay.\">&nbsp;checkout
+</form>"
+} else {
+    append paypal_checkout_button "
+Checkout with <input type=\"submit\" value=\"PayPal\" title=\"Check out with PayPal. The safer, easier way to pay.\" alt=\"PayPal.\">. A safe, easy way to pay.
+</form>"
+
+}
+if { $paypal_standard_mode > 0 && $paypal_standard_mode < 3} {
+    set no_shipping_options "t"
+}
+
+# src="http://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" alt="Check out with PayPal. The safer, easier way to pay." 
+
 # bottom links:
 # 1) continue shopping (always and already created)
 # 2) log in (if they're not logged in)
@@ -332,6 +421,7 @@
 	    and saved_p='t')" -default ""]
 }
 
+
 set title "Shopping Cart"
 set context [list $title]
 set ec_system_owner [ec_system_owner]